Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 1 addition & 19 deletions Example/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="JZm-MP-9P9">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
Expand All @@ -26,23 +26,5 @@
</objects>
<point key="canvasLocation" x="1079.2" y="133.5832083958021"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="B0W-MR-hZe">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="JZm-MP-9P9" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="Mth-AM-Dsm">
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="BYZ-38-t0r" kind="relationship" relationship="rootViewController" id="F6K-zW-Nuc"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="zBz-6N-fe8" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="158" y="134"/>
</scene>
</scenes>
</document>
2 changes: 1 addition & 1 deletion Example/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ViewController: FormViewController {
row.placeholder = "Location"
}.onPresent({ (_, presentingViewController) in
presentingViewController.title = "Location"
presentingViewController.placeholder = "Enter Location"
presentingViewController.searchPlaceholder = "Enter Location"
})
}
}
Expand Down
4 changes: 0 additions & 4 deletions LocationRow.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

/* Begin PBXBuildFile section */
2823556C221CC5B400DF4771 /* LocationRow.h in Headers */ = {isa = PBXBuildFile; fileRef = 2823556A221CC5B400DF4771 /* LocationRow.h */; settings = {ATTRIBUTES = (Public, ); }; };
28235575221CC62100DF4771 /* LocationCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28235572221CC62100DF4771 /* LocationCell.xib */; };
28235576221CC62100DF4771 /* LocationRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28235573221CC62100DF4771 /* LocationRow.swift */; };
28235577221CC62100DF4771 /* LocationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28235574221CC62100DF4771 /* LocationViewController.swift */; };
2823557A221CC80700DF4771 /* Eureka.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28235579221CC80700DF4771 /* Eureka.framework */; };
Expand All @@ -20,7 +19,6 @@
28235567221CC5B400DF4771 /* LocationRow.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LocationRow.framework; sourceTree = BUILT_PRODUCTS_DIR; };
2823556A221CC5B400DF4771 /* LocationRow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LocationRow.h; sourceTree = "<group>"; };
2823556B221CC5B400DF4771 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
28235572221CC62100DF4771 /* LocationCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LocationCell.xib; sourceTree = "<group>"; };
28235573221CC62100DF4771 /* LocationRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationRow.swift; sourceTree = "<group>"; };
28235574221CC62100DF4771 /* LocationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationViewController.swift; sourceTree = "<group>"; };
28235579221CC80700DF4771 /* Eureka.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Eureka.framework; path = Carthage/Build/iOS/Eureka.framework; sourceTree = "<group>"; };
Expand Down Expand Up @@ -60,7 +58,6 @@
28235569221CC5B400DF4771 /* LocationRow */ = {
isa = PBXGroup;
children = (
28235572221CC62100DF4771 /* LocationCell.xib */,
28235573221CC62100DF4771 /* LocationRow.swift */,
28235574221CC62100DF4771 /* LocationViewController.swift */,
2823556A221CC5B400DF4771 /* LocationRow.h */,
Expand Down Expand Up @@ -150,7 +147,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
28235575221CC62100DF4771 /* LocationCell.xib in Resources */,
28235598221D006500DF4771 /* Assets.xcassets in Resources */,
2823557C221CCD8B00DF4771 /* LocationViewController.xib in Resources */,
);
Expand Down
42 changes: 0 additions & 42 deletions LocationRow/LocationCell.xib

This file was deleted.

60 changes: 38 additions & 22 deletions LocationRow/LocationRow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,60 @@ import Eureka
import Foundation

public final class LocationCell: PushSelectorCell<CLPlacemark> {
@IBOutlet public var clearButton: UIButton! {
didSet {
clearButton.setImage(UIImage(named: "Clear", in: Bundle.current, compatibleWith: nil)?.withRenderingMode(.alwaysTemplate), for: .normal)
clearButton.tintColor = .lightGray
}
}
@IBOutlet public weak var clearButton: UIButton!

required init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)

let clearButton = UIButton(frame: CGRect(x: 0, y: 0, width: 18, height: 18))
clearButton.setImage(UIImage(named: "Clear", in: Bundle.current, compatibleWith: nil)?.withRenderingMode(.alwaysTemplate), for: .normal)
clearButton.tintColor = .lightGray

self.clearButton = clearButton

accessoryView = clearButton
editingAccessoryView = accessoryView
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

deinit {
clearButton?.removeTarget(self, action: nil, for: .allEvents)
}

public override func setup() {
super.setup()

clearButton.addTarget(self, action: #selector(LocationCell.clear), for: .touchUpInside)
}

public override func update() {
super.update()

detailTextLabel?.text = nil
accessoryType = .none

guard let row = self.row as? LocationRow else { return }

let isEmpty = row.value?.name?.isEmpty ?? true

textLabel?.text = row.value?.name ?? row.placeholder
textLabel?.textColor = row.value?.name != nil ? .black : UIColor(red: 198 / 255, green: 198 / 255, blue: 204 / 255, alpha: 1)
textLabel?.textColor = isEmpty ? UIColor(red: 198 / 255, green: 198 / 255, blue: 204 / 255, alpha: 1) : row.isDisabled ? .gray : .black

clearButton.isHidden = row.value?.name == nil
clearButton.isHidden = isEmpty
clearButton.isEnabled = !row.isDisabled
}

@IBAction func clear(_: Any) {
@objc
func clear() {
row.value = nil
update()
}
}

public final class LocationRow: Row<LocationCell>, RowType, PresenterRowType {
public typealias PresenterRow = LocationViewController
public typealias PresenterRow = LocationNavigationController

public var presentationMode: PresentationMode<PresenterRow>?
public var onPresentCallback: ((FormViewController, PresenterRow) -> Void)?
Expand All @@ -50,35 +67,34 @@ public final class LocationRow: Row<LocationCell>, RowType, PresenterRowType {

public required init(tag: String?) {
super.init(tag: tag)

cellProvider = CellProvider<LocationCell>(nibName: "LocationCell", bundle: Bundle.current)
}

public override func customDidSelect() {
super.customDidSelect()

guard let controller = makeController() else { return }
guard !isDisabled else { return }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can allow the user to set up a title and use the detailTextView as the value. By doing that the user can opt by leaving empty the title and we will get the same result as now.

I would recommend to add the cell clear button as cell accessoryView.

We also have to change cell color title when row is disabled in order to indicate that.

Take a look at switchCell to see how we do it.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend to add the cell clear button as cell accessoryView.

Done in f04a8b0

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also have to change cell color title when row is disabled in order to indicate that.

Done in ccd09f6

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can allow the user to set up a title and use the detailTextView as the value. By doing that the user can opt by leaving empty the title and we will get the same result as now.

@mtnbarreto There are a couple of reasons I would prefer the leave this as is (at least for the moment), where only the textLabel is used to display the location value / placeholder.

  1. For a consistent look and feel with the Apple location field in the Calendar app.
  2. Setting the title (textLabel) text to empty / nil does not auto left align the detailTextLabel in UITableViewCell. I can achieve this by adding constraints however the look and feel of the cell can then dynamically change from a left aligned title and right aligned value to no title and a left aligned value depending on the value of row.title. I don't particularly like this dynamic change in look and feel. This too of course can be further enhanced by allowing the user to choose the layout style, say title and value or value only but I rather implement this as a future improvement.

Let me know if these reasonings are acceptable.


presentationMode = PresentationMode.show(controllerProvider: ControllerProvider.callback {
controller
}, onDismiss: { viewController in
_ = viewController.navigationController?.popViewController(animated: true)
presentationMode = PresentationMode.presentModally(controllerProvider: ControllerProvider.callback {
let bar = LocationViewController(nibName: "LocationViewController", bundle: Bundle.current)
return LocationNavigationController(rootViewController: bar)
}, onDismiss: { viewController in
viewController.presentingViewController?.dismiss(animated: true)
})

guard let presentationMode = presentationMode, !isDisabled else { return }

if let controller = presentationMode.makeController() {
controller.row = self

onPresentCallback?(cell.formViewController()!, controller)

controller.topViewController?.title = controller.title

presentationMode.present(controller, row: self, presentingController: cell.formViewController()!)
} else {
presentationMode.present(nil, row: self, presentingController: cell.formViewController()!)
}
}

private func makeController() -> LocationViewController? {
return LocationViewController(nibName: "LocationViewController", bundle: Bundle.current)
}
}

private extension Bundle {
Expand Down
34 changes: 25 additions & 9 deletions LocationRow/LocationViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import Eureka
import Foundation
import MapKit

public final class LocationViewController: UIViewController, TypedRowControllerType {
public var row: RowOf<CLPlacemark>!
public var onDismissCallback: ((UIViewController) -> Void)?

public var placeholder: String?

public final class LocationViewController: UIViewController {
@IBOutlet var tableView: UITableView!

var searchBar: UISearchBar? {
return searchController.searchBar
}

private let searchController = UISearchController(searchResultsController: nil)
private var searchResults: [MKMapItem] = []

Expand All @@ -24,7 +23,7 @@ public final class LocationViewController: UIViewController, TypedRowControllerT
searchController.obscuresBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation = false

searchController.searchBar.placeholder = placeholder ?? "Enter Location"
navigationItem.setRightBarButton(UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(LocationViewController.dismiss(_:))), animated: false)

navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false
Expand All @@ -35,6 +34,11 @@ public final class LocationViewController: UIViewController, TypedRowControllerT
definesPresentationContext = true
}

@objc
func dismiss(_ sender: Any) {
(navigationController as? LocationNavigationController)?.onDismissCallback?(self)
}

private func address(for placemark: MKPlacemark) -> String {
let address: [String?] = [
[placemark.subThoroughfare, placemark.thoroughfare].compactMap { $0 }.joined(separator: " "),
Expand Down Expand Up @@ -88,8 +92,20 @@ extension LocationViewController: UITableViewDataSource {

extension LocationViewController: UITableViewDelegate {
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
row.value = searchResults[indexPath.row].placemark
guard let navigationController = navigationController as? LocationNavigationController else { return }

navigationController?.popViewController(animated: true)
navigationController.row.value = searchResults[indexPath.row].placemark
navigationController.onDismissCallback?(self)
}
}

public class LocationNavigationController: UINavigationController, TypedRowControllerType {
public var row: RowOf<CLPlacemark>!
public var onDismissCallback: ((UIViewController) -> Void)?

public var searchPlaceholder: String? {
didSet {
(topViewController as? LocationViewController)?.searchBar?.placeholder = searchPlaceholder
}
}
}
18 changes: 6 additions & 12 deletions LocationRow/LocationViewController.xib
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="LocationViewController" customModule="LocationRow" customModuleProvider="target">
<connections>
<outlet property="tableView" destination="VlU-1g-l7A" id="d3E-ij-fe5"/>
<outlet property="tableView" destination="VlU-1g-l7A" id="W3Q-La-78Y"/>
<outlet property="view" destination="BQ4-yt-hqm" id="IPL-4S-by8"/>
</connections>
</placeholder>
Expand All @@ -21,29 +21,23 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mMR-k2-eKa">
<rect key="frame" x="46" y="8" width="42" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="VlU-1g-l7A">
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
<rect key="frame" x="0.0" y="64" width="375" height="603"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<connections>
<outlet property="dataSource" destination="-1" id="57d-2m-BJk"/>
<outlet property="delegate" destination="-1" id="PIE-Nt-YG2"/>
<outlet property="dataSource" destination="-1" id="Ujf-6E-Lxb"/>
<outlet property="delegate" destination="-1" id="jVB-CG-qyg"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="BMK-1t-lWj" firstAttribute="bottom" secondItem="VlU-1g-l7A" secondAttribute="bottom" id="G5q-R1-TtV"/>
<constraint firstItem="VlU-1g-l7A" firstAttribute="top" secondItem="BMK-1t-lWj" secondAttribute="top" id="PiP-d8-Lhi"/>
<constraint firstItem="VlU-1g-l7A" firstAttribute="leading" secondItem="BMK-1t-lWj" secondAttribute="leading" id="YYN-g2-qO0"/>
<constraint firstItem="VlU-1g-l7A" firstAttribute="top" secondItem="BMK-1t-lWj" secondAttribute="top" id="aMV-N9-a0I"/>
<constraint firstItem="BMK-1t-lWj" firstAttribute="trailing" secondItem="VlU-1g-l7A" secondAttribute="trailing" id="fMC-cv-Nav"/>
</constraints>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
<viewLayoutGuide key="safeArea" id="BMK-1t-lWj"/>
<point key="canvasLocation" x="953" y="807"/>
</view>
Expand Down