From a0246ed1f000a1e2fa829fdc98cf827b160c1816 Mon Sep 17 00:00:00 2001 From: fun Date: Thu, 30 Jun 2022 15:42:56 +0800 Subject: [PATCH] =?UTF-8?q?Ontap=20=E6=B3=9B=E5=9E=8B=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JengaExample.xcodeproj/project.pbxproj | 4 + .../Examples/CustomViewController.swift | 4 + .../Examples/OnTapViewController.swift | 107 ++++++++++++++++++ .../Examples/ViewRowViewController.swift | 9 +- .../JengaExample/ViewController.swift | 4 + Sources/Jenga/Core/Row/BasicRow.swift | 11 ++ Sources/Jenga/Core/Row/Row.swift | 17 +-- .../Jenga/Core/Row/System/NavigationRow.swift | 4 +- Sources/Jenga/Core/Row/System/OptionRow.swift | 23 +++- Sources/Jenga/Core/Row/System/SystemRow.swift | 2 +- Sources/Jenga/Core/Row/TableRow.swift | 22 ++++ Sources/Jenga/Core/Row/WrapperRow.swift | 23 ++++ Sources/Jenga/Core/TableDirector.swift | 12 +- 13 files changed, 221 insertions(+), 21 deletions(-) create mode 100644 JengaExample/JengaExample/Examples/OnTapViewController.swift diff --git a/JengaExample/JengaExample.xcodeproj/project.pbxproj b/JengaExample/JengaExample.xcodeproj/project.pbxproj index 7eb8563..778e3bb 100644 --- a/JengaExample/JengaExample.xcodeproj/project.pbxproj +++ b/JengaExample/JengaExample.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ B32FABA427FD4F08006A37BE /* HeaderFooterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B32FABA327FD4F08006A37BE /* HeaderFooterViewController.swift */; }; B32FABA627FD7B93006A37BE /* Runtime.swift in Sources */ = {isa = PBXBuildFile; fileRef = B32FABA527FD7B92006A37BE /* Runtime.swift */; }; B331732527FD7D2C008DFF5E /* UILabel.Inset.swift in Sources */ = {isa = PBXBuildFile; fileRef = B331732427FD7D2C008DFF5E /* UILabel.Inset.swift */; }; + B3436763286D895E003C213E /* OnTapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3436762286D895E003C213E /* OnTapViewController.swift */; }; B3496B3627F45338007D7A1D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3496B3527F45338007D7A1D /* AppDelegate.swift */; }; B3496B3827F45338007D7A1D /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3496B3727F45338007D7A1D /* SceneDelegate.swift */; }; B3496B3A27F45338007D7A1D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3496B3927F45338007D7A1D /* ViewController.swift */; }; @@ -64,6 +65,7 @@ B32FABA327FD4F08006A37BE /* HeaderFooterViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeaderFooterViewController.swift; sourceTree = ""; }; B32FABA527FD7B92006A37BE /* Runtime.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Runtime.swift; sourceTree = ""; }; B331732427FD7D2C008DFF5E /* UILabel.Inset.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILabel.Inset.swift; sourceTree = ""; }; + B3436762286D895E003C213E /* OnTapViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnTapViewController.swift; sourceTree = ""; }; B3496B3227F45338007D7A1D /* JengaExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JengaExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; B3496B3527F45338007D7A1D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; B3496B3727F45338007D7A1D /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -165,6 +167,7 @@ B32FABA127FD3649006A37BE /* StateViewController.swift */, B32FABA327FD4F08006A37BE /* HeaderFooterViewController.swift */, B372D8EF2859C49D0054BCA8 /* ViewRowViewController.swift */, + B3436762286D895E003C213E /* OnTapViewController.swift */, ); path = Examples; sourceTree = ""; @@ -284,6 +287,7 @@ B3496BB327F45799007D7A1D /* NavigationRow2.swift in Sources */, B32FABA227FD3649006A37BE /* StateViewController.swift in Sources */, B32FAB7D27F827BD006A37BE /* BaseViewController.swift in Sources */, + B3436763286D895E003C213E /* OnTapViewController.swift in Sources */, B32FABA627FD7B93006A37BE /* Runtime.swift in Sources */, B3496B3A27F45338007D7A1D /* ViewController.swift in Sources */, B3496B3627F45338007D7A1D /* AppDelegate.swift in Sources */, diff --git a/JengaExample/JengaExample/Examples/CustomViewController.swift b/JengaExample/JengaExample/Examples/CustomViewController.swift index 718ddf0..5dd8869 100644 --- a/JengaExample/JengaExample/Examples/CustomViewController.swift +++ b/JengaExample/JengaExample/Examples/CustomViewController.swift @@ -26,8 +26,12 @@ class CustomViewController: BaseViewController, DSLAutoTable { SpacerRow(10) TableRow() + .isSelectable(true) .height(1540 / 2078 * (UIScreen.main.bounds.width - 40)) .data("image2") + .onTap { cell in + print(cell) + } .customize { (cell, value) in print(cell, value) } diff --git a/JengaExample/JengaExample/Examples/OnTapViewController.swift b/JengaExample/JengaExample/Examples/OnTapViewController.swift new file mode 100644 index 0000000..cfb4bc4 --- /dev/null +++ b/JengaExample/JengaExample/Examples/OnTapViewController.swift @@ -0,0 +1,107 @@ +// +// OnTapViewController.swift +// JengaExample +// +// Created by 方林威 on 2022/6/30. +// + +import UIKit +import Jenga + +class OnTapViewController: BaseViewController, DSLAutoTable { + + override var pageTitle: String { get { "OnTap 泛型支持" } } + + @State private var string: String = "123" + + var tableBody: [Table] { + + TableSection { + NavigationRow("自定义 Navigation Cell") + .height(52) + .onTap { cell in + print(cell) + } + + TableRow(1993) + .height(1184 / 2256 * (UIScreen.main.bounds.width - 40)) + .onTap { (view, data) in + print(view.id, data) + } + + WrapperRow(1994) + .height(1184 / 2256 * (UIScreen.main.bounds.width - 40)) + .onTap { (view, data) in + print(view.id, data) + } + } + } +} + +private extension OnTapViewController { + + class BannerView: UIView, TableRowView { + + private lazy var coverImageView = UIImageView(image: UIImage(named: "image1")!) + + let id: Int = 1993 + + override init(frame: CGRect) { + super.init(frame: frame) + setup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setup() + } + + private func setup() { + addSubview(coverImageView) + } + + override func layoutSubviews() { + super.layoutSubviews() + coverImageView.frame = bounds + } + + func configure(with data: Int) { + print(data) + } + } + + class BannerCell: UITableViewCell, ConfigurableCell { + + private lazy var coverImageView = UIImageView(image: UIImage(named: "image2")!) + + let id: Int = 1994 + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + setup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setup() + } + + private func setup() { + addSubview(coverImageView) + } + + override func layoutSubviews() { + super.layoutSubviews() + coverImageView.frame = bounds + } + + func configure(with data: Int) { + print(data) + } + } + + class NavigationCell: UITableViewCell { + + } +} + diff --git a/JengaExample/JengaExample/Examples/ViewRowViewController.swift b/JengaExample/JengaExample/Examples/ViewRowViewController.swift index f363571..a0586d8 100644 --- a/JengaExample/JengaExample/Examples/ViewRowViewController.swift +++ b/JengaExample/JengaExample/Examples/ViewRowViewController.swift @@ -19,6 +19,9 @@ class ViewRowViewController: BaseViewController, DSLAutoTable { TableSection { WrapperRow(123) .height(1184 / 2256 * (UIScreen.main.bounds.width - 40)) + .onTap { (view, data) in + print(view, data) + } WrapperRow("456") .customize { label, data in @@ -51,7 +54,6 @@ fileprivate class BannerView: UIView, TableRowView { button.setTitle("点击", for: .normal) button.setTitleColor(.red, for: .normal) - button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside) } override func layoutSubviews() { @@ -66,10 +68,5 @@ fileprivate class BannerView: UIView, TableRowView { print("===============") print(data) } - - @objc - private func buttonAction() { - print("123") - } } diff --git a/JengaExample/JengaExample/ViewController.swift b/JengaExample/JengaExample/ViewController.swift index 7a02363..54c84a0 100644 --- a/JengaExample/JengaExample/ViewController.swift +++ b/JengaExample/JengaExample/ViewController.swift @@ -52,6 +52,10 @@ class ViewController: UIViewController, DSLAutoTable { .onTap(on: self) { (self) in self.navigationController?.pushViewController(ViewRowViewController(), animated: true) } + NavigationRow("OnTap 泛型支持") + .onTap(on: self) { (self) in + self.navigationController?.pushViewController(OnTapViewController(), animated: true) + } NavigationRow("测试") .onTap(on: self) { (self) in self.navigationController?.pushViewController(TableViewController(), animated: true) diff --git a/Sources/Jenga/Core/Row/BasicRow.swift b/Sources/Jenga/Core/Row/BasicRow.swift index f1c962d..4220b35 100644 --- a/Sources/Jenga/Core/Row/BasicRow.swift +++ b/Sources/Jenga/Core/Row/BasicRow.swift @@ -85,6 +85,17 @@ public extension BasicRow { func customize(_ value: @escaping ((T) -> Void)) -> Self { reform { $0.customize = value } } + + func onTap(_ value: @escaping ((T) -> Void)) -> Self { + reform { + $0.action = { cell in + guard let cell = cell as? T else { + return + } + value(cell) + } + } + } } extension BasicRow { diff --git a/Sources/Jenga/Core/Row/Row.swift b/Sources/Jenga/Core/Row/Row.swift index a3f07b8..56be48b 100644 --- a/Sources/Jenga/Core/Row/Row.swift +++ b/Sources/Jenga/Core/Row/Row.swift @@ -5,6 +5,9 @@ public protocol RowActionable { var isSelectable: Bool { get set } var action: RowAction? { get set } + + func onTap(on target: S, _ value: @escaping (S) -> Void) -> Self + func onTap(on target: S, _ value: @escaping (S) -> Void) -> Self where S: AnyObject } public protocol Row: JengaHashable, RowActionable, Reform { @@ -37,18 +40,18 @@ public extension Row { func selectionStyle(_ value: UITableViewCell.SelectionStyle) -> Self { reform { $0.selectionStyle = value } } - - func onTap(_ value: RowAction?) -> Self { - reform { $0.action = value } - } + func onTap(_ value: @escaping (() -> Void)) -> Self { + reform { $0.action = { _ in value() } } + } + func onTap(on target: S, _ value: @escaping (S) -> Void) -> Self { - reform { $0.action = { value(target) } } + reform { $0.action = { _ in value(target) } } } func onTap(on target: S, _ value: @escaping (S) -> Void) -> Self where S: AnyObject { reform { - $0.action = { [weak target] in + $0.action = { [weak target] _ in guard let target = target else { return } value(target) } @@ -78,5 +81,5 @@ public enum RowHeight { } } -public typealias RowAction = () -> Void +public typealias RowAction = (UITableViewCell) -> Void diff --git a/Sources/Jenga/Core/Row/System/NavigationRow.swift b/Sources/Jenga/Core/Row/System/NavigationRow.swift index 8a91c65..dd48824 100644 --- a/Sources/Jenga/Core/Row/System/NavigationRow.swift +++ b/Sources/Jenga/Core/Row/System/NavigationRow.swift @@ -17,7 +17,7 @@ open class NavigationRow: BasicRow, NavigationRowCompatib set {} } - public var accessoryButtonAction: RowAction? + public var accessoryButtonAction: (() -> Void)? public override var isSelectable: Bool { get { action != nil } @@ -33,7 +33,7 @@ open class NavigationRow: BasicRow, NavigationRowCompatib extension NavigationRow { - public func accessoryButtonAction(_ value: RowAction?) -> Self { + public func accessoryButtonAction(_ value: (() -> Void)?) -> Self { reform { $0.accessoryButtonAction = value } } diff --git a/Sources/Jenga/Core/Row/System/OptionRow.swift b/Sources/Jenga/Core/Row/System/OptionRow.swift index c379b9f..7ae2803 100644 --- a/Sources/Jenga/Core/Row/System/OptionRow.swift +++ b/Sources/Jenga/Core/Row/System/OptionRow.swift @@ -2,7 +2,7 @@ import UIKit /// TODO: 功能待开发 open class OptionRow: BasicRow, OptionRowCompatible, Equatable { - + public typealias OptionRowAction = (() -> Void) public init(text: Binding, isSelected: Bool = false) { super.init(text) self.isSelected = isSelected @@ -14,11 +14,13 @@ open class OptionRow: BasicRow, OptionRowCompatible, Equa return } DispatchQueue.main.async { - self.action?() + self.optionRowAction?() } } } + public var optionRowAction: OptionRowAction? + public override var accessoryType: UITableViewCell.AccessoryType { get { isSelected ? .checkmark : .none } set {} @@ -37,4 +39,21 @@ public extension OptionRow { func isSelected(_ value: Bool) -> Self { reform { $0.isSelected = value } } + + func onTap(_ value: OptionRowAction?) -> Self { + reform { $0.optionRowAction = value } + } + + func onTap(on target: S, _ value: @escaping (S) -> Void) -> Self { + reform { $0.optionRowAction = { value(target) } } + } + + func onTap(on target: S, _ value: @escaping (S) -> Void) -> Self where S: AnyObject { + reform { + $0.optionRowAction = { [weak target] in + guard let target = target else { return } + value(target) + } + } + } } diff --git a/Sources/Jenga/Core/Row/System/SystemRow.swift b/Sources/Jenga/Core/Row/System/SystemRow.swift index 99ee057..16f2b7d 100644 --- a/Sources/Jenga/Core/Row/System/SystemRow.swift +++ b/Sources/Jenga/Core/Row/System/SystemRow.swift @@ -90,7 +90,7 @@ public extension SystemRow { public protocol NavigationRowCompatible: SystemRow { - var accessoryButtonAction: RowAction? { get } + var accessoryButtonAction: (() -> Void)? { get } } public protocol BadgeRowCompatible: SystemRow, AnyObject { diff --git a/Sources/Jenga/Core/Row/TableRow.swift b/Sources/Jenga/Core/Row/TableRow.swift index e3945fa..1beaa05 100644 --- a/Sources/Jenga/Core/Row/TableRow.swift +++ b/Sources/Jenga/Core/Row/TableRow.swift @@ -70,4 +70,26 @@ public extension TableRow { func customize(_ value: @escaping (Cell) -> Void) -> Self { reform { $0.customize = { (cell, _) in value(cell) } } } + + func onTap(_ value: @escaping ((Cell) -> Void)) -> Self { + reform { + $0.action = { cell in + guard let cell = cell as? Cell else { + return + } + value(cell) + } + } + } + + func onTap(_ value: @escaping ((Cell, Cell.CellData) -> Void)) -> Self { + reform { + $0.action = { cell in + guard let cell = cell as? Cell, let data = item?.wrappedValue else { + return + } + value(cell, data) + } + } + } } diff --git a/Sources/Jenga/Core/Row/WrapperRow.swift b/Sources/Jenga/Core/Row/WrapperRow.swift index 477cd9c..86b0292 100644 --- a/Sources/Jenga/Core/Row/WrapperRow.swift +++ b/Sources/Jenga/Core/Row/WrapperRow.swift @@ -90,6 +90,29 @@ public extension WrapperRow { func customize(_ value: @escaping (View) -> Void) -> Self { reform { $0.customize = { (view, _) in value(view) } } } + + + func onTap(_ value: @escaping ((View) -> Void)) -> Self { + reform { + $0.action = { cell in + guard let cell = cell as? Cell else { + return + } + value(cell.view) + } + } + } + + func onTap(_ value: @escaping ((View, Data) -> Void)) -> Self { + reform { + $0.action = { cell in + guard let cell = cell as? Cell, let data = item?.wrappedValue else { + return + } + value(cell.view, data) + } + } + } } extension WrapperRow: Table { } diff --git a/Sources/Jenga/Core/TableDirector.swift b/Sources/Jenga/Core/TableDirector.swift index fc80a08..faa02f7 100644 --- a/Sources/Jenga/Core/TableDirector.swift +++ b/Sources/Jenga/Core/TableDirector.swift @@ -205,16 +205,22 @@ extension TableDirector: UITableViewDelegate { case let (_, option as OptionRowCompatible): option.isSelected = !option.isSelected tableView.reloadData() - + case (_, is TapActionRowCompatible): tableView.deselectRow(at: indexPath, animated: true) DispatchQueue.main.async { - row.action?() + guard let cell = tableView.cellForRow(at: indexPath) else { + return + } + row.action?(cell) } case let (_, row) where row.isSelectable: DispatchQueue.main.async { - row.action?() + guard let cell = tableView.cellForRow(at: indexPath) else { + return + } + row.action?(cell) } default: