diff --git a/Sources/Core/Utilities/OptionalSize.swift b/Sources/Core/Utilities/OptionalSize.swift index 6c3785b..70b1868 100644 --- a/Sources/Core/Utilities/OptionalSize.swift +++ b/Sources/Core/Utilities/OptionalSize.swift @@ -19,6 +19,14 @@ public struct OptionalSize { self.width = width self.height = height } + + public init(size: Float?) { + self.init(width: size, height: size) + } + + public init(_ size: Float?) { + self.init(size: size) + } } // MARK: - Logic diff --git a/Sources/Epoxy/CollectionView/Tools/EpoxyModeled+Padding.swift b/Sources/Epoxy/CollectionView/Tools/EpoxyModeled+Padding.swift new file mode 100644 index 0000000..74e6299 --- /dev/null +++ b/Sources/Epoxy/CollectionView/Tools/EpoxyModeled+Padding.swift @@ -0,0 +1,18 @@ +// +// EpoxyModeled+Padding.swift +// RakuyoKit +// +// Created by Rakuyo on 2024/5/22. +// Copyright © 2024 RakuyoKit. All rights reserved. +// + +import UIKit + +import EpoxyCore +import EpoxyLayoutGroups + +extension EpoxyModeled where Self: PaddingProviding { + public func padding(_ value: SectionEdgeInsets) -> Self { + padding(value.edgeInsets) + } +} diff --git a/Sources/Epoxy/CollectionView/Layout/Model/ListSpacing.swift b/Sources/Epoxy/CollectionView/Tools/ListSpacing.swift similarity index 98% rename from Sources/Epoxy/CollectionView/Layout/Model/ListSpacing.swift rename to Sources/Epoxy/CollectionView/Tools/ListSpacing.swift index e2def79..74a954a 100644 --- a/Sources/Epoxy/CollectionView/Layout/Model/ListSpacing.swift +++ b/Sources/Epoxy/CollectionView/Tools/ListSpacing.swift @@ -16,13 +16,13 @@ import CoreGraphics.CGFunction public struct ListSpacing { /// Default Spacing: 0 public static let `default`: Self = 0 - + /// Normal Spacing: 10 public static let normal: Self = 10 - + /// Spacing public let spacing: CGFloat - + /// Set Custom Spacing /// /// - Parameter spacing: Custom Spacing diff --git a/Sources/Epoxy/CollectionView/Layout/Model/SectionEdgeInsets.swift b/Sources/Epoxy/CollectionView/Tools/SectionEdgeInsets.swift similarity index 81% rename from Sources/Epoxy/CollectionView/Layout/Model/SectionEdgeInsets.swift rename to Sources/Epoxy/CollectionView/Tools/SectionEdgeInsets.swift index 00b8186..6fbef43 100644 --- a/Sources/Epoxy/CollectionView/Layout/Model/SectionEdgeInsets.swift +++ b/Sources/Epoxy/CollectionView/Tools/SectionEdgeInsets.swift @@ -13,28 +13,31 @@ import UIKit /// Spacing around the section. public enum SectionEdgeInsets { // swiftlint:disable sorted_enum_cases - + /// Only at the top. case top(CGFloat) - + /// Only at the bottom. case bottom(CGFloat) - + /// Both top and bottom with the same size. - case topBottom(CGFloat) - + case vertical(CGFloat) + /// Both sides with the same size. - case bothSides(CGFloat) - + case horizontal(CGFloat) + /// Custom spacing for all four sides. case allInOne(CGFloat) + /// Custom spacing, equal spacing on coaxes + case allWithCoaxes(vertical: CGFloat, horizontal: CGFloat) + /// Custom spacing for all four sides. case all(top: CGFloat, leading: CGFloat, bottom: CGFloat, trailing: CGFloat) - + /// Fully customized using `NSDirectionalEdgeInsets`. case custom(NSDirectionalEdgeInsets) - + // swiftlint:enable sorted_enum_cases } @@ -43,22 +46,25 @@ extension SectionEdgeInsets { switch self { case .top(let value): .init(top: value, leading: 0, bottom: 0, trailing: 0) - + case .bottom(let value): .init(top: 0, leading: 0, bottom: value, trailing: 0) - - case .topBottom(let value): + + case .vertical(let value): .init(top: value, leading: 0, bottom: value, trailing: 0) - - case .bothSides(let value): + + case .horizontal(let value): .init(top: 0, leading: value, bottom: 0, trailing: value) - + case .allInOne(let value): .init(top: value, leading: value, bottom: value, trailing: value) + case .allWithCoaxes(let vertical, let horizontal): + .init(top: vertical, leading: horizontal, bottom: vertical, trailing: horizontal) + case .all(let top, let leading, let bottom, let trailing): .init(top: top, leading: leading, bottom: bottom, trailing: trailing) - + case .custom(let edge): edge } diff --git a/Sources/Epoxy/Row/ButtonRow.swift b/Sources/Epoxy/Row/ButtonRow.swift index bbcebc9..c5d16d6 100644 --- a/Sources/Epoxy/Row/ButtonRow.swift +++ b/Sources/Epoxy/Row/ButtonRow.swift @@ -20,11 +20,14 @@ import RAKCore public final class ButtonRow: UIButton { private lazy var size: OptionalSize? = nil - /// Closure for touch down event. + /// Closure for `.touchDown` event. private lazy var didTouchDown: ButtonClosure? = nil - /// Closure for tap event. + /// Closure for `.touchUpInside` event. private lazy var didTap: ButtonClosure? = nil + + /// Closure for `.menuActionTriggered` event. Only available on iOS 14. + private lazy var didTriggerMenuAction: ButtonClosure? = nil } // MARK: - Life cycle @@ -53,6 +56,11 @@ extension ButtonRow { private func buttonDidClick(_ button: UIButton) { didTap?(button) } + + @objc + private func buttonDidTriggerMenuAction(_ button: UIButton) { + didTriggerMenuAction?(button) + } } // MARK: StyledView @@ -117,6 +125,10 @@ extension ButtonRow: StyledView { addTarget(self, action: #selector(buttonDidTouchDown(_:)), for: .touchDown) addTarget(self, action: #selector(buttonDidClick(_:)), for: .touchUpInside) + + if #available(iOS 14.0, *) { + addTarget(self, action: #selector(buttonDidTriggerMenuAction(_:)), for: .menuActionTriggered) + } } } @@ -225,14 +237,19 @@ extension ButtonRow: BehaviorsConfigurableView { /// Closure for tap event. public let didTap: ButtonClosure? + /// Closure for `.menuActionTriggered` event. Only available on iOS 14. + public let didTriggerMenuAction: ButtonClosure? + public init( updateImage: ImageRow.Behaviors? = nil, didTouchDown: ButtonClosure? = nil, - didTap: ButtonClosure? = nil + didTap: ButtonClosure? = nil, + didTriggerMenuAction: ButtonClosure? = nil ) { self.updateImage = updateImage self.didTouchDown = didTouchDown self.didTap = didTap + self.didTriggerMenuAction = didTriggerMenuAction } } @@ -257,5 +274,14 @@ extension ButtonRow: BehaviorsConfigurableView { didTouchDown = behaviors?.didTouchDown didTap = behaviors?.didTap + + if + #available(iOS 14.0, *), + let _didTriggerMenuAction = behaviors?.didTriggerMenuAction + { + didTriggerMenuAction = _didTriggerMenuAction + } else { + didTriggerMenuAction = nil + } } } diff --git a/Sources/Epoxy/Row/ImageRow.swift b/Sources/Epoxy/Row/ImageRow.swift index c0dc12c..8c1beb4 100644 --- a/Sources/Epoxy/Row/ImageRow.swift +++ b/Sources/Epoxy/Row/ImageRow.swift @@ -95,7 +95,7 @@ extension ImageRow: ContentConfigurableView { case asset(String, bundle: Bundle = .main) case data(Data) case file(String) - case sfSymbols(String) + case sfSymbols(String, configuration: UIImage.SymbolConfiguration? = nil) public var image: UIImage? { switch self { @@ -111,8 +111,8 @@ extension ImageRow: ContentConfigurableView { case .file(let path): .init(contentsOfFile: path) - case .sfSymbols(let name): - .init(systemName: name) + case .sfSymbols(let name, let configuration): + .init(systemName: name, withConfiguration: configuration) } } }