版本記錄
版本號 | 時(shí)間 |
---|---|
V1.0 | 2020.05.05 星期二 |
前言
iOS中有關(guān)視圖控件用戶能看到的都在UIKit框架里面演训,用戶交互也是通過UIKit進(jìn)行的。感興趣的參考上面幾篇文章拂募。
1. UIKit框架(一) —— UIKit動(dòng)力學(xué)和移動(dòng)效果(一)
2. UIKit框架(二) —— UIKit動(dòng)力學(xué)和移動(dòng)效果(二)
3. UIKit框架(三) —— UICollectionViewCell的擴(kuò)張效果的實(shí)現(xiàn)(一)
4. UIKit框架(四) —— UICollectionViewCell的擴(kuò)張效果的實(shí)現(xiàn)(二)
5. UIKit框架(五) —— 自定義控件:可重復(fù)使用的滑塊(一)
6. UIKit框架(六) —— 自定義控件:可重復(fù)使用的滑塊(二)
7. UIKit框架(七) —— 動(dòng)態(tài)尺寸UITableViewCell的實(shí)現(xiàn)(一)
8. UIKit框架(八) —— 動(dòng)態(tài)尺寸UITableViewCell的實(shí)現(xiàn)(二)
9. UIKit框架(九) —— UICollectionView的數(shù)據(jù)異步預(yù)加載(一)
10. UIKit框架(十) —— UICollectionView的數(shù)據(jù)異步預(yù)加載(二)
11. UIKit框架(十一) —— UICollectionView的重用陈症、選擇和重排序(一)
12. UIKit框架(十二) —— UICollectionView的重用录肯、選擇和重排序(二)
13. UIKit框架(十三) —— 如何創(chuàng)建自己的側(cè)滑式面板導(dǎo)航(一)
14. UIKit框架(十四) —— 如何創(chuàng)建自己的側(cè)滑式面板導(dǎo)航(二)
15. UIKit框架(十五) —— 基于自定義UICollectionViewLayout布局的簡單示例(一)
16. UIKit框架(十六) —— 基于自定義UICollectionViewLayout布局的簡單示例(二)
17. UIKit框架(十七) —— 基于自定義UICollectionViewLayout布局的簡單示例(三)
18. UIKit框架(十八) —— 基于CALayer屬性的一種3D邊欄動(dòng)畫的實(shí)現(xiàn)(一)
19. UIKit框架(十九) —— 基于CALayer屬性的一種3D邊欄動(dòng)畫的實(shí)現(xiàn)(二)
20. UIKit框架(二十) —— 基于UILabel跑馬燈類似效果的實(shí)現(xiàn)(一)
21. UIKit框架(二十一) —— UIStackView的使用(一)
22. UIKit框架(二十二) —— 基于UIPresentationController的自定義viewController的轉(zhuǎn)場和展示(一)
23. UIKit框架(二十三) —— 基于UIPresentationController的自定義viewController的轉(zhuǎn)場和展示(二)
24. UIKit框架(二十四) —— 基于UICollectionViews和Drag-Drop在兩個(gè)APP間的使用示例 (一)
25. UIKit框架(二十五) —— 基于UICollectionViews和Drag-Drop在兩個(gè)APP間的使用示例 (二)
26. UIKit框架(二十六) —— UICollectionView的自定義布局 (一)
27. UIKit框架(二十七) —— UICollectionView的自定義布局 (二)
28. UIKit框架(二十八) —— 一個(gè)UISplitViewController的簡單實(shí)用示例 (一)
29. UIKit框架(二十九) —— 一個(gè)UISplitViewController的簡單實(shí)用示例 (二)
30. UIKit框架(三十) —— 基于UICollectionViewCompositionalLayout API的UICollectionViews布局的簡單示例(一)
31. UIKit框架(三十一) —— 基于UICollectionViewCompositionalLayout API的UICollectionViews布局的簡單示例(二)
32. UIKit框架(三十二) —— 替換Peek and Pop交互的基于iOS13的Context Menus(一)
33. UIKit框架(三十三) —— 替換Peek and Pop交互的基于iOS13的Context Menus(二)
34. UIKit框架(三十四) —— Accessibility的使用(一)
35. UIKit框架(三十五) —— Accessibility的使用(二)
36. UIKit框架(三十六) —— UICollectionView UICollectionViewDiffableDataSource的使用(一)
37. UIKit框架(三十七) —— UICollectionView UICollectionViewDiffableDataSource的使用(二)
38. UIKit框架(三十八) —— 基于CollectionView轉(zhuǎn)盤效果的實(shí)現(xiàn)(一)
開始
首先看下主要內(nèi)容:
在本
UISearchController
教程中,您將了解UISearchToken
试伙、UISearchTextField
和iOS 13
中引入的其他新api
嘁信。來自翻譯于样。
下面看下寫作環(huán)境
Swift 5, iOS 13, Xcode 11
接著就是正文了疏叨。
UISearchBar
和UISearchController
是iOS應(yīng)用開發(fā)的主要部分。不過穿剖,雖然UISearchBar
自iOS 2
引入以來一直在周期性地變化蚤蔓,但自從蘋果在iOS 8
中引入它以來,UISearchController
就一直是相當(dāng)穩(wěn)定的糊余。在iOS 13
中,蘋果對兩者都進(jìn)行了更新宣决。
蘋果還推出了UISearchToken
尊沸,為UISearchController
提供了急需的能力洼专。只需很少的努力,您就可以讓用戶執(zhí)行復(fù)雜的搜索查詢蜡镶,以及他們習(xí)慣的基于文本的搜索帽哑。
如果您曾經(jīng)編寫過冗長妻枕、脆弱的代碼來遍歷搜索欄的視圖層次結(jié)構(gòu)以獲得對搜索text field
的引用屡谐,那么這里有更多的好消息愕掏。UISearchTextField
現(xiàn)在作為一個(gè)屬性公開,這使得定制更加容易滑潘。
在本教程中,您將學(xué)習(xí):
- 如何控制搜索結(jié)果控制器的顯示钮孵。
- 關(guān)于搜索令牌
(search tokens)
的所有信息诅需。 - 如何創(chuàng)建和使用搜索令牌蔫仙。
- 如何自定義
UISearchController
,search bar
和它的text field
丑慎。
在本教程中腻异,您將在L.I.S.T.E.D
中進(jìn)行學(xué)習(xí),它是Large International Sorted Tally of Earth Dwellers
。L.I.S.T.E.D.
是一個(gè)跟蹤世界人口總數(shù)的組織罐旗。他們目前有2018年和2019年所有國家的人口。
預(yù)計(jì)到2020年人口數(shù)據(jù)的發(fā)布,他們希望擴(kuò)大搜索能力娇豫。作為一個(gè)地球居民,你將幫助重構(gòu)應(yīng)用程序,并將其搜索功能提升到一個(gè)全新的組織層面。
首先在starter文件夾中打開列表LISTED.xcodeproj
中夹供,然后打開Main.storyboard
。
你會(huì)發(fā)現(xiàn)這個(gè)應(yīng)用程序非常簡單。只有兩個(gè)視圖控制器,它們被封裝在一個(gè)導(dǎo)航控制器中蒿秦。
構(gòu)建和運(yùn)行。你會(huì)看到:
現(xiàn)在祟辟,搜索“new”
。你會(huì)看到這些搜索結(jié)果:
結(jié)果顯示所有年份的匹配馍悟。在范圍欄中點(diǎn)擊2018或2019將縮小搜索范圍∫阏現(xiàn)在就試試2019年戏蔑,你會(huì)看到:
很好捍壤,基本的搜索工作得很好。現(xiàn)在寡夹,你需要進(jìn)一步優(yōu)化!
Using the Search Results Controller
UISearchController
為顯示結(jié)果提供了兩個(gè)選項(xiàng):在顯示原始數(shù)據(jù)的相同視圖中顯示結(jié)果,或者使用搜索結(jié)果控制器法牲。
L.I.S.T.E.D.
使用搜索結(jié)果控制器(search results controller)
以與主控制器稍微不同的格式顯示結(jié)果。當(dāng)用戶點(diǎn)擊搜索欄時(shí),主視圖控制器仍然可見。結(jié)果視圖控制器在用戶開始輸入搜索后顯示。
在iOS 13
之前,你幾乎無法控制這種行為零蓉,但現(xiàn)在你可以在UISearchController
中使用新添加的showsSearchResultsController
來定制你的結(jié)果章喉。在下一節(jié)中您將看到如何實(shí)現(xiàn)部蛇。
1. Displaying Results: You’re in Control
要控制何時(shí)顯示搜索結(jié)果抹腿,您需要對搜索欄中的更改做出反應(yīng)房蝉。為了讓它工作檀蹋,主視圖控制器將遵循UISearchResultsUpdating
。
當(dāng)搜索欄成為第一個(gè)響應(yīng)器或文本發(fā)生更改時(shí),委托接收updateSearchResults(for:)
調(diào)用。您將使用它來觸發(fā)結(jié)果控制器的顯示。
打開MainViewController.swift
,并在UISearchBarDelegate
之后添加以下內(nèi)容:
// MARK: -
extension MainViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
searchController.showsSearchResultsController = true
}
}
搜索欄成為第一個(gè)響應(yīng)者時(shí),搜索結(jié)果現(xiàn)在顯示岂却。
在進(jìn)行測試之前,添加以下代碼作為viewDidLoad()
中的最后一行:
searchController.searchResultsUpdater = self
search results updater
負(fù)責(zé)更新搜索結(jié)果控制器(search results controller)
正驻。這里,您將該職責(zé)分配給主控制器。
構(gòu)建和運(yùn)行。點(diǎn)擊搜索欄,你會(huì)看到一個(gè)空的搜索結(jié)果控制器打肝。
你現(xiàn)在可以完全控制搜索結(jié)果的顯示和隱藏。正如您現(xiàn)在所感受到的那樣強(qiáng)大鉴嗤,顯示一個(gè)空白的結(jié)果控制器并不是一個(gè)很好的用戶體驗(yàn)。您將很快解決這個(gè)問題经柴,但是首先牛哺,您需要了解關(guān)于搜索令牌(search tokens)
的更多信息椰拒。
Everything You Need to Know About Search Tokens
搜索令牌(Search token)
可以說是蘋果在ios13
中添加的最有趣的搜索功能便瑟。如果你在iOS 13上使用蘋果的Mail or Photo
應(yīng)用程序浇雹,你可能已經(jīng)看到了搜索令牌的作用。
Mail
應(yīng)用程序使用搜索令牌來創(chuàng)建復(fù)雜的搜索。點(diǎn)擊搜索欄會(huì)顯示unread messages
和flagged messages
等建議。
Tokens
可以表示復(fù)雜的搜索敌完,比如通過地理位置進(jìn)行搜索,或者使用預(yù)先確定的文本進(jìn)行簡單的搜索得哆。搜索令牌的鍵在UISearchToken
中是representedObject
。
representedObject
是一個(gè)Any?
可以包含對您有用的任何類型的數(shù)據(jù)。
一定要記住壹无,representedObject
是強(qiáng)引用的岖是。它所引用的任何對象都可能在周圍停留相當(dāng)長的一段時(shí)間前硫。使用輕量級數(shù)據(jù)來避免問題。String、int
和NSManagedObjectID
都是不錯(cuò)的選擇偷线。
1. Creating Tokens
現(xiàn)在是處理單擊搜索欄時(shí)看到的空搜索結(jié)果視圖的時(shí)候了亥曹。這是顯示用戶可用令牌列表的好地方。
打開ResultsTableViewController.swift
熊响。在類的頂部铭若,countries
之后嫂侍,添加以下內(nèi)容:
var searchTokens: [UISearchToken] = []
這里各淀,您正在創(chuàng)建一個(gè)數(shù)組來保存搜索標(biāo)記南捂。在這一行之后,添加以下內(nèi)容:
var isFilteringByCountry: Bool {
return countries != nil
}
當(dāng)用戶進(jìn)行搜索時(shí)吱晒,這個(gè)計(jì)算得到的布爾值將返回true
驼壶;當(dāng)用戶不進(jìn)行搜索時(shí)纪铺,將返回false
烹棉。你很快就會(huì)用到它。
在文件末尾的類下面摘昌,添加以下擴(kuò)展名:
// MARK: -
extension ResultsTableViewController {
func makeTokens() {
// 1
let continents = Continent.allCases
searchTokens = continents.map { (continent) -> UISearchToken in
// 2
let globeImage = UIImage(systemName: "globe")
let token = UISearchToken(icon: globeImage, text: continent.description)
// 3
token.representedObject = Continent(rawValue: continent.description)
// 4
return token
}
}
}
這些代碼的內(nèi)容如下:
- 1) 創(chuàng)建一個(gè)所有
continents
的數(shù)組喉镰。 - 2) 創(chuàng)建表示
token
的圖像。接下來柱蟀,使用圖像和當(dāng)前continents
的描述,創(chuàng)建一個(gè)search token
痰哨。 - 3) 將
continents
的描述賦給token
的representedObject
。稍后您將使用它來將搜索范圍縮小到特定的continents
撬讽。使用輕量級值(如字符串)非常適合這種情況。 - 4) 返回
token
尝蠕,它附加到您先前創(chuàng)建的searchTokens
烘豌。
在viewDidLoad()
中廊佩,添加這一行作為最后一行:
makeTokens()
在這里,您將在視圖加載時(shí)創(chuàng)建search token
。就是這樣!創(chuàng)建search token
就是這么簡單。
在重新構(gòu)建和運(yùn)行之前扇住,您需要更新結(jié)果控制器來顯示這些新token
。你將在下一步中做庸汗。
2. Making a UI for Selecting Tokens
現(xiàn)在,您將創(chuàng)建一個(gè)UI
立宜,以使用Mail
應(yīng)用程序作為靈感來選擇token
。首先鸦采,將tableView(_:numberOfRowsInSection:)
替換為:
override func tableView(
_ tableView: UITableView,
numberOfRowsInSection section: Int
) -> Int {
return isFilteringByCountry ? (countries?.count ?? 0) : searchTokens.count
}
使用前面創(chuàng)建的isFilteringByCountry
,您可以確定是使用search tokens
計(jì)數(shù)還是使用countries
計(jì)數(shù)來設(shè)置表視圖中的行數(shù)。如果用戶正在搜索膛檀,則發(fā)送國家計(jì)數(shù)(如果countries
為nil
,則發(fā)送零)挺尾。當(dāng)它們不進(jìn)行搜索時(shí)赦抖,您發(fā)送token count
蚕键。
接下來兽赁,用以下代碼替換tableView(_:cellForRowAt:)
:
override func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath
) -> UITableViewCell {
// 1
if
isFilteringByCountry,
let cell = tableView.dequeueReusableCell(
withIdentifier: "results",
for: indexPath) as? CountryCell {
cell.country = countries?[indexPath.row]
return cell
// 2
} else if
let cell = tableView.dequeueReusableCell(
withIdentifier: "search",
for: indexPath) as? SearchTokenCell {
cell.token = searchTokens[indexPath.row]
return cell
}
// 3
return UITableViewCell()
}
你可以這樣處理這些代碼:
- 1) 首先檢查用戶是否正在搜索某個(gè)國家。如果是枕赵,則使用
CountryCell
其掂。然后將國家分配給單元格的國家并返回單元格叹谁。 - 2) 否則,使用
SearchTokenCell
。將token
分配給cell
的token
并返回cell
夭拌。 - 3) 如果所有操作都失敗,則返回一個(gè)
UITableViewCell
噩凹。
構(gòu)建和運(yùn)行。點(diǎn)擊搜索欄,但不要輸入任何文本。您將看到為選擇search token
而創(chuàng)建的UI
优构。
這是一個(gè)非常棒的方法,但是有一個(gè)問題:如果您點(diǎn)擊其中一個(gè)token
劳澄,什么也不會(huì)發(fā)生。噓蔚万!別擔(dān)心,你下次會(huì)修好的肖方。
3. Adding Tokens to the Search Bar
當(dāng)您在結(jié)果視圖中點(diǎn)擊一個(gè)token entries
時(shí)司草,什么也不會(huì)發(fā)生柬讨。應(yīng)該發(fā)生的是將token
添加到搜索欄中境输。這向用戶表明他們正在搜索他們指定的大陸。
results controller
不能添加token
姑丑,因?yàn)樗皇撬阉鳈诘乃姓哒ぐА.?dāng)用戶點(diǎn)擊一個(gè)token
時(shí)戳晌,你必須通知主視圖控制器泼菌。為此嘉蕾,您將使用委托協(xié)議以清。
在類之前障贸,將以下代碼添加到ResultsTableViewController.swift
的頂部:
protocol ResultsTableViewDelegate: class {
func didSelect(token: UISearchToken)
}
在類的頂部戳杀,在isFilteringByCountry
之后咐低,添加以下內(nèi)容:
weak var delegate: ResultsTableViewDelegate?
您已經(jīng)創(chuàng)建了一個(gè)簡單的協(xié)議揽思,當(dāng)用戶點(diǎn)擊一個(gè)token
時(shí),您將使用它來通知委托≡ㄐ現(xiàn)在绰更,在tableView(_:cellForRowAt:)
之后添加以下代碼:
override func tableView(
_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath
) {
guard !isFilteringByCountry else { return }
delegate?.didSelect(token: searchTokens[indexPath.row])
}
首先,檢查視圖是否顯示tokens or countries
锡宋。如果是一個(gè)國家儡湾,則忽略行選擇。否則执俩,您將通知委托用戶所點(diǎn)擊的search token
徐钠。
在MainViewController.swift
,在文件底部添加如下內(nèi)容:
// MARK: -
extension MainViewController: ResultsTableViewDelegate {
func didSelect(token: UISearchToken) {
// 1
let searchTextField = searchController.searchBar.searchTextField
// 2
searchTextField.insertToken(token, at: searchTextField.tokens.count)
// 3
searchFor(searchController.searchBar.text)
}
}
當(dāng)通知主視圖控制器時(shí)役首,用戶已經(jīng)選擇了一個(gè)token
尝丐,你:
- 1) 獲取搜索欄的
text field
。 - 2) 使用
field
的insertToken(_:at:)
將token
添加到已經(jīng)在field
中的tokens
的末尾衡奥。 - 3) 運(yùn)行搜索算法爹袁。
在viewDidLoad()
中,在resultsTableViewController
實(shí)例化之后矮固,添加:
resultsTableViewController.delegate = self
現(xiàn)在失息,主視圖控制器將是結(jié)果控制器的代理。
構(gòu)建并運(yùn)行档址,然后點(diǎn)擊搜索欄盹兢。當(dāng)結(jié)果控制器出現(xiàn)時(shí),點(diǎn)擊“Search by Europe”
守伸。然后绎秒,輸入“united”
,你會(huì)看到:
令人興奮尼摹!您已經(jīng)向搜索欄添加了一個(gè)search token
见芹。然而,它似乎不起作用蠢涝。
除非地理環(huán)境從你上高中起就發(fā)生了變化玄呛,否則美國和阿拉伯聯(lián)合酋長國不會(huì)出現(xiàn)在歐洲。
問題出在搜索算法上:您沒有更新它以使其考慮到tokens
惠赫。解決這個(gè)問題是你的下一個(gè)挑戰(zhàn)。
Modifying Your Search to Use Tokens
當(dāng)前的搜索算法使用搜索欄的文本和范圍來執(zhí)行搜索故黑。您還將重構(gòu)它以使用tokens
儿咱。
在此之前庭砍,您需要?jiǎng)?chuàng)建兩個(gè)helper
屬性。在MainViewController.swift
中混埠,在resultsTableViewController
之后添加以下內(nèi)容:
var searchContinents: [String] {
// 1
let tokens = searchController.searchBar.searchTextField.tokens
// 2
return tokens.compactMap {
($0.representedObject as? Continent)?.description
}
}
該計(jì)算屬性將:
- 1) 創(chuàng)建在搜索欄的
text field
中包含的tokens
數(shù)組怠缸。 - 2) 使用每個(gè)
token
的representedObject
返回大陸字符串?dāng)?shù)組。
在searchContinents
之后钳宪,添加代碼:
var isSearchingByTokens: Bool {
return
searchController.isActive &&
searchController.searchBar.searchTextField.tokens.count > 0
}
如果搜索控制器處于活動(dòng)狀態(tài)揭北,并且搜索欄包含搜索token
,則此屬性返回true
吏颖。
使用這些新屬性搔体,將searchFor(_:)
替換為:
func searchFor(_ searchText: String?) {
// 1
guard searchController.isActive else { return }
// 2
guard let searchText = searchText else {
resultsTableViewController.countries = nil
return
}
// 3
let selectedYear = selectedScopeYear()
let allCountries = countries.values.joined()
let filteredCountries = allCountries.filter { (country: Country) -> Bool in
// 4
let isMatchingYear = selectedYear == Year.all.description ?
true : (country.year.description == selectedYear)
// 5
let isMatchingTokens = searchContinents.count == 0 ?
true : searchContinents.contains(country.continent.description)
// 6
if !searchText.isEmpty {
return
isMatchingYear &&
isMatchingTokens &&
country.name.lowercased().contains(searchText.lowercased())
// 7
} else if isSearchingByTokens {
return isMatchingYear && isMatchingTokens
}
// 8
return false
}
// 9
resultsTableViewController.countries =
filteredCountries.count > 0 ? filteredCountries : nil
}
新的搜索算法做以下工作:
- 1) 如果搜索控制器
(search controller)
當(dāng)前不是活動(dòng)的,它將終止半醉。 - 2) 如果搜索文本為
nil
疚俱,則將結(jié)果控制器的countries
設(shè)置為nil
并終止。 - 3) 從范圍欄中獲取選定的年份缩多。接下來呆奕,創(chuàng)建一個(gè)所有國家的數(shù)組并開始過濾該數(shù)組。
- 4) 國家每年出現(xiàn)一次衬吆。根據(jù)2018年和2019年的數(shù)據(jù)梁钾,每個(gè)國家都被列出了兩次。過濾時(shí)的第一步是創(chuàng)建一個(gè)布爾值逊抡,如果選擇的年份是
“all”
姆泻,則為true
。如果不是秦忿,則返回一個(gè)布爾值麦射,該布爾值基于該國的年份是否等于所選年份。 - 5) 使用之前創(chuàng)建的
searchContinents
灯谣,如果國家的大陸匹配任何選定的tokens
潜秋,就創(chuàng)建一個(gè)布爾值。如果searchContinents
為nil
胎许,則返回true
峻呛,因?yàn)?code>nil表示匹配所有大陸。 - 6) 如果有任何搜索文本辜窑,如果年份匹配钩述,令牌匹配,并且國家名稱包含搜索文本中的任何字符穆碎,那么您將返回國家牙勘。
- 7) 如果您有
token
但沒有文本,則返回與年份和token
所在大陸匹配的國家。 - 8) 當(dāng)這兩種情況都不為
true
時(shí)方面,您將返回false
放钦。 - 9) 將任何經(jīng)過篩選的國家分配給結(jié)果控制器的
countries
。如果沒有恭金,賦值為nil
操禀。
構(gòu)建和運(yùn)行。點(diǎn)擊搜索欄横腿,像上次一樣颓屑,點(diǎn)擊Search by Europe
,然后輸入united
耿焊。你只會(huì)看到英國2018年和2019年的entries
揪惦。
雖然這很神奇,但現(xiàn)在還不要慶祝搀别。確保您所做的更改沒有影響到在沒有tokens
的情況下進(jìn)行搜索的能力丹擎。
在搜索text field
中選擇Europe token
并刪除它,但不刪除單詞“united”
歇父。你會(huì)看到:
哇蒂培!你做了一些偉大的工作。只有一些小的改變榜苫,你已經(jīng)徹底改變了L.I.S.T.E.D.
的搜索功能护戳。
Hiding the Scope Bar
在您可以將其稱為準(zhǔn)備好投入生產(chǎn)之前,您還有一些事情要做垂睬。L.I.S.T.E.D.設(shè)計(jì)團(tuán)隊(duì)已經(jīng)確定媳荒,當(dāng)結(jié)果控制器顯示token selection UI
時(shí),scope bar
不應(yīng)該是可見的驹饺。
要實(shí)現(xiàn)這一點(diǎn)钳枕,請轉(zhuǎn)到viewDidLoad()
并將其添加為最后一行:
searchController.automaticallyShowsScopeBar = false
在ios13
之前,scope bar
總是會(huì)自動(dòng)顯示∩鸵迹現(xiàn)在鱼炒,您可以通過使用新的1automaticallyShowsScopeBar1來控制這種行為。
注意:有一個(gè)類似的
automaticallyShowsCancelButton
蝌借。此屬性允許您控制搜索欄的“取消”按鈕的可見性昔瞧。雖然在這個(gè)項(xiàng)目中不需要它,但是應(yīng)該知道它的存在菩佑。
接下來自晰,找到selectedScopeYear()
并在其后面添加以下內(nèi)容:
func showScopeBar(_ show: Bool) {
guard searchController.searchBar.showsScopeBar != show else { return }
searchController.searchBar.setShowsScope(show, animated: true)
view.setNeedsLayout()
}
在這里,檢查搜索欄的showsScopeBar
是否匹配show
稍坯。如果是這樣酬荞,你就會(huì)停下來,因?yàn)槟銦o事可做。
如果不匹配混巧,則使用新的setShowsScope(_:animated:)
來顯示或隱藏scope bar
糟把。
最后,必須在視圖控制器的視圖上調(diào)用setNeedsLayout()
牲剃。
現(xiàn)在,您將使用這個(gè)新函數(shù)來顯示和隱藏scope bar
雄可。在UISearchBarDelegate
中凿傅,找到searchBar(_:textDidChange:)
并添加以下內(nèi)容作為最后一行:
let showScope = !searchText.isEmpty
showScopeBar(showScope)
如果搜索文本不是空的,應(yīng)該顯示scope bar
数苫。
在searchBarCancelButtonClicked(_:)
中聪舒,添加以下內(nèi)容作為最后一行:
showScopeBar(false)
現(xiàn)在,當(dāng)用戶點(diǎn)擊搜索欄的取消按鈕時(shí)虐急,您將隱藏scope bar
箱残。
最后,在ResultsTableViewDelegate
中止吁,在didSelect(token:)
結(jié)尾添加以下內(nèi)容:
showScopeBar(true)
當(dāng)用戶選擇一個(gè)token
時(shí)被辑,您現(xiàn)在將顯示scope bar
。
構(gòu)建并運(yùn)行敬惦,然后點(diǎn)擊搜索欄盼理。您將不再看到scope bar
。
點(diǎn)擊一個(gè)token
俄删,scope bar
就會(huì)出現(xiàn)宏怔。
Customizing the Search Bar and Text Field
最后的任務(wù)是在搜索欄中添加一個(gè)主題。在ios13
中顯示search text field
之前畴椰,自定義field
充滿了問題‰铮現(xiàn)在,隨著text field
的暴露斜脂,您可以像定制任何其他UITextField
一樣定制它抓艳。
1. Changing Text and Background Color
設(shè)計(jì)團(tuán)隊(duì)希望text field
更突出一些,所以您的第一個(gè)任務(wù)是更改文本的顏色秽褒。
在viewDidLoad()
中壶硅,添加這一行作為最后一行:
searchController.searchBar.searchTextField.textColor = .rwGreen()
該項(xiàng)目有一個(gè)UIColor
擴(kuò)展。這個(gè)擴(kuò)展返回一個(gè)非常特殊的綠色销斟,您最喜歡的教程站點(diǎn)使用它庐椒。在這里。您正在將search text field
的文本顏色設(shè)置為華麗的綠色陰影蚂踊。
下一步是改變背景顏色约谈。當(dāng)search bar
成為第一個(gè)響應(yīng)時(shí),它應(yīng)該變成透明的綠色。當(dāng)用戶取消搜索時(shí)棱诱,它應(yīng)該返回到默認(rèn)顏色泼橘。
要實(shí)現(xiàn)這一點(diǎn),在UISearchResultsUpdating
擴(kuò)展中找到updateSearchResults(for:)
迈勋,并將它替換為:
func updateSearchResults(for searchController: UISearchController) {
// 1
if searchController.searchBar.searchTextField.isFirstResponder {
searchController.showsSearchResultsController = true
// 2
searchController.searchBar
.searchTextField.backgroundColor = UIColor.rwGreen().withAlphaComponent(0.1)
} else {
// 3
searchController.searchBar.searchTextField.backgroundColor = nil
}
}
在這里炬灭,你是:
- 1) 如果
search text field
是第一個(gè)響應(yīng)者,則顯示結(jié)果控制器靡菇。 - 2) 將
search text field
的背景顏色更改為rwGreen
重归。使用alpha
組件使顏色透明。 - 3) 如果
search text field
不是第一個(gè)響應(yīng)者厦凤,則將背景顏色設(shè)置回默認(rèn)值鼻吮。
在UISearchDelegate
中,查找searchBarCancelButtonClicked(_:)
并將其添加為最后一行:
searchController.searchBar.searchTextField.backgroundColor = nil
如果用戶取消搜索较鼓,則將text field
的背景設(shè)置為默認(rèn)值椎木。
構(gòu)建和運(yùn)行。點(diǎn)擊搜索欄博烂,點(diǎn)擊Search by Africa
香椎,輸入“faso”
。您將看到以下內(nèi)容:
您現(xiàn)在已經(jīng)設(shè)置了搜索text field
的文本和背景主題禽篱。事情看起來很尖銳究流!
但是歉秫,現(xiàn)在這個(gè)token
看起來不太對耘婚〕豆蓿總會(huì)有辦法的,不是嗎肥照?別擔(dān)心脚仔,你下次會(huì)修好的。
2. Changing the Color of Tokens
Token
有幾個(gè)主題選項(xiàng)舆绎。例如鲤脏,您可以像前面那樣設(shè)置Token
的圖標(biāo)。你也可以改變背景顏色吕朵,這是你接下來要做的猎醇。
在viewDidLoad()
中,添加這一行作為最后一行:
searchController.searchBar.searchTextField.tokenBackgroundColor = .rwGreen()
這里努溃,您將tokens
的默認(rèn)背景顏色設(shè)置為rwGreen
硫嘶。
構(gòu)建和運(yùn)行。點(diǎn)擊search
梧税,點(diǎn)擊Search by Oceania
沦疾,你會(huì)看到這個(gè):
看那些綠色称近!它真的可以幫助你出色的新搜索功能脫穎而出。
看看這些很好的資源哮塞,以了解更多關(guān)于UISearchController
:
- WWDC 2019 Modernizing Your UI for iOS 13刨秆。
后記
本篇主要講述了
iOS 13
中UISearchController
和UISearchBar
的新更改,感興趣的給個(gè)贊或者關(guān)注~~~