Commit 6b085653 authored by Zac Wood's avatar Zac Wood
Browse files

Added search

parent 791ba248
...@@ -10,95 +10,6 @@ ...@@ -10,95 +10,6 @@
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<scenes> <scenes>
<!--What's Open-->
<scene sceneID="mvU-3a-6pj">
<objects>
<tableViewController id="qgd-YS-8BQ" customClass="MainTableViewController" customModule="WhatsOpen" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="89" sectionHeaderHeight="28" sectionFooterHeight="28" id="kaY-rU-2In">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="Cell" rowHeight="89" id="hUU-na-lag" customClass="SRCTSimpleTableViewCell" customModule="WhatsOpen" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="375" height="89"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="hUU-na-lag" id="Ctl-yf-TXC">
<rect key="frame" x="0.0" y="0.0" width="375" height="88.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="CLOSED" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="096-jU-K7m">
<rect key="frame" x="275" y="11" width="84" height="29"/>
<color key="backgroundColor" red="1" green="0.29840450600000001" blue="0.060627813330000002" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="width" constant="84" id="vqQ-Sa-wvE"/>
<constraint firstAttribute="height" constant="29" id="wGn-A0-rvu"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Opens tomorrow at 9am" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DPA-Nu-eyP">
<rect key="frame" x="16" y="48" width="343" height="28"/>
<constraints>
<constraint firstAttribute="height" constant="28" id="zkw-SM-0t0"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Panera" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UvO-Lp-vwb">
<rect key="frame" x="16" y="11" width="251" height="28"/>
<constraints>
<constraint firstAttribute="height" constant="28" id="rXq-zk-e92"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="23"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="096-jU-K7m" firstAttribute="leading" secondItem="UvO-Lp-vwb" secondAttribute="trailing" constant="8" id="1al-XN-BCE"/>
<constraint firstItem="096-jU-K7m" firstAttribute="trailing" secondItem="Ctl-yf-TXC" secondAttribute="trailingMargin" id="6UF-4t-SpV"/>
<constraint firstItem="DPA-Nu-eyP" firstAttribute="trailing" secondItem="Ctl-yf-TXC" secondAttribute="trailingMargin" id="dqb-HV-QxH"/>
<constraint firstItem="UvO-Lp-vwb" firstAttribute="leading" secondItem="Ctl-yf-TXC" secondAttribute="leadingMargin" id="j2P-gy-Nz2"/>
<constraint firstItem="DPA-Nu-eyP" firstAttribute="top" secondItem="096-jU-K7m" secondAttribute="bottom" constant="8" id="lql-J9-fsf"/>
<constraint firstItem="096-jU-K7m" firstAttribute="top" secondItem="Ctl-yf-TXC" secondAttribute="topMargin" id="tZL-iQ-yD8"/>
<constraint firstItem="UvO-Lp-vwb" firstAttribute="top" secondItem="Ctl-yf-TXC" secondAttribute="topMargin" id="y3i-xc-tPG"/>
<constraint firstItem="DPA-Nu-eyP" firstAttribute="leading" secondItem="Ctl-yf-TXC" secondAttribute="leadingMargin" id="zI0-jy-OSD"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="nameLabel" destination="UvO-Lp-vwb" id="X0e-1G-yNd"/>
<outlet property="openClosedLabel" destination="096-jU-K7m" id="OC4-19-ja6"/>
<outlet property="timeDescriptionLabel" destination="DPA-Nu-eyP" id="0jY-sT-X2U"/>
</connections>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="qgd-YS-8BQ" id="gwp-kO-MKh"/>
<outlet property="delegate" destination="qgd-YS-8BQ" id="jR7-jd-u6u"/>
</connections>
</tableView>
<navigationItem key="navigationItem" title="What's Open" id="DJn-4Y-j3Y">
<barButtonItem key="leftBarButtonItem" systemItem="trash" id="74k-F0-Qql">
<color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</barButtonItem>
<barButtonItem key="rightBarButtonItem" systemItem="search" id="iVC-mL-qiS">
<color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<connections>
<action selector="SearchButton:" destination="qgd-YS-8BQ" id="k23-W5-zoR"/>
</connections>
</barButtonItem>
</navigationItem>
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="lightContent"/>
<connections>
<outlet property="mainNavigationBar" destination="DJn-4Y-j3Y" id="Mju-vB-oFP"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="d2o-5D-WNk" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-7182" y="-2740"/>
</scene>
<!--Filters--> <!--Filters-->
<scene sceneID="92M-hL-B3A"> <scene sceneID="92M-hL-B3A">
<objects> <objects>
...@@ -443,7 +354,7 @@ ...@@ -443,7 +354,7 @@
<constraint firstItem="WT6-Th-cbL" firstAttribute="leading" secondItem="cfK-H8-l8E" secondAttribute="leading" constant="16" id="PUT-sA-c7X"/> <constraint firstItem="WT6-Th-cbL" firstAttribute="leading" secondItem="cfK-H8-l8E" secondAttribute="leading" constant="16" id="PUT-sA-c7X"/>
<constraint firstItem="WT6-Th-cbL" firstAttribute="top" secondItem="VoZ-nV-Wve" secondAttribute="top" constant="174" id="Rax-Sc-nea"/> <constraint firstItem="WT6-Th-cbL" firstAttribute="top" secondItem="VoZ-nV-Wve" secondAttribute="top" constant="174" id="Rax-Sc-nea"/>
<constraint firstItem="cfK-H8-l8E" firstAttribute="trailing" secondItem="FR0-qX-jnd" secondAttribute="trailing" id="Sxh-yE-N5L"/> <constraint firstItem="cfK-H8-l8E" firstAttribute="trailing" secondItem="FR0-qX-jnd" secondAttribute="trailing" id="Sxh-yE-N5L"/>
<constraint firstItem="tzw-Ro-L8p" firstAttribute="top" secondItem="cfK-H8-l8E" secondAttribute="top" constant="8" symbolic="YES" id="ZGe-ml-5d1"/> <constraint firstItem="tzw-Ro-L8p" firstAttribute="top" secondItem="cfK-H8-l8E" secondAttribute="top" symbolic="YES" id="ZGe-ml-5d1"/>
<constraint firstItem="tzw-Ro-L8p" firstAttribute="centerX" secondItem="FR0-qX-jnd" secondAttribute="centerX" id="cs6-s4-1Tf"/> <constraint firstItem="tzw-Ro-L8p" firstAttribute="centerX" secondItem="FR0-qX-jnd" secondAttribute="centerX" id="cs6-s4-1Tf"/>
<constraint firstItem="WT6-Th-cbL" firstAttribute="centerX" secondItem="FR0-qX-jnd" secondAttribute="centerX" id="h6i-El-57t"/> <constraint firstItem="WT6-Th-cbL" firstAttribute="centerX" secondItem="FR0-qX-jnd" secondAttribute="centerX" id="h6i-El-57t"/>
<constraint firstItem="WT6-Th-cbL" firstAttribute="leading" secondItem="VoZ-nV-Wve" secondAttribute="leadingMargin" id="iNo-VZ-1qP"/> <constraint firstItem="WT6-Th-cbL" firstAttribute="leading" secondItem="VoZ-nV-Wve" secondAttribute="leadingMargin" id="iNo-VZ-1qP"/>
...@@ -589,7 +500,7 @@ ...@@ -589,7 +500,7 @@
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="yn4-Px-X4z" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="yn4-Px-X4z" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="-6372" y="-1886.8065967016494"/> <point key="canvasLocation" x="-7319" y="-1884"/>
</scene> </scene>
<!--Root Navigation--> <!--Root Navigation-->
<scene sceneID="WBs-Vx-0Yx"> <scene sceneID="WBs-Vx-0Yx">
...@@ -636,24 +547,6 @@ ...@@ -636,24 +547,6 @@
</objects> </objects>
<point key="canvasLocation" x="-7706" y="-1066"/> <point key="canvasLocation" x="-7706" y="-1066"/>
</scene> </scene>
<!--Navigation Controller-->
<scene sceneID="hwr-4e-Zz9">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="rWC-pl-Jtu" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="8y1-Ys-RiO">
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="qgd-YS-8BQ" kind="relationship" relationship="rootViewController" id="y95-NO-3Xg"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="2mB-A4-BEl" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-8119" y="-2740"/>
</scene>
<!--Filters Navigation--> <!--Filters Navigation-->
<scene sceneID="Qec-l3-QPJ"> <scene sceneID="Qec-l3-QPJ">
<objects> <objects>
......
...@@ -34,7 +34,6 @@ class SRCTNetworkController: NSObject { ...@@ -34,7 +34,6 @@ class SRCTNetworkController: NSObject {
let facility = Facility() let facility = Facility()
let map = Map(mappingType: .fromJSON, JSON: json, toObject: true, context: facility, shouldIncludeNilValues: true) let map = Map(mappingType: .fromJSON, JSON: json, toObject: true, context: facility, shouldIncludeNilValues: true)
facility.mapping(map: map) facility.mapping(map: map)
print(facility)
return facility return facility
}) })
// This is where completion is called // This is where completion is called
......
...@@ -13,6 +13,11 @@ import RealmSwift ...@@ -13,6 +13,11 @@ import RealmSwift
class FacilitiesListViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UIViewControllerPreviewingDelegate { class FacilitiesListViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UIViewControllerPreviewingDelegate {
var facilitiesArray = List<Facility>() var facilitiesArray = List<Facility>()
var filteredFacilities = List<Facility>()
// passing in nil sets the controller to be this controller
let searchController = UISearchController(searchResultsController: nil)
var filters = Filters() var filters = Filters()
override var preferredStatusBarStyle: UIStatusBarStyle { override var preferredStatusBarStyle: UIStatusBarStyle {
...@@ -85,11 +90,13 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate, ...@@ -85,11 +90,13 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate,
let tapLocation = sender.location(in: LocationsList) let tapLocation = sender.location(in: LocationsList)
let indexPath = LocationsList.indexPathForItem(at: tapLocation) let indexPath = LocationsList.indexPathForItem(at: tapLocation)
if((indexPath) != nil) { if((indexPath) != nil) {
let destination = storyboard?.instantiateViewController(withIdentifier: "detailView") as? FacilityDetailViewController let destination = self.storyboard?.instantiateViewController(withIdentifier: "detailView") as? FacilityDetailViewController
let tapped = LocationsList.cellForItem(at: indexPath!) as! FacilityCollectionViewCell let tapped = self.LocationsList.cellForItem(at: indexPath!) as! FacilityCollectionViewCell
destination!.facility = tapped.facility destination!.facility = tapped.facility
presentDetailView(destination!) self.presentDetailView(destination!)
} }
} }
...@@ -101,16 +108,40 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate, ...@@ -101,16 +108,40 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate,
let popoverController = destination.popoverPresentationController let popoverController = destination.popoverPresentationController
popoverController?.permittedArrowDirections = .any popoverController?.permittedArrowDirections = .any
popoverController?.sourceView = destination.view popoverController?.sourceView = destination.view
present(destination, animated: true, completion: nil) // present the detail view over the search controller if we're searching
if searchController.isActive {
searchController.present(destination, animated: true, completion: nil)
}
else {
present(destination, animated: true, completion: nil)
}
} }
else { else {
let destDelegate = DeckTransitioningDelegate() let destDelegate = DeckTransitioningDelegate()
destination.modalPresentationStyle = .custom destination.modalPresentationStyle = .custom
destination.transitioningDelegate = destDelegate destination.transitioningDelegate = destDelegate
present(destination, animated: true, completion: nil)
// present the detail view over the search controller if we're searching
if searchController.isActive {
searchController.present(destination, animated: true, completion: nil)
}
else {
present(destination, animated: true, completion: nil)
}
} }
} }
func configureSearchController() {
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
// add it to the navigationItem
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = true
}
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
...@@ -122,9 +153,7 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate, ...@@ -122,9 +153,7 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate,
navigationItem.title = "What's Open" navigationItem.title = "What's Open"
navigationController?.navigationBar.prefersLargeTitles = true navigationController?.navigationBar.prefersLargeTitles = true
let searchController = UISearchController(searchResultsController: nil) //TODO: ADD SEARCH configureSearchController()
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = true
LocationsListLayout.invalidateLayout() LocationsListLayout.invalidateLayout()
...@@ -147,6 +176,21 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate, ...@@ -147,6 +176,21 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate,
} }
} }
func isSearchBarEmpty() -> Bool {
return searchController.searchBar.text?.isEmpty ?? true
}
func isSearching() -> Bool {
return searchController.isActive && !isSearchBarEmpty()
}
func filterFacilitiesForSearchText(_ searchText: String) {
filteredFacilities = facilitiesArray.filter({(facility: Facility) -> Bool in
return facility.facilityName.lowercased().contains(searchText.lowercased())
})
LocationsList.reloadData()
}
@objc func refresh(_ sender: Any) { @objc func refresh(_ sender: Any) {
refreshControl.beginRefreshing() refreshControl.beginRefreshing()
...@@ -155,6 +199,7 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate, ...@@ -155,6 +199,7 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate,
LastUpdatedLabel.title = "Updated: " + shortDateFormat(date) LastUpdatedLabel.title = "Updated: " + shortDateFormat(date)
refreshControl.endRefreshing() refreshControl.endRefreshing()
} }
func shortDateFormat(_ date: Date) -> String { func shortDateFormat(_ date: Date) -> String {
let dateFormatter = DateFormatter() let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short dateFormatter.dateStyle = .short
...@@ -175,11 +220,9 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate, ...@@ -175,11 +220,9 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate,
} }
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.facilitiesArray.count return isSearching() ? self.filteredFacilities.count : self.facilitiesArray.count
} }
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as! FacilityCollectionViewCell let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as! FacilityCollectionViewCell
/* /*
...@@ -194,9 +237,19 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate, ...@@ -194,9 +237,19 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate,
cell.gestureRecognizers = [] cell.gestureRecognizers = []
cell.gestureRecognizers?.append(cell.tapRecognizer) cell.gestureRecognizers?.append(cell.tapRecognizer)
//get facility for cell
let dataArray = placeOpenFacilitiesFirstInArray(facilitiesArray) let facility: Facility
let facility = dataArray[indexPath.row] let dataArray: [Facility]
// if something has been searched for, we want to use the filtered array as the data source
if isSearching() {
dataArray = placeOpenFacilitiesFirstInArray(filteredFacilities)
} else {
dataArray = placeOpenFacilitiesFirstInArray(facilitiesArray)
}
facility = dataArray[indexPath.row]
cell.facility = facility cell.facility = facility
//set labels //set labels
...@@ -245,9 +298,9 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate, ...@@ -245,9 +298,9 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate,
} }
//Returns an array which has the open locations listed first // Returns an array which has the open locations listed first
//Could be improved in the future because currently this means you're checking // Could be improved in the future because currently this means you're checking
//open status twice per cell // open status twice per cell
func placeOpenFacilitiesFirstInArray(_ facilitiesArray: List<Facility>) -> [Facility] { func placeOpenFacilitiesFirstInArray(_ facilitiesArray: List<Facility>) -> [Facility] {
var open = [Facility]() var open = [Facility]()
var closed = [Facility]() var closed = [Facility]()
...@@ -284,24 +337,30 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate, ...@@ -284,24 +337,30 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate,
// MARK: - Navigation // MARK: - Navigation
//In a storyboard-based application, you will often want to do a little preparation before navigation //In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController. // // Get the new view controller using segue.destinationViewController.
if(segue.identifier == "toDetailView") { // if(segue.identifier == "toDetailView") {
let destination = segue.destination as! FacilityDetailViewController // let destination = segue.destination as! FacilityDetailViewController
let destDelegate = DeckTransitioningDelegate() // let destDelegate = DeckTransitioningDelegate()
destination.transitioningDelegate = destDelegate // destination.transitioningDelegate = destDelegate
let tapped = sender as! FacilityCollectionViewCell //this is probably a bad idea just FYI future me // let tapped = sender as! FacilityCollectionViewCell //this is probably a bad idea just FYI future me
destination.facility = tapped.facility // destination.facility = tapped.facility
present(destination, animated: true, completion: nil) //
} // // if we're in the search view, present on its controller
else if(segue.identifier == "toFilters") { // if searchController.isActive {
let destination = segue.destination as! UINavigationController // searchController.present(destination, animated: true, completion: nil)
let filterView = destination.topViewController as! FiltersTableViewController // } else {
filterView.filters = self.filters // present(destination, animated: true, completion: nil)
} // }
// }
// Pass the selected object to the new view controller. // else if(segue.identifier == "toFilters") {
} // let destination = segue.destination as! UINavigationController
// let filterView = destination.topViewController as! FiltersTableViewController
// filterView.filters = self.filters
// }
//
// // Pass the selected object to the new view controller.
// }
// MARK: - Peek and Pop // MARK: - Peek and Pop
...@@ -324,3 +383,12 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate, ...@@ -324,3 +383,12 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate,
} }
} }
// by implementing UISearchResultsUpdating, we can use this controller for the search controller
extension FacilitiesListViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
let searchText = searchController.searchBar.text ?? ""
filterFacilitiesForSearchText(searchText)
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment