版本記錄
| 版本號(hào) | 時(shí)間 |
|---|---|
| V1.0 | 2019.09.18 星期三 |
前言
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)場(chǎng)和展示(一)
23. UIKit框架(二十三) —— 基于UIPresentationController的自定義viewController的轉(zhuǎn)場(chǎng)和展示(二)
24. UIKit框架(二十四) —— 基于UICollectionViews和Drag-Drop在兩個(gè)APP間的使用示例 (一)
25. UIKit框架(二十五) —— 基于UICollectionViews和Drag-Drop在兩個(gè)APP間的使用示例 (二)
26. UIKit框架(二十六) —— UICollectionView的自定義布局 (一)
27. UIKit框架(二十七) —— UICollectionView的自定義布局 (二)
開始
今天是個(gè)特殊的日子,勿忘國恥,國人當(dāng)自強(qiáng),向抵抗侵略的將士們致敬!
首先看下主要內(nèi)容
了解如何將iOS應(yīng)用程序拆分為兩個(gè)部分,并在此
UISplitViewController教程的每一側(cè)顯示視圖控制器
接著看一下寫作環(huán)境
Swift 5, iOS 13, Xcode 11
應(yīng)用程序通常需要提供拆分視圖以提供整潔的導(dǎo)航模型。 這方面的一個(gè)例子是Mail.app,它在iPad上使用左側(cè)有文件夾列表的分割視圖,然后是右側(cè)選定的郵件項(xiàng)目。 Apple為我們構(gòu)建了一個(gè)非常方便的視圖控制器,稱為UISplitViewController,它可以直接回到iPad的低端。 在這個(gè)UISplitViewController教程中,您將學(xué)習(xí)如何使用它! 此外,自iOS 8起,split view controller拆分視圖控制器可在iPad和iPhone上運(yùn)行。
在本教程中,您將從頭開始創(chuàng)建一個(gè)通用應(yīng)用程序,它使用split view controller來顯示Math Ninja中的怪物列表。
您將使用拆分視圖控制器來處理導(dǎo)航和顯示。 它適用于iPhone和iPad。

單擊File ? New ? Project…,在Xcode中創(chuàng)建一個(gè)新項(xiàng)目。 選擇 iOS ? Application ? Single View App模板。

將項(xiàng)目命名為MathMonsters。 將Language保持為Swift。 將User Interface設(shè)置為Storyboard。 取消選中所有復(fù)選框。 然后單擊Next完成項(xiàng)目的創(chuàng)建。
雖然您可以使用Master-Detail App模板作為起點(diǎn),但您將從頭開始使用Single View App模板。 這將使您更好地了解UISplitViewController的工作原理。 在將來的項(xiàng)目中使用UISplitViewController時(shí),這些知識(shí)將非常有用。
是時(shí)候創(chuàng)建UI了,所以打開Main.storyboard。
刪除故事板中的默認(rèn)初始View Controller Scene。 同時(shí)從項(xiàng)目導(dǎo)航器中刪除ViewController.swift,確保在詢問時(shí)選擇Move to Trash。
將拆分視圖控制器拖到空的故事板中:

這將為您的storyboard添加幾個(gè)元素:
- Split View Controller - 拆分視圖控制器:此拆分視圖將包含應(yīng)用程序的其余部分,并且是應(yīng)用程序的根。
-
Navigation Controller - 導(dǎo)航控制器:此
UINavigationController將是主視圖控制器的根視圖。 這是拆分視圖的左側(cè)窗格,當(dāng)在iPad上或在較大的iPhone(如iPhone 8 Plus)上橫向顯示時(shí)。在拆分視圖控制器中,您將看到導(dǎo)航控制器具有稱為master view controller的關(guān)系segue。 這允許您在主視圖控制器中創(chuàng)建整個(gè)導(dǎo)航層次結(jié)構(gòu),而無需影響詳細(xì)視圖控制器。 -
View Controller - 視圖控制器:這將最終顯示所有怪物的詳細(xì)信息。 如果查看拆分視圖控制器,您將看到視圖控制器具有稱為詳細(xì)視圖控制器
(detail view controller)的關(guān)系segue:

-
Table View Controller:這是主
UINavigationController的根視圖控制器。 它最終將顯示怪物列表。
注意:Xcode會(huì)警告您表視圖的原型單元缺少重用標(biāo)識(shí)符
(reuse identifier)。 暫時(shí)不要擔(dān)心。 你很快就會(huì)解決它。
由于您從故事板中刪除了默認(rèn)的初始視圖控制器,因此您需要告訴故事板您希望拆分視圖控制器成為初始視圖控制器。
選擇Split View Controller,然后打開Attributes inspector。 選中Is Initial View Controller選項(xiàng)。

您將在分割視圖控制器的左側(cè)看到一個(gè)箭頭。 這告訴你它是這個(gè)故事板的初始視圖控制器。
在iPad模擬器上構(gòu)建并運(yùn)行應(yīng)用程序。 將模擬器旋轉(zhuǎn)到橫向。
您應(yīng)該看到一個(gè)空的拆分視圖控制器:

現(xiàn)在可以在任何iPhone模擬器上運(yùn)行它,除了一個(gè)加大尺寸的手機(jī),它足夠大,可以像iPad一樣運(yùn)行。 你會(huì)看到它開始全屏顯示細(xì)節(jié)視圖。 它還允許您點(diǎn)擊導(dǎo)航欄上的后退按鈕以彈回主視圖控制器:

在除了橫向大型Plus或Max設(shè)備之外的iPhone上,分割視圖控制器將像傳統(tǒng)的master-detail應(yīng)用程序一樣,帶有導(dǎo)航控制器來回推出和彈出。這是內(nèi)置功能,開發(fā)人員只需要很少的額外配置。
您需要顯示自己的視圖控制器而不是這些默認(rèn)控制器。是時(shí)候開始創(chuàng)建它們了。
Creating Custom View Controllers
故事板具有視圖控制器層次結(jié)構(gòu)集:拆分視圖控制器,其主視圖控制器和詳細(xì)視圖控制器作為其子視圖?,F(xiàn)在,您需要實(shí)現(xiàn)代碼方面以獲取要顯示的數(shù)據(jù)。
轉(zhuǎn)到File ? New ? File…,并選擇iOS ? Source ? Cocoa Touch Class模板。將類命名為MasterViewController,并使其成為UITableViewController的子類。確保未選中Also create XIB file復(fù)選框,并將Language設(shè)置為Swift。單擊Next,然后單擊Create。
打開MasterViewController.swift。
向下滾動(dòng)到numberOfSections(in:)中。刪除此方法。只返回一個(gè)部分時(shí)不需要它。
接下來,找到tableView(_:numberOfRowsInSection :)并用以下內(nèi)容替換實(shí)現(xiàn):
override func tableView(
_ tableView: UITableView,
numberOfRowsInSection section: Int)
-> Int {
return 10
}
最后,取消注釋tableView(_:cellForRowAt :)并將其實(shí)現(xiàn)替換為以下內(nèi)容:
override func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath)
-> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
return cell
}
這樣,當(dāng)你稍后測(cè)試這個(gè)東西時(shí),你將看到十個(gè)空行。
打開Main.storyboard。 選擇Root View Controller并切換Identity檢查器。 將類更改為MasterViewController。
此外,您需要確保在表視圖中為原型單元格提供重用標(biāo)識(shí)符。 如果沒有,它會(huì)在故事板試圖加載時(shí)導(dǎo)致崩潰。
在Master View Controller中,選擇Prototype Cell。 在Attributes inspector中,將Identifier更改為Cell。 同時(shí)將單元格Style更改為Basic。

在iPad或iPhone模擬器中構(gòu)建和運(yùn)行。 你會(huì)注意到雖然有十行,都標(biāo)有標(biāo)題,點(diǎn)擊一行不會(huì)做任何事情。 這是因?yàn)槟形粗付ㄔ敿?xì)視圖控制器。
現(xiàn)在,您將為細(xì)節(jié)方創(chuàng)建視圖控制器。
轉(zhuǎn)到File ? New ? File…,并選擇iOS ? Source ? Cocoa Touch Class模板。 將類命名為DetailViewController,并使其成為UIViewController的子類。 確保未選中Also create XIB file復(fù)選框,并將Language設(shè)置為Swift。
單擊Next,然后單擊Create。
打開Main.storyboard并在View Controller Scene中選擇視圖控制器。 在Identity inspector中,將Class更改為DetailViewController。
然后將label拖到詳細(xì)視圖控制器的中間。 使用“自動(dòng)布局”將label固定到容器的水平和垂直中心。

雙擊label將其文本更改為Hello,World!,所以當(dāng)你稍后測(cè)試它時(shí)你會(huì)知道它正在工作。
構(gòu)建并運(yùn)行。 此時(shí),您應(yīng)該看到自定義視圖控制器。
在iPad上:

在iPhone上:

您現(xiàn)在已經(jīng)獲得了拆分視圖的基礎(chǔ),每個(gè)位都有自定義視圖控制器。 接下來你需要添加那些討厭的怪物。
Making Your Model
接下來,您需要為要顯示的數(shù)據(jù)定義模型。 在學(xué)習(xí)拆分視圖控制器的基礎(chǔ)知識(shí)時(shí),您不希望復(fù)雜化,因此您將使用沒有數(shù)據(jù)持久性的簡單模型。
首先,創(chuàng)建一個(gè)表示要顯示的怪物的類。 轉(zhuǎn)到File ? New ? File…,選擇iOS ? Source ? Swift File模板,然后單擊Next。 將文件命名為Monster,然后單擊Create。
您將創(chuàng)建一個(gè)簡單的類,其中包含有關(guān)要顯示的每個(gè)怪物的屬性屬性。 您還將實(shí)現(xiàn)一些方法來創(chuàng)建新的怪物并訪問每個(gè)怪物武器的圖像。
用以下內(nèi)容替換Monster.swift的內(nèi)容:
import UIKit
enum Weapon {
case blowgun, ninjaStar, fire, sword, smoke
var image: UIImage {
switch self {
case .blowgun:
return UIImage(named: "blowgun.png")!
case .fire:
return UIImage(named: "fire.png")!
case .ninjaStar:
return UIImage(named: "ninjastar.png")!
case .smoke:
return UIImage(named: "smoke.png")!
case .sword:
return UIImage(named: "sword.png")!
}
}
}
class Monster {
let name: String
let description: String
let iconName: String
let weapon: Weapon
init(name: String, description: String, iconName: String, weapon: Weapon) {
self.name = name
self.description = description
self.iconName = iconName
self.weapon = weapon
}
var icon: UIImage? {
return UIImage(named: iconName)
}
}
這定義了枚舉和類。 枚舉是為了跟蹤不同種類的武器,包括每種武器的圖像。 該類將使用簡單的初始化程序保存怪物信息以創(chuàng)建Monster實(shí)例。
這是用于定義模型的。 接下來,您將它連接到您的主視圖!
Displaying the Monster List
打開MasterViewController.swift并向該類添加一個(gè)新屬性:
let monsters = [
Monster(name: "Cat-Bot", description: "MEE-OW",
iconName: "meetcatbot", weapon: .sword),
Monster(name: "Dog-Bot", description: "BOW-WOW",
iconName: "meetdogbot", weapon: .blowgun),
Monster(name: "Explode-Bot", description: "BOOM!",
iconName: "meetexplodebot", weapon: .smoke),
Monster(name: "Fire-Bot", description: "Will Make You Steamed",
iconName: "meetfirebot", weapon: .ninjaStar),
Monster(name: "Ice-Bot", description: "Has A Chilling Effect",
iconName: "meeticebot", weapon: .fire),
Monster(name: "Mini-Tomato-Bot", description: "Extremely Handsome",
iconName: "meetminitomatobot", weapon: .ninjaStar)
]
這可以保存用于填充表視圖的怪物數(shù)組。
找到tableView(_:numberOfRowsInSection :)并將return語句替換為以下內(nèi)容:
return monsters.count
這將根據(jù)數(shù)組的大小返回怪物數(shù)量。
接下來,找到tableView(_:cellForRowAtIndexPath :)并在最終的return語句之前添加以下代碼:
let monster = monsters[indexPath.row]
cell.textLabel?.text = monster.name
這將根據(jù)正確的怪物配置單元格。 這就是table view,它只是顯示每個(gè)怪物的名字。
構(gòu)建并運(yùn)行應(yīng)用程序。
你應(yīng)該在橫屏iPad的左側(cè)看到怪物機(jī)器人列表:

在iPhone上:

請(qǐng)記住,在compact-width的iPhone上,您可以在詳細(xì)信息屏幕上的導(dǎo)航堆棧中開始一層深度。 您可以點(diǎn)擊后退按鈕查看table view。
Updating the Master View Controller’s Title
導(dǎo)航欄自動(dòng)設(shè)置初始視圖控制器的標(biāo)題,即RootViewController。
打開Main.storyboard,選擇Root View Controller并雙擊NavigationBar。
將其更改為Monster List。 這比Root View Controller好得多。

Displaying Bot Details
現(xiàn)在table view顯示了怪物列表,現(xiàn)在是時(shí)候按順序獲取詳細(xì)視圖了。
打開Main.storyboard,選擇Detail View Controller并刪除之前放下的label。
使用下面的屏幕截圖作為指導(dǎo),將以下控件拖到DetailViewController的視圖中(有關(guān)要添加的內(nèi)容的詳細(xì)列表,請(qǐng)參閱下面的內(nèi)容):

以下是您需要添加的內(nèi)容:
- 1) 其余視圖將進(jìn)入的容器視圖。這應(yīng)該與屏幕頂部對(duì)齊并在屏幕中水平居中。
- 2) 一個(gè)
95×95的圖像視圖,距離容器視圖頂部8個(gè)像素,距離左側(cè)20個(gè)像素。這是為了顯示怪物的圖像。 - 3) 與圖像視圖頂部對(duì)齊的
label,字體System Bold,大小為30,文本為Monster Name。將其頂部與圖像的頂部對(duì)齊,并將其設(shè)置為圖像右側(cè)的8個(gè)像素。同時(shí)使其尾部邊距容器視圖的右側(cè)8像素。 - 4) 下面有兩個(gè)帶有
System字體的labels,尺寸為24。一個(gè)label應(yīng)與圖像視圖底部對(duì)齊。另一個(gè)label應(yīng)位于第一個(gè)標(biāo)簽下方。它們的左邊緣應(yīng)該對(duì)齊,它們應(yīng)該垂直間隔8個(gè)像素。同時(shí)將這些標(biāo)簽的尾部設(shè)置為距離容器視圖右側(cè)8個(gè)像素。他們應(yīng)該有標(biāo)題Description和Preferred way to kill。 - 5) 一個(gè)
70×70的圖像視圖,與Preferred way to kill標(biāo)簽左對(duì)齊,8像素垂直間距。同時(shí)將其底部設(shè)置為距離容器視圖底部8個(gè)像素。
讓自動(dòng)布局使用適當(dāng)?shù)募s束尤其重要,因?yàn)檫@個(gè)應(yīng)用程序是通用的,自動(dòng)布局確保布局適應(yīng)iPad和iPhone。

這就是現(xiàn)在的自動(dòng)布局。 接下來,您需要將這些視圖掛鉤到某些outlets。
打開DetailViewController.swift并將以下屬性添加到類的頂部:
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var descriptionLabel: UILabel!
@IBOutlet weak var iconImageView: UIImageView!
@IBOutlet weak var weaponImageView: UIImageView!
var monster: Monster? {
didSet {
refreshUI()
}
}
在這里,您為剛剛創(chuàng)建的需要?jiǎng)討B(tài)更改的各種UI元素添加了屬性。 您還為此視圖控制器應(yīng)顯示的Monster對(duì)象添加了一個(gè)屬性。
接下來,將以下幫助器方法添加到類中:
private func refreshUI() {
loadViewIfNeeded()
nameLabel.text = monster?.name
descriptionLabel.text = monster?.description
iconImageView.image = monster?.icon
weaponImageView.image = monster?.weapon.image
}
無論何時(shí)切換怪物,您都希望UI自行刷新并更新outlets中顯示的詳細(xì)信息。 你甚至可以在視圖加載之前更改monster并觸發(fā)方法。 因此,您調(diào)用loadViewIfNeeded()以保證視圖已加載且其outlets已連接。
現(xiàn)在,打開Main.storyboard。 在Document Outline中右鍵單擊Detail View Controller對(duì)象以顯示插座列表。 從每個(gè)項(xiàng)目右側(cè)的圓圈拖動(dòng)到視圖以連接outlets。

請(qǐng)記住,圖標(biāo)圖像視圖是左上角的大圖像視圖。 武器圖像視圖是Preferred way to kill標(biāo)簽的方式下面較小的一個(gè)。
轉(zhuǎn)到SceneDelegate.swift并使用以下內(nèi)容替換scene(_:willConnectTo:options :)的實(shí)現(xiàn):
guard
let splitViewController = window?.rootViewController as? UISplitViewController,
let leftNavController = splitViewController.viewControllers.first
as? UINavigationController,
let masterViewController = leftNavController.viewControllers.first
as? MasterViewController,
let detailViewController = splitViewController.viewControllers.last
as? DetailViewController
else { fatalError() }
let firstMonster = masterViewController.monsters.first
detailViewController.monster = firstMonster
拆分視圖控制器具有一個(gè)數(shù)組屬性viewControllers,其中包含主控制器和詳細(xì)視圖控制器。 在您的情況下,主視圖控制器實(shí)際上是導(dǎo)航控制器。 因此,要獲取實(shí)際的MasterViewController實(shí)例,請(qǐng)使用導(dǎo)航控制器的第一個(gè)視圖控制器。
要獲取詳細(xì)視圖控制器,請(qǐng)查看拆分視圖控制器的viewControllers數(shù)組中的第二個(gè)視圖控制器。
構(gòu)建并運(yùn)行應(yīng)用程序,您應(yīng)該在右側(cè)看到一些怪物細(xì)節(jié)。
在iPad上橫屏:

在iPhone上

請(qǐng)注意,在MasterViewController上選擇一個(gè)monster什么也沒做,你就永遠(yuǎn)陷入了Cat-Bot。 這就是你接下來要做的事情!
Hooking Up the Master With the Detail
關(guān)于如何在這兩個(gè)視圖控制器之間進(jìn)行最佳通信的策略有很多。 在Master-Detail App模板中,主視圖控制器具有對(duì)詳細(xì)視圖控制器的引用。 這意味著主視圖控制器可以在選擇行時(shí)在詳細(xì)視圖控制器上設(shè)置屬性。
這適用于在詳細(xì)信息窗格中只有一個(gè)視圖控制器的簡單應(yīng)用程序。 但是,您將遵循UISplitViewController類引用中建議的方法來處理更復(fù)雜的應(yīng)用程序并使用委托delegate。
打開MasterViewController.swift并在MasterViewController類定義上面添加以下協(xié)議定義:
protocol MonsterSelectionDelegate: class {
func monsterSelected(_ newMonster: Monster)
}
這定義了一個(gè)帶有單個(gè)方法的協(xié)議,monsterSelected(_ :)。 詳細(xì)視圖控制器將實(shí)現(xiàn)此方法,并且主視圖控制器將在用戶選擇怪物時(shí)向其發(fā)送消息。
接下來,更新MasterViewController以添加符合委托協(xié)議的對(duì)象的屬性:
weak var delegate: MonsterSelectionDelegate?
基本上,這意味著委托屬性需要是一個(gè)實(shí)現(xiàn)了monsterSelected(_ :)的對(duì)象。 在用戶選擇怪物后,該對(duì)象將負(fù)責(zé)處理其視圖中需要發(fā)生的事情。
由于您希望DetailViewController在用戶選擇怪物時(shí)更新,因此您需要實(shí)現(xiàn)委托。
打開DetailViewController.swift并在文件的最后添加一個(gè)類擴(kuò)展:
extension DetailViewController: MonsterSelectionDelegate {
func monsterSelected(_ newMonster: Monster) {
monster = newMonster
}
}
類擴(kuò)展非常適合分離委托協(xié)議并將方法組合在一起。 在此擴(kuò)展中,您說DetailViewController符合MonsterSelectionDelegate。 然后,您實(shí)現(xiàn)一個(gè)必需的方法。
現(xiàn)在委托方法已準(zhǔn)備就緒,您需要從master方面調(diào)用它。
打開MasterViewController.swift并添加以下方法:
override func tableView(
_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath) {
let selectedMonster = monsters[indexPath.row]
delegate?.monsterSelected(selectedMonster)
}
實(shí)現(xiàn)tableView(_:didSelectRowAt :)意味著只要用戶在表視圖中選擇一行,您就會(huì)收到通知。 您需要做的就是通知新怪物的怪物選擇代理。
最后,返回SceneDelegate.swift。 在scene(_:willConnectTo:options:)中,在方法的最后添加以下代碼:
masterViewController.delegate = detailViewController
這是兩個(gè)視圖控制器之間的最終連接。
在iPad上構(gòu)建并運(yùn)行應(yīng)用程序。 你現(xiàn)在應(yīng)該可以在monsters之間進(jìn)行選擇,如下所示:

到目前為止,拆分視圖非常好! 但是還有一個(gè)問題:如果你在iPhone上運(yùn)行它,從主表視圖中選擇怪物不會(huì)顯示詳細(xì)視圖控制器。 您現(xiàn)在需要進(jìn)行一些小修改,以確保拆分視圖也適用于iPhone。
打開MasterViewController.swift。 找到tableView(_:didSelectRowAt :)并將以下內(nèi)容添加到方法的末尾:
if let detailViewController = delegate as? DetailViewController {
splitViewController?.showDetailViewController(detailViewController, sender: nil)
}
首先,您需要確保代理已設(shè)置,并且它是一個(gè)DetailViewController實(shí)例,正如您所期望的那樣。 然后在拆分視圖控制器上調(diào)用showDetailViewController(_:sender :)并傳入詳細(xì)視圖控制器。 UIViewController的每個(gè)子類都有一個(gè)繼承屬性splitViewController,它將引用它容器視圖控制器(如果存在)。
此新代碼僅更改iPhone上應(yīng)用程序的行為,導(dǎo)致導(dǎo)航控制器在您選擇新怪物時(shí)將細(xì)節(jié)控制器推入堆棧。 它不會(huì)改變iPad實(shí)現(xiàn)的行為,因?yàn)樵趇Pad上,細(xì)節(jié)視圖控制器始終可見。
進(jìn)行此更改后,在iPhone上運(yùn)行它現(xiàn)在應(yīng)該正常運(yùn)行。 只需添加幾行代碼,您就可以在iPad和iPhone上使用功能齊全的分割視圖控制器。 不錯(cuò)!

Split View Controller in iPad Portrait
以縱向模式在iPad中運(yùn)行應(yīng)用程序。 起初,似乎沒有辦法進(jìn)入左側(cè)菜單。
但請(qǐng)嘗試從屏幕左側(cè)滑動(dòng)。 很酷吧? 點(diǎn)按菜單外的任意位置即可隱藏它。
內(nèi)置的滑動(dòng)功能非常酷,但是如果你想在導(dǎo)航欄上方放置一個(gè)顯示菜單的按鈕,類似于它在iPhone上的表現(xiàn)怎么辦? 要做到這一點(diǎn),您需要對(duì)應(yīng)用程序進(jìn)行一些小的修改。
首先,打開Main.storyboard并將Detail View Controller嵌入到導(dǎo)航控制器中。 您可以通過選擇詳細(xì)視圖控制器,然后選擇Editor ? Embed In ? Navigation Controller來完成此操作。
您的故事板現(xiàn)在看起來像這樣:

現(xiàn)在打開MasterViewController.swift并找到tableView(_:didSelectRowAt :)。 通過調(diào)用showDetailViewController(_:sender :)將if塊更改為以下內(nèi)容:
if
let detailViewController = delegate as? DetailViewController,
let detailNavigationController = detailViewController.navigationController {
splitViewController?
.showDetailViewController(detailNavigationController, sender: nil)
}
現(xiàn)在,您將顯示詳細(xì)視圖控制器的導(dǎo)航控制器,而不是顯示詳細(xì)視圖控制器。 無論如何,導(dǎo)航控制器的根目錄是詳細(xì)視圖控制器,因此您仍然可以看到與之前相同的內(nèi)容,只需將其包含在導(dǎo)航控制器中。
在運(yùn)行應(yīng)用程序之前,最后要進(jìn)行兩項(xiàng)更改。
首先,在SceneDelegate.swift更新scene(_willConnectTo:options:)中,通過替換初始化detailViewController的行來解釋DetailViewController現(xiàn)在包含在導(dǎo)航控制器中的事實(shí):
let detailViewController =
(splitViewController.viewControllers.last as? UINavigationController)?
.topViewController as? DetailViewController
由于詳細(xì)視圖控制器包含在導(dǎo)航控制器中,因此現(xiàn)在有兩個(gè)步驟來訪問它。
最后,在方法結(jié)束之前添加以下行。
detailViewController.navigationItem.leftItemsSupplementBackButton = true
detailViewController.navigationItem.leftBarButtonItem =
splitViewController.displayModeButtonItem
這告訴詳細(xì)視圖控制器用一個(gè)按鈕替換其左側(cè)導(dǎo)航項(xiàng),該按鈕將切換拆分視圖控制器的顯示模式。 在iPhone上運(yùn)行時(shí)不會(huì)改變?nèi)魏螙|西,但在iPad上,你會(huì)在左上角看到一個(gè)按鈕來切換table view顯示。
在iPad豎屏上運(yùn)行應(yīng)用程序并檢查:

現(xiàn)在,您可以在縱向和橫向上在iPad和iPhone上運(yùn)行良好的效果!
后記
本篇主要講述了一個(gè)UISplitViewController的簡單實(shí)用示例,感興趣的給個(gè)贊或者關(guān)注~~~
