From daa7472824e7bef0e67bb665ee2707f6b4fa21bd Mon Sep 17 00:00:00 2001 From: Aleksei Cherepanov Date: Wed, 31 Oct 2018 00:47:03 +0800 Subject: [PATCH 1/8] Custom DropDownCell class initialization for UITableView --- Demo/Base.lproj/Main.storyboard | 29 ++++++++++++------------- Demo/MySecondCell.swift | 34 ++++++++++++++++++++++++++++++ Demo/ViewController.swift | 16 ++++++++++++++ DropDown.xcodeproj/project.pbxproj | 4 ++++ DropDown/src/DropDown.swift | 8 +++++++ 5 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 Demo/MySecondCell.swift diff --git a/Demo/Base.lproj/Main.storyboard b/Demo/Base.lproj/Main.storyboard index 364b07e..3589041 100644 --- a/Demo/Base.lproj/Main.storyboard +++ b/Demo/Base.lproj/Main.storyboard @@ -1,13 +1,11 @@ - + - - - + @@ -20,7 +18,7 @@ - + - + @@ -89,13 +87,13 @@ - + @@ -106,24 +104,25 @@ - + + diff --git a/Demo/MySecondCell.swift b/Demo/MySecondCell.swift new file mode 100644 index 0000000..bd0cd76 --- /dev/null +++ b/Demo/MySecondCell.swift @@ -0,0 +1,34 @@ +// +// MySecondCell.swift +// Demo +// +// Created by Aleksei Cherepanov on 31/10/2018. +// Copyright © 2018 Kevin Hirsch. All rights reserved. +// + +import UIKit +import DropDown + +class MySecondCell: DropDownCell { + var logoImageView = UIImageView(frame: .zero) + var titleView = UILabel(frame: .zero) + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + optionLabel = titleView + + addSubview(logoImageView) + addSubview(titleView) + } + + override func layoutSubviews() { + super.layoutSubviews() + logoImageView.frame = CGRect(origin: .zero, + size: CGSize(width: frame.height, height: frame.height)) + titleView.frame = CGRect(x: frame.height, y: 0, width: frame.width - frame.height, height: frame.height) + } +} diff --git a/Demo/ViewController.swift b/Demo/ViewController.swift index c5130f0..c70a5fb 100644 --- a/Demo/ViewController.swift +++ b/Demo/ViewController.swift @@ -81,6 +81,7 @@ class ViewController: UIViewController { switch sender.selectedSegmentIndex { case 0: setupDefaultDropDown() case 1: customizeDropDown(self) + case 2: customizeDropDownWithClass(self) default: break; } } @@ -134,6 +135,21 @@ class ViewController: UIViewController { /*** ---------------- ***/ } } + + func customizeDropDownWithClass(_ sender: AnyObject) { + dropDowns.forEach { + /*** FOR CUSTOM CELLS ***/ + $0.cellClass = MySecondCell.self + + $0.customCellConfiguration = { (index: Index, item: String, cell: DropDownCell) -> Void in + guard let cell = cell as? MySecondCell else { return } + + // Setup your custom UI components + cell.logoImageView.image = UIImage(named: "logo_\(index % 10)") + } + /*** ---------------- ***/ + } + } //MARK: - UIViewController diff --git a/DropDown.xcodeproj/project.pbxproj b/DropDown.xcodeproj/project.pbxproj index 3b60491..f56c24c 100644 --- a/DropDown.xcodeproj/project.pbxproj +++ b/DropDown.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ 0AB5D89A1D0EF15D002D3A17 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB5D8971D0EF15D002D3A17 /* ViewController.swift */; }; 0AB5D8A11D0EF173002D3A17 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0AB5D89F1D0EF173002D3A17 /* Main.storyboard */; }; 0AC1C33A1B6B884100A8DC0D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0AC1C3391B6B884100A8DC0D /* Images.xcassets */; }; + 945A86E22188BD39007B8D96 /* MySecondCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945A86E12188BD39007B8D96 /* MySecondCell.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -81,6 +82,7 @@ 0AB5D8971D0EF15D002D3A17 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 0AB5D8A01D0EF173002D3A17 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 0AC1C3391B6B884100A8DC0D /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Demo/Images.xcassets; sourceTree = ""; }; + 945A86E12188BD39007B8D96 /* MySecondCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MySecondCell.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -137,6 +139,7 @@ 0AB5D8971D0EF15D002D3A17 /* ViewController.swift */, 0A8518D41D6480190089529A /* MyCell.swift */, 0A8518D61D6481E30089529A /* MyCell.xib */, + 945A86E12188BD39007B8D96 /* MySecondCell.swift */, 0AB5D89F1D0EF173002D3A17 /* Main.storyboard */, 0AB5D8961D0EF15D002D3A17 /* NiceButton.swift */, 0A7644121B676C2300BF1A2D /* Supporting Files */, @@ -360,6 +363,7 @@ 0A8518D51D6480190089529A /* MyCell.swift in Sources */, 0AB5D8991D0EF15D002D3A17 /* NiceButton.swift in Sources */, 0AB5D8981D0EF15D002D3A17 /* AppDelegate.swift in Sources */, + 945A86E22188BD39007B8D96 /* MySecondCell.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/DropDown/src/DropDown.swift b/DropDown/src/DropDown.swift index 42738fa..580ebf8 100644 --- a/DropDown/src/DropDown.swift +++ b/DropDown/src/DropDown.swift @@ -362,6 +362,14 @@ public final class DropDown: UIView { reloadAllComponents() } } + + public var cellClass: AnyClass = DropDownCell.self { + didSet { + tableView.register(cellClass, forCellReuseIdentifier: DPDConstant.ReusableIdentifier.DropDownCell) + templateCell = nil + reloadAllComponents() + } + } //MARK: Content From f6aaf56d43863f90b0fefb79364fca88af4510e1 Mon Sep 17 00:00:00 2001 From: Aleksei Cherepanov Date: Wed, 31 Oct 2018 17:59:56 +0800 Subject: [PATCH 2/8] UIScrollView layout fixed --- Demo/Base.lproj/Main.storyboard | 304 +++++++++++++++++--------------- 1 file changed, 158 insertions(+), 146 deletions(-) diff --git a/Demo/Base.lproj/Main.storyboard b/Demo/Base.lproj/Main.storyboard index 3589041..96c57f9 100644 --- a/Demo/Base.lproj/Main.storyboard +++ b/Demo/Base.lproj/Main.storyboard @@ -1,11 +1,11 @@ - + - + @@ -14,161 +14,173 @@ - - + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - + From 3b6396ff0d633df304dc9528cd5de62bc09449d2 Mon Sep 17 00:00:00 2001 From: Aleksei Cherepanov Date: Wed, 31 Oct 2018 18:11:33 +0800 Subject: [PATCH 3/8] DropDownCustomCell added --- Demo/MySecondCell.swift | 8 ++------ DropDown/src/DropDown.swift | 2 +- DropDown/src/DropDownCell.swift | 14 ++++++++++++++ README.md | 6 ++++++ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Demo/MySecondCell.swift b/Demo/MySecondCell.swift index bd0cd76..56eed51 100644 --- a/Demo/MySecondCell.swift +++ b/Demo/MySecondCell.swift @@ -9,9 +9,8 @@ import UIKit import DropDown -class MySecondCell: DropDownCell { +class MySecondCell: DropDownCustomCell { var logoImageView = UIImageView(frame: .zero) - var titleView = UILabel(frame: .zero) required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) @@ -19,16 +18,13 @@ class MySecondCell: DropDownCell { override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) - optionLabel = titleView - addSubview(logoImageView) - addSubview(titleView) } override func layoutSubviews() { super.layoutSubviews() logoImageView.frame = CGRect(origin: .zero, size: CGSize(width: frame.height, height: frame.height)) - titleView.frame = CGRect(x: frame.height, y: 0, width: frame.width - frame.height, height: frame.height) + optionLabel.frame = CGRect(x: frame.height, y: 0, width: frame.width - frame.height, height: frame.height) } } diff --git a/DropDown/src/DropDown.swift b/DropDown/src/DropDown.swift index 580ebf8..d1054f9 100644 --- a/DropDown/src/DropDown.swift +++ b/DropDown/src/DropDown.swift @@ -363,7 +363,7 @@ public final class DropDown: UIView { } } - public var cellClass: AnyClass = DropDownCell.self { + public var cellClass: DropDownCustomCell.Type = DropDownCustomCell.self { didSet { tableView.register(cellClass, forCellReuseIdentifier: DPDConstant.ReusableIdentifier.DropDownCell) templateCell = nil diff --git a/DropDown/src/DropDownCell.swift b/DropDown/src/DropDownCell.swift index 7a90efc..ce498c2 100644 --- a/DropDown/src/DropDownCell.swift +++ b/DropDown/src/DropDownCell.swift @@ -19,6 +19,20 @@ open class DropDownCell: UITableViewCell { } +open class DropDownCustomCell: DropDownCell { + var strongOptionLabel = UILabel(frame: .zero) + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + override public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + optionLabel = strongOptionLabel + addSubview(strongOptionLabel) + } +} + //MARK: - UI extension DropDownCell { diff --git a/README.md b/README.md index e7d6d31..299eb93 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,12 @@ dropDown.customCellConfiguration = { (index: Index, item: String, cell: DropDown For a complete example, don't hesitate to check the demo app and code. +To avoid NIBs use +```swift +dropDown.cellClass = CellClassName.self +``` +Where `CellClassName` is subclass of `DropDownCustomCell`. + ### Events ```swift From 031eb4188a644841cc1c8e8e5d973023d0e8f718 Mon Sep 17 00:00:00 2001 From: Aleksei Cherepanov Date: Wed, 31 Oct 2018 18:45:14 +0800 Subject: [PATCH 4/8] Checkbox selection example added --- Demo/Base.lproj/Main.storyboard | 7 +++--- Demo/CheckboxCell.swift | 35 ++++++++++++++++++++++++++++++ Demo/ViewController.swift | 11 ++++++++++ DropDown.xcodeproj/project.pbxproj | 4 ++++ DropDown/src/DropDownCell.swift | 2 +- 5 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 Demo/CheckboxCell.swift diff --git a/Demo/Base.lproj/Main.storyboard b/Demo/Base.lproj/Main.storyboard index 96c57f9..415ba85 100644 --- a/Demo/Base.lproj/Main.storyboard +++ b/Demo/Base.lproj/Main.storyboard @@ -109,9 +109,10 @@ - - - + + + + diff --git a/Demo/CheckboxCell.swift b/Demo/CheckboxCell.swift new file mode 100644 index 0000000..050d44f --- /dev/null +++ b/Demo/CheckboxCell.swift @@ -0,0 +1,35 @@ +// +// CheckboxCell.swift +// Demo +// +// Created by Aleksei Cherepanov on 31/10/2018. +// Copyright © 2018 Kevin Hirsch. All rights reserved. +// + +import UIKit +import DropDown + +class CheckboxCell: DropDownCustomCell { + + override func setSelected(_ selected: Bool, animated: Bool) { + let executeSelection: () -> Void = { [weak self] in + guard let `self` = self else { return } + self.accessoryType = selected ? .checkmark : .none + } + + if animated { + UIView.animate(withDuration: 0.3, animations: { + executeSelection() + }) + } else { + executeSelection() + } + accessibilityTraits = selected ? .selected : .none + } + + override func layoutSubviews() { + super.layoutSubviews() + optionLabel.frame = contentView.bounds + } + +} diff --git a/Demo/ViewController.swift b/Demo/ViewController.swift index c70a5fb..4afed47 100644 --- a/Demo/ViewController.swift +++ b/Demo/ViewController.swift @@ -82,6 +82,7 @@ class ViewController: UIViewController { case 0: setupDefaultDropDown() case 1: customizeDropDown(self) case 2: customizeDropDownWithClass(self) + case 3: customizeDropDownSelector(self) default: break; } } @@ -150,6 +151,16 @@ class ViewController: UIViewController { /*** ---------------- ***/ } } + + func customizeDropDownSelector(_ sender: AnyObject) { + dropDowns.forEach { + /*** FOR CUSTOM CELLS ***/ + $0.cellClass = CheckboxCell.self + $0.customCellConfiguration = nil + } + } + + //MARK: - UIViewController diff --git a/DropDown.xcodeproj/project.pbxproj b/DropDown.xcodeproj/project.pbxproj index f56c24c..fc3fecf 100644 --- a/DropDown.xcodeproj/project.pbxproj +++ b/DropDown.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ 0AB5D89A1D0EF15D002D3A17 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB5D8971D0EF15D002D3A17 /* ViewController.swift */; }; 0AB5D8A11D0EF173002D3A17 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0AB5D89F1D0EF173002D3A17 /* Main.storyboard */; }; 0AC1C33A1B6B884100A8DC0D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0AC1C3391B6B884100A8DC0D /* Images.xcassets */; }; + 9442B7DB2189B8EC000720B8 /* CheckboxCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9442B7DA2189B8EC000720B8 /* CheckboxCell.swift */; }; 945A86E22188BD39007B8D96 /* MySecondCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945A86E12188BD39007B8D96 /* MySecondCell.swift */; }; /* End PBXBuildFile section */ @@ -82,6 +83,7 @@ 0AB5D8971D0EF15D002D3A17 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 0AB5D8A01D0EF173002D3A17 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 0AC1C3391B6B884100A8DC0D /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Demo/Images.xcassets; sourceTree = ""; }; + 9442B7DA2189B8EC000720B8 /* CheckboxCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxCell.swift; sourceTree = ""; }; 945A86E12188BD39007B8D96 /* MySecondCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MySecondCell.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -140,6 +142,7 @@ 0A8518D41D6480190089529A /* MyCell.swift */, 0A8518D61D6481E30089529A /* MyCell.xib */, 945A86E12188BD39007B8D96 /* MySecondCell.swift */, + 9442B7DA2189B8EC000720B8 /* CheckboxCell.swift */, 0AB5D89F1D0EF173002D3A17 /* Main.storyboard */, 0AB5D8961D0EF15D002D3A17 /* NiceButton.swift */, 0A7644121B676C2300BF1A2D /* Supporting Files */, @@ -361,6 +364,7 @@ files = ( 0AB5D89A1D0EF15D002D3A17 /* ViewController.swift in Sources */, 0A8518D51D6480190089529A /* MyCell.swift in Sources */, + 9442B7DB2189B8EC000720B8 /* CheckboxCell.swift in Sources */, 0AB5D8991D0EF15D002D3A17 /* NiceButton.swift in Sources */, 0AB5D8981D0EF15D002D3A17 /* AppDelegate.swift in Sources */, 945A86E22188BD39007B8D96 /* MySecondCell.swift in Sources */, diff --git a/DropDown/src/DropDownCell.swift b/DropDown/src/DropDownCell.swift index ce498c2..afbb185 100644 --- a/DropDown/src/DropDownCell.swift +++ b/DropDown/src/DropDownCell.swift @@ -29,7 +29,7 @@ open class DropDownCustomCell: DropDownCell { override public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) optionLabel = strongOptionLabel - addSubview(strongOptionLabel) + contentView.addSubview(strongOptionLabel) } } From 64ab4c4a5ac0cb3bcfa592445577342668270241 Mon Sep 17 00:00:00 2001 From: Aleksei Cherepanov Date: Wed, 31 Oct 2018 18:50:08 +0800 Subject: [PATCH 5/8] Manual layout in MySecondCell fixed --- Demo/MySecondCell.swift | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Demo/MySecondCell.swift b/Demo/MySecondCell.swift index 56eed51..46e8551 100644 --- a/Demo/MySecondCell.swift +++ b/Demo/MySecondCell.swift @@ -18,13 +18,22 @@ class MySecondCell: DropDownCustomCell { override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) - addSubview(logoImageView) + contentView.addSubview(logoImageView) } override func layoutSubviews() { super.layoutSubviews() - logoImageView.frame = CGRect(origin: .zero, - size: CGSize(width: frame.height, height: frame.height)) - optionLabel.frame = CGRect(x: frame.height, y: 0, width: frame.width - frame.height, height: frame.height) + let size = contentView.bounds.size + let imageSize = logoImageView.image?.size ?? .zero + let padding: CGFloat = 4 + logoImageView.frame = CGRect(x: padding, + y: (frame.height - imageSize.height)/2, + width: imageSize.width, + height: imageSize.height) + let offset = padding * 2 + imageSize.width + optionLabel.frame = CGRect(x: offset, + y: 0, + width: size.width - offset, + height: size.height) } } From 9fd89e549548f2746ef8662cb52d6efb56ceb7fb Mon Sep 17 00:00:00 2001 From: Aleksei Cherepanov Date: Wed, 31 Oct 2018 22:52:40 +0800 Subject: [PATCH 6/8] Separator inset added --- DropDown/helpers/DPDConstants.swift | 1 + DropDown/src/DropDown.swift | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/DropDown/helpers/DPDConstants.swift b/DropDown/helpers/DPDConstants.swift index b5caa30..68f40d0 100644 --- a/DropDown/helpers/DPDConstants.swift +++ b/DropDown/helpers/DPDConstants.swift @@ -30,6 +30,7 @@ internal struct DPDConstant { static let BackgroundColor = UIColor(white: 0.94, alpha: 1) static let SelectionBackgroundColor = UIColor(white: 0.89, alpha: 1) static let SeparatorColor = UIColor.clear + static let SeparatorInset = UIEdgeInsets.zero static let CornerRadius: CGFloat = 2 static let RowHeight: CGFloat = 44 static let HeightPadding: CGFloat = 20 diff --git a/DropDown/src/DropDown.swift b/DropDown/src/DropDown.swift index d1054f9..17c2438 100644 --- a/DropDown/src/DropDown.swift +++ b/DropDown/src/DropDown.swift @@ -216,6 +216,16 @@ public final class DropDown: UIView { willSet { tableView.separatorColor = newValue } didSet { reloadAllComponents() } } + + /** + The separator inset + + Changing the separator inset automatically reloads the drop down. + */ + @objc public dynamic var separatorInset = DPDConstant.UI.SeparatorInset { + willSet { tableView.separatorInset = newValue } + didSet { reloadAllComponents() } + } /** The corner radius of DropDown. @@ -546,6 +556,7 @@ private extension DropDown { tableView.backgroundColor = tableViewBackgroundColor tableView.separatorColor = separatorColor + tableView.separatorInset = separatorInset tableView.layer.cornerRadius = cornerRadius tableView.layer.masksToBounds = true } From dec80380f50344c0d1fdb70896c8b2e2f67dd078 Mon Sep 17 00:00:00 2001 From: Aleksei Cherepanov Date: Wed, 7 Nov 2018 10:10:03 +0800 Subject: [PATCH 7/8] AnchorView from dropdown width calculating removed --- Demo/CheckboxCell.swift | 7 +++++++ DropDown/src/DropDown.swift | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Demo/CheckboxCell.swift b/Demo/CheckboxCell.swift index 050d44f..c1f2f7e 100644 --- a/Demo/CheckboxCell.swift +++ b/Demo/CheckboxCell.swift @@ -27,6 +27,13 @@ class CheckboxCell: DropDownCustomCell { accessibilityTraits = selected ? .selected : .none } + override func systemLayoutSizeFitting(_ targetSize: CGSize) -> CGSize { + let contentSize = optionLabel.systemLayoutSizeFitting(targetSize) + let accessoryViewWidth:CGFloat = 40 + return CGSize(width: contentSize.width + accessoryViewWidth, + height: contentSize.height) + } + override func layoutSubviews() { super.layoutSubviews() optionLabel.frame = contentView.bounds diff --git a/DropDown/src/DropDown.swift b/DropDown/src/DropDown.swift index 17c2438..fe3864d 100644 --- a/DropDown/src/DropDown.swift +++ b/DropDown/src/DropDown.swift @@ -725,7 +725,7 @@ extension DropDown { fileprivate func computeLayoutBottomDisplay(window: UIWindow) -> ComputeLayoutTuple { var offscreenHeight: CGFloat = 0 - let width = self.width ?? (anchorView?.plainView.bounds.width ?? fittingWidth()) - bottomOffset.x + let width = self.width ?? fittingWidth() - bottomOffset.x let anchorViewX = anchorView?.plainView.windowFrame?.minX ?? window.frame.midX - (width / 2) let anchorViewY = anchorView?.plainView.windowFrame?.minY ?? window.frame.midY - (tableHeight / 2) @@ -771,13 +771,14 @@ extension DropDown { fileprivate func fittingWidth() -> CGFloat { if templateCell == nil { - templateCell = (cellNib.instantiate(withOwner: nil, options: nil)[0] as! DropDownCell) + templateCell = (tableView.dequeueReusableCell(withIdentifier: DPDConstant.ReusableIdentifier.DropDownCell) as! DropDownCell) } var maxWidth: CGFloat = 0 for index in 0.. Date: Wed, 7 Nov 2018 11:53:15 +0800 Subject: [PATCH 8/8] Arrow Indicator position calculation added --- Demo/ViewController.swift | 2 ++ DropDown/src/DropDown.swift | 39 ++++++++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/Demo/ViewController.swift b/Demo/ViewController.swift index 4afed47..42f5743 100644 --- a/Demo/ViewController.swift +++ b/Demo/ViewController.swift @@ -170,6 +170,8 @@ class ViewController: UIViewController { setupDropDowns() dropDowns.forEach { $0.dismissMode = .onTap } dropDowns.forEach { $0.direction = .any } + + dropDowns.forEach { $0.showArrowIndicator = true } view.addSubview(textField) } diff --git a/DropDown/src/DropDown.swift b/DropDown/src/DropDown.swift index fe3864d..401e6ef 100644 --- a/DropDown/src/DropDown.swift +++ b/DropDown/src/DropDown.swift @@ -159,15 +159,21 @@ public final class DropDown: UIView { */ public var arrowIndicationX: CGFloat? { didSet { - if let arrowIndicationX = arrowIndicationX { - tableViewContainer.addSubview(arrowIndication) - arrowIndication.tintColor = tableViewBackgroundColor - arrowIndication.frame.origin.x = arrowIndicationX - } else { - arrowIndication.removeFromSuperview() - } + guard let x = arrowIndicationX else { return } + arrowIndication.frame.origin.x = x + showArrowIndicator = true } } + public var showArrowIndicator: Bool = false { + didSet { + if showArrowIndicator { + tableViewContainer.addSubview(arrowIndication) + arrowIndication.tintColor = tableViewBackgroundColor + } else { + arrowIndication.removeFromSuperview() + } + } + } //MARK: Constraints fileprivate var heightConstraint: NSLayoutConstraint! @@ -184,7 +190,7 @@ public final class DropDown: UIView { @objc fileprivate dynamic var tableViewBackgroundColor = DPDConstant.UI.BackgroundColor { willSet { tableView.backgroundColor = newValue - if arrowIndicationX != nil { arrowIndication.tintColor = newValue } + if showArrowIndicator { arrowIndication.tintColor = newValue } } } @@ -712,13 +718,18 @@ extension DropDown { direction = .top } } - + constraintWidthToFittingSizeIfNecessary(layout: &layout) constraintWidthToBoundsIfNecessary(layout: &layout, in: window) let visibleHeight = tableHeight - layout.offscreenHeight let canBeDisplayed = visibleHeight >= minHeight + if showArrowIndicator { + arrowIndication.frame.origin.x = computeArrowIndicator(window: window, + layout: layout) + } + return (layout.x, layout.y, layout.width, layout.offscreenHeight, visibleHeight, canBeDisplayed, direction) } @@ -768,6 +779,16 @@ extension DropDown { return (x, y, width, offscreenHeight) } + + fileprivate func computeArrowIndicator(window: UIWindow, layout: ComputeLayoutTuple) -> CGFloat { + if let x = arrowIndicationX { return x } + guard let anchorViewX = anchorView?.plainView.windowFrame?.minX else { + return layout.width / 2 + } + let anchorViewWidth = anchorView?.plainView.bounds.width ?? 0 + let leftSpacing = max(anchorViewX - layout.x, 0) + return leftSpacing + anchorViewWidth/2 + } fileprivate func fittingWidth() -> CGFloat { if templateCell == nil {