Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Update Search UI #138

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
8 changes: 8 additions & 0 deletions Cineaste.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
3F4701C6238C8312006C1577 /* PagedMovieResultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F4701C5238C8312006C1577 /* PagedMovieResultTests.swift */; };
3F4701C8238C850A006C1577 /* PagedMovieResult+Testing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F4701C7238C850A006C1577 /* PagedMovieResult+Testing.swift */; };
3F4701C9238C8541006C1577 /* PagedMovieResult+Testing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F4701C7238C850A006C1577 /* PagedMovieResult+Testing.swift */; };
3F48A7DF257CE76B00956F2E /* SearchSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E903D95249E5DE600EAA4E6 /* SearchSection.swift */; };
3F492E6F24F250C900016B2A /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F492E6E24F250C900016B2A /* WidgetKit.framework */; };
3F492E7124F250C900016B2A /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F492E7024F250C900016B2A /* SwiftUI.framework */; };
3F492E7424F250C900016B2A /* CountdownWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F492E7324F250C900016B2A /* CountdownWidget.swift */; };
Expand Down Expand Up @@ -106,6 +107,7 @@
3F7ABD5620F5C71E004B069E /* String+Locale.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F941B6C20F527E5008A4407 /* String+Locale.swift */; };
3F7B66C62353B81600464BCC /* ContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F7B66C52353B81600464BCC /* ContextMenu.swift */; };
3F7D1D4F23D4A84900BA530F /* SearchMovieDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F7D1D4E23D4A84900BA530F /* SearchMovieDataSource.swift */; };
3F7D1D5123D4AEB400BA530F /* SearchTokenCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F7D1D5023D4AEB400BA530F /* SearchTokenCell.swift */; };
3F8065BC238AE3220087D6EA /* DateFormatter+Cineaste.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8065BB238AE3220087D6EA /* DateFormatter+Cineaste.swift */; };
3F80F27222359E5C007E03C5 /* UIView+SlideIn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F80F27122359E5C007E03C5 /* UIView+SlideIn.swift */; };
3F8CEBEE2250A229001916BD /* Screenshots+ScrollToElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8CEBED2250A229001916BD /* Screenshots+ScrollToElement.swift */; };
Expand Down Expand Up @@ -388,6 +390,7 @@
3F75665B2381737E007E2DE8 /* UIViewController+ShareMovie.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+ShareMovie.swift"; sourceTree = "<group>"; };
3F7B66C52353B81600464BCC /* ContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenu.swift; sourceTree = "<group>"; };
3F7D1D4E23D4A84900BA530F /* SearchMovieDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchMovieDataSource.swift; sourceTree = "<group>"; };
3F7D1D5023D4AEB400BA530F /* SearchTokenCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchTokenCell.swift; sourceTree = "<group>"; };
3F8065BB238AE3220087D6EA /* DateFormatter+Cineaste.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+Cineaste.swift"; sourceTree = "<group>"; };
3F80F27122359E5C007E03C5 /* UIView+SlideIn.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+SlideIn.swift"; sourceTree = "<group>"; };
3F83BE771FF39DFC00E584E9 /* Instantiable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Instantiable.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -458,6 +461,7 @@
3FFEC6CC236DCF91005E7EED /* Storyboard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Storyboard.swift; sourceTree = "<group>"; };
4E20FD24226851D3006EB4B8 /* PersistenceSubscriber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistenceSubscriber.swift; sourceTree = "<group>"; };
4E779FC022690151007B278D /* SelectionReducerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectionReducerTests.swift; sourceTree = "<group>"; };
4E903D95249E5DE600EAA4E6 /* SearchSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchSection.swift; sourceTree = "<group>"; };
4EABD57D2129C622007F20D9 /* SeparatorViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorViewTests.swift; sourceTree = "<group>"; };
4EB512012268B07600CBDC7E /* AppReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppReducer.swift; sourceTree = "<group>"; };
4EB512032268B1FD00CBDC7E /* SelectionReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectionReducer.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -863,6 +867,8 @@
3FEEE8E6222BBC6A00EB1649 /* SearchMoviesViewController+SwipeAction.swift */,
6409298F22DBAB0C0011AB96 /* SearchMoviesViewController+SwipeHint.swift */,
3FD722CB20264B720046DEAC /* SearchMoviesViewController+UITableView.swift */,
3F7D1D5023D4AEB400BA530F /* SearchTokenCell.swift */,
4E903D95249E5DE600EAA4E6 /* SearchSection.swift */,
);
path = SearchMovies;
sourceTree = "<group>";
Expand Down Expand Up @@ -1489,6 +1495,7 @@
1A31111D2518003000F05C16 /* AppGroup+Kingfisher.swift in Sources */,
3F187F952263491500B7A9CF /* SortDescriptor.swift in Sources */,
3F36F5D2238A8CCE00267280 /* UserDefaults+Cineaste.swift in Sources */,
3F48A7DF257CE76B00956F2E /* SearchSection.swift in Sources */,
3FF790F620DE274A007B7D37 /* NavigationController.swift in Sources */,
3FF790F720DE274A007B7D37 /* Button.swift in Sources */,
3F229212225A40BC001D4358 /* Store.swift in Sources */,
Expand Down Expand Up @@ -1518,6 +1525,7 @@
3FF095D5210325D100ADFB86 /* SettingsViewController+UIDocumentPicker.swift in Sources */,
3FF7910220DE274A007B7D37 /* SettingsCell.swift in Sources */,
3FF7910420DE274A007B7D37 /* SettingsDetailViewController.swift in Sources */,
3F7D1D5123D4AEB400BA530F /* SearchTokenCell.swift in Sources */,
4ED2FC7D22666D89007BDE06 /* CoreDataMigrator.swift in Sources */,
3F0C1D1322A4395E00F0F52A /* ShortcutIdentifier.swift in Sources */,
3FF7910620DE274A007B7D37 /* Model.xcdatamodeld in Sources */,
Expand Down
37 changes: 36 additions & 1 deletion Cineaste/Storyboards/Base.lproj/Search.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,41 @@
<outlet property="title" destination="AYE-99-Bh1" id="Z9y-W7-ZXm"/>
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="SearchTokenCell" id="siu-ys-alf" customClass="SearchTokenCell" customModule="Cineaste_App" customModuleProvider="target">
<rect key="frame" x="0.0" y="128" width="414" height="145"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="siu-ys-alf" id="SM0-PY-tUJ">
<rect key="frame" x="0.0" y="0.0" width="414" height="145"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BRJ-zl-ued">
<rect key="frame" x="102" y="20" width="292" height="105"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="xqS-rw-5fJ">
<rect key="frame" x="32" y="52.5" width="40" height="40"/>
<constraints>
<constraint firstAttribute="width" constant="40" id="Gye-5T-gTc"/>
<constraint firstAttribute="width" secondItem="xqS-rw-5fJ" secondAttribute="height" id="wWh-lB-khI"/>
</constraints>
</imageView>
</subviews>
<constraints>
<constraint firstItem="BRJ-zl-ued" firstAttribute="top" secondItem="SM0-PY-tUJ" secondAttribute="top" constant="20" symbolic="YES" id="Cgh-Fz-T5l"/>
<constraint firstAttribute="trailing" secondItem="BRJ-zl-ued" secondAttribute="trailing" constant="20" symbolic="YES" id="HC2-ZJ-aiy"/>
<constraint firstItem="xqS-rw-5fJ" firstAttribute="leading" secondItem="SM0-PY-tUJ" secondAttribute="leading" constant="32" id="IKJ-BR-zej"/>
<constraint firstItem="xqS-rw-5fJ" firstAttribute="centerY" secondItem="SM0-PY-tUJ" secondAttribute="centerY" id="UGL-GQ-kwI"/>
<constraint firstAttribute="bottom" secondItem="BRJ-zl-ued" secondAttribute="bottom" constant="20" symbolic="YES" id="WvH-FX-eTI"/>
<constraint firstItem="BRJ-zl-ued" firstAttribute="leading" secondItem="xqS-rw-5fJ" secondAttribute="trailing" constant="30" id="ltz-nj-Ids"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="title" destination="BRJ-zl-ued" id="lKx-Fb-qbA"/>
<outlet property="tokenIcon" destination="xqS-rw-5fJ" id="qMR-nM-bvj"/>
</connections>
</tableViewCell>
</prototypes>
</tableView>
</subviews>
Expand Down Expand Up @@ -171,7 +206,7 @@
</constraints>
</view>
</objects>
<point key="canvasLocation" x="4876" y="5.8470764617691158"/>
<point key="canvasLocation" x="4875.36231884058" y="5.3571428571428568"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="nqO-6w-fBm">
Expand Down
62 changes: 57 additions & 5 deletions Cineaste/ViewController/SearchMovies/SearchMovieDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,70 @@
import UIKit

class SearchMovieDataSource: NSObject, UITableViewDataSource {
enum Mode {
case discover
@available (iOS 13, *)
case manualSearch
}

var mode: Mode = .discover
var movies: [Movie] = []

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
guard #available(iOS 13, *),
mode == .manualSearch
else { return nil }

switch SearchSection(rawValue: section) {
case .tokens?:
return "Genres"
case .movies?:
return "Movies"
default:
return nil
}
}

func numberOfSections(in tableView: UITableView) -> Int {
switch mode {
case .discover:
return 1
case .manualSearch:
return 2
}
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
movies.count
switch (mode, SearchSection(rawValue: section)) {
case (.discover, _),
(.manualSearch, .movies?):
return movies.count
case (.manualSearch, .tokens?):
return 1
default:
return 0
}
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: SearchMoviesCell = tableView.dequeueCell(identifier: SearchMoviesCell.identifier)

let movie = movies[indexPath.row]
cell.configure(with: movie)
switch (mode, SearchSection(rawValue: indexPath.section)) {
case (.discover, _),
(.manualSearch, .movies?):
let cell: SearchMoviesCell = tableView.dequeueCell(identifier: SearchMoviesCell.identifier)

let movie = movies[indexPath.row]

cell.configure(with: movie)

return cell
case (.manualSearch, .tokens?):
let cell: SearchTokenCell = tableView.dequeueCell(identifier: SearchTokenCell.identifier)
cell.configure()
return cell
default:
fatalError("The impossible has happened")
}

return cell
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,22 @@ extension SearchMoviesViewController: UISearchControllerDelegate {
}
}

extension SearchMoviesViewController: UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
if #available(iOS 13, *) {
dataSource.mode = .manualSearch
} else {
dataSource.mode = .discover
}
tableView.reloadData()
}

func textFieldDidEndEditing(_ textField: UITextField) {
dataSource.mode = .discover
tableView.reloadData()
}
}

extension SearchMoviesViewController: UISearchResultsUpdating {
internal func updateSearchResults(for searchController: UISearchController) {
searchDelayTimer?.invalidate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,25 @@ extension SearchMoviesViewController: UITableViewDataSourcePrefetching {

extension SearchMoviesViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedMovie = movies[indexPath.row]
store.dispatch(SelectionAction.select(movie: selectedMovie))
perform(segue: .showMovieDetail, sender: self)

switch (dataSource.mode, SearchSection(rawValue: indexPath.section)) {
case (.discover, _),
(.manualSearch, .movies?):
let selectedMovie = movies[indexPath.row]
store.dispatch(SelectionAction.select(movie: selectedMovie))
perform(segue: .showMovieDetail, sender: self)
case (.manualSearch, .tokens?):
guard #available(iOS 13.0, *),
let cell = tableView.cellForRow(at: indexPath) as? SearchTokenCell,
let genre = cell.title.text
else { return }

let searchField = resultSearchController.searchBar.searchTextField
let searchToken = UISearchToken(icon: UIImage.moreIcon, text: genre)
searchField.insertToken(searchToken, at: 0)
searchField.tokenBackgroundColor = .cineButton
default:
break
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ class SearchMoviesViewController: UIViewController {
navigationItem.hidesSearchBarWhenScrolling = false

definesPresentationContext = true

if #available(iOS 13.0, *) {
resultSearchController.searchBar.searchTextField.delegate = self
}
}
}

Expand Down
12 changes: 12 additions & 0 deletions Cineaste/ViewController/SearchMovies/SearchSection.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// SearchSection.swift
// Cineaste App
//
// Created by Felizia Bernutz on 19.01.20.
// Copyright © 2020 spacepandas.de. All rights reserved.
//

enum SearchSection: Int {
case tokens = 0
case movies = 1
}
22 changes: 22 additions & 0 deletions Cineaste/ViewController/SearchMovies/SearchTokenCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// SearchTokenCell.swift
// Cineaste App
//
// Created by Felizia Bernutz on 19.01.20.
// Copyright © 2020 spacepandas.de. All rights reserved.
//

import UIKit

class SearchTokenCell: UITableViewCell {
static let identifier = "SearchTokenCell"

@IBOutlet weak var tokenIcon: UIImageView!
@IBOutlet weak var title: UILabel!

func configure() {
tokenIcon.image = UIImage.searchIcon
title.text = "Horror"
}

}