From f953e0c71fa325465d8e7090e85f133f1f97d91e Mon Sep 17 00:00:00 2001 From: Phillip Kast Date: Fri, 18 Jan 2019 17:52:43 -0800 Subject: [PATCH 1/3] Add a .segmentedControl accessory --- Static.xcodeproj/project.pbxproj | 4 +++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++++++ Static/Row.swift | 6 +++++ Static/SegmentedControlAccessory.swift | 26 +++++++++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 Static.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 Static/SegmentedControlAccessory.swift diff --git a/Static.xcodeproj/project.pbxproj b/Static.xcodeproj/project.pbxproj index 6d6f0ee..0a6b8e2 100644 --- a/Static.xcodeproj/project.pbxproj +++ b/Static.xcodeproj/project.pbxproj @@ -28,6 +28,7 @@ 36748D591B5034EC0046F207 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 36748D581B5034EC0046F207 /* Assets.xcassets */; }; 36748D5C1B5034EC0046F207 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 36748D5A1B5034EC0046F207 /* LaunchScreen.storyboard */; }; 39DC804A1BD96BB0001F04CD /* NibTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39DC80491BD96BB0001F04CD /* NibTableViewCell.swift */; }; + 4AEF73EB21F2B802004927DA /* SegmentedControlAccessory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AEF73EA21F2B802004927DA /* SegmentedControlAccessory.swift */; }; A706253D1BC81C1400E471EF /* CustomTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A706253B1BC81C1400E471EF /* CustomTableViewCell.swift */; }; A706253E1BC81C1400E471EF /* NibTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A706253C1BC81C1400E471EF /* NibTableViewCell.xib */; }; B84E13F720555E26001D6C99 /* SwitchAccessory.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84E13F620555E26001D6C99 /* SwitchAccessory.swift */; }; @@ -89,6 +90,7 @@ 36799F981B41C857009A9D16 /* Cell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cell.swift; sourceTree = ""; }; 36C8FE9A1B4EECF30004DA5B /* TableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = ""; }; 39DC80491BD96BB0001F04CD /* NibTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NibTableViewCell.swift; sourceTree = ""; }; + 4AEF73EA21F2B802004927DA /* SegmentedControlAccessory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentedControlAccessory.swift; sourceTree = ""; }; A706253B1BC81C1400E471EF /* CustomTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomTableViewCell.swift; sourceTree = ""; }; A706253C1BC81C1400E471EF /* NibTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NibTableViewCell.xib; sourceTree = ""; }; B84E13F620555E26001D6C99 /* SwitchAccessory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwitchAccessory.swift; sourceTree = ""; }; @@ -150,6 +152,7 @@ 21826AC61B3F51D000AA9641 /* Section.swift */, 21826AC51B3F51D000AA9641 /* Row.swift */, B84E13F620555E26001D6C99 /* SwitchAccessory.swift */, + 4AEF73EA21F2B802004927DA /* SegmentedControlAccessory.swift */, 366AB2E91B4DFCDD002C4717 /* Cells */, 21826AAF1B3F51A100AA9641 /* Info.plist */, 366AB2ED1B4EE1A7002C4717 /* Tests */, @@ -342,6 +345,7 @@ files = ( 21F219631D10B7B9001EC0F5 /* SubtitleCell.swift in Sources */, 21F219611D10B7A9001EC0F5 /* Value1Cell.swift in Sources */, + 4AEF73EB21F2B802004927DA /* SegmentedControlAccessory.swift in Sources */, B84E13F720555E26001D6C99 /* SwitchAccessory.swift in Sources */, 21826ACA1B3F51D000AA9641 /* Row.swift in Sources */, 21F219671D10B7CF001EC0F5 /* Section.swift in Sources */, diff --git a/Static.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Static.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Static.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Static/Row.swift b/Static/Row.swift index edf61da..04da7dd 100644 --- a/Static/Row.swift +++ b/Static/Row.swift @@ -3,6 +3,7 @@ import UIKit /// Row or Accessory selection callback. public typealias Selection = () -> Void public typealias ValueChange = (Bool) -> () +public typealias SegmentedControlValueChange = (Int, Any?) -> () /// Representation of a table row. public struct Row: Hashable, Equatable { @@ -32,6 +33,9 @@ public struct Row: Hashable, Equatable { /// Switch. Handles value change. case switchToggle(value: Bool, ValueChange) + + /// Segmented control. Handles value change. + case segmentedControl(items: [Any], selectedIndex: Int, SegmentedControlValueChange) /// Custom view case view(UIView) @@ -55,6 +59,8 @@ public struct Row: Hashable, Equatable { return SwitchAccessory(initialValue: value, valueChange: valueChange) case .checkmarkPlaceholder: return UIView(frame: CGRect(x: 0, y: 0, width: 24, height: 24)) + case .segmentedControl(let items, let selectedIndex, let valueChange): + return SegmentedControlAccessory(items: items, selectedIndex: selectedIndex, valueChange: valueChange) default: return nil } } diff --git a/Static/SegmentedControlAccessory.swift b/Static/SegmentedControlAccessory.swift new file mode 100644 index 0000000..deff46c --- /dev/null +++ b/Static/SegmentedControlAccessory.swift @@ -0,0 +1,26 @@ +import UIKit + +class SegmentedControlAccessory: UISegmentedControl { + typealias ValueChange = (Int, Any?) -> () + var valueChange: ValueChange? = nil + + init(items: [Any], selectedIndex: Int, valueChange: (ValueChange)? = nil) { + super.init(items: items) + + self.valueChange = valueChange + self.selectedSegmentIndex = selectedIndex + addTarget(self, action: #selector(valueChanged), for: .valueChanged) + } + + fileprivate init() {super.init(frame: .zero)} + fileprivate override init(frame: CGRect) {super.init(frame: frame)} + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func valueChanged() { + let segmentContents: Any? = titleForSegment(at: selectedSegmentIndex) ?? imageForSegment(at: selectedSegmentIndex) + valueChange?(selectedSegmentIndex, segmentContents) + } +} From 76ca55205e46b32a4e57e195984b1b07458840c8 Mon Sep 17 00:00:00 2001 From: Phillip Kast Date: Fri, 18 Jan 2019 18:03:48 -0800 Subject: [PATCH 2/3] Add segmented control row to example app --- Example/ViewController.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Example/ViewController.swift b/Example/ViewController.swift index 95061e6..5ad68db 100644 --- a/Example/ViewController.swift +++ b/Example/ViewController.swift @@ -58,6 +58,9 @@ class ViewController: TableViewController { Row(text: "UISwitch", accessory: .switchToggle(value: false) { [unowned self] newValue in self.showAlert(title: "Switch Toggled: \(newValue ? "On" : "Off")") }), + Row(text: "Segmented control", accessory: .segmentedControl(items: ["Left", "Middle", "Right"], selectedIndex: 1) { [unowned self] (i, str) in + self.showAlert(title: "Segment \"\(str!)\" at index \(i) selected") + }), Row(text: "Custom View", accessory: .view(customAccessory), accessibilityIdentifier: "CustomView") ], footer: "Try tapping the ⓘ buttons."), Section(header: "Selection", rows: [ From b1e18359666443f8a02435a034a50adf0a4b270f Mon Sep 17 00:00:00 2001 From: Phillip Kast Date: Fri, 18 Jan 2019 18:32:53 -0800 Subject: [PATCH 3/3] Make SegmentedControlAccessory open --- Static/SegmentedControlAccessory.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Static/SegmentedControlAccessory.swift b/Static/SegmentedControlAccessory.swift index deff46c..66d8e5a 100644 --- a/Static/SegmentedControlAccessory.swift +++ b/Static/SegmentedControlAccessory.swift @@ -1,10 +1,10 @@ import UIKit -class SegmentedControlAccessory: UISegmentedControl { - typealias ValueChange = (Int, Any?) -> () +open class SegmentedControlAccessory: UISegmentedControl { + public typealias ValueChange = (Int, Any?) -> () var valueChange: ValueChange? = nil - init(items: [Any], selectedIndex: Int, valueChange: (ValueChange)? = nil) { + public init(items: [Any], selectedIndex: Int, valueChange: (ValueChange)? = nil) { super.init(items: items) self.valueChange = valueChange @@ -12,10 +12,10 @@ class SegmentedControlAccessory: UISegmentedControl { addTarget(self, action: #selector(valueChanged), for: .valueChanged) } - fileprivate init() {super.init(frame: .zero)} - fileprivate override init(frame: CGRect) {super.init(frame: frame)} + public init() {super.init(frame: .zero)} + public override init(frame: CGRect) {super.init(frame: frame)} - required init?(coder aDecoder: NSCoder) { + public required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }