首發於公衆號git
微信在 iPad 上豎屏時顯示的樣式和手機版同樣,橫屏的顯示爲分隔視圖。github
UIKit 裏能夠實現這樣的效果的組件是UISplitViewController
。swift
接下來就是要自定義一個 UISplitViewController 來逐步實現像微信同樣的效果。微信
豎屏時 master 視圖須要佔滿全屏,橫屏的時候則 master 和 detail 都須要顯示,能夠更好的利用 iPad 大屏幕的優點。app
豎屏模式下,設置 master 的寬度爲全屏大小:ide
private func toPortraitWidth() {
maximumPrimaryColumnWidth = maxMasterWidth
preferredPrimaryColumnWidthFraction = 1
}
複製代碼
橫屏時恢復爲默認寬度佈局
private func toLandscapeWidth() {
maximumPrimaryColumnWidth = UISplitViewController.automaticDimension
preferredPrimaryColumnWidthFraction = UISplitViewController.automaticDimension
}
複製代碼
豎屏模式下,全部子視圖的顯示都由 master 來處理,ui
橫屏模式下,子視圖的顯示都放到 detail 視圖中,spa
須要實現下面這個代理方法,本身來控制頁面的顯示。代理
public func splitViewController(_ splitViewController: UISplitViewController, showDetail vc: UIViewController, sender: Any?) -> Bool {
if isPortrait {
masterViewController?.show(vc, sender: nil)
} else {
detailViewController?.viewControllers = [vc]
}
return true
}
複製代碼
豎屏時,全部的頁面都顯示在 master 視圖中,
橫屏時,全部的子頁面都顯示在 detail 視圖中,
思路比較簡單,在 viewWillTransition
方法裏直接操做 viewControllers
屬性來達到移動子頁面的目的。
public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
var subVCs: [UIViewController] = masterViewController!.viewControllers
// after transition, it will be portrait mode
if !isPortrait {
var flag: Bool = false
if let topVC = detailViewController?.topViewController, !topVC.isKind(of: placeholderViewControllerClass) {
subVCs.append(contentsOf: detailViewController!.viewControllers)
flag = true
}
if flag {
let placeholderViewController = (placeholderViewControllerClass as? UIViewController.Type)?.init() ?? UIViewController()
detailViewController?.viewControllers = [placeholderViewController]
masterViewController?.viewControllers = subVCs
}
toPortraitWidth()
} else {
if subVCs.count > 1 {
subVCs.remove(at: 0)
masterViewController!.popToRootViewController(animated: false)
detailViewController?.viewControllers = subVCs
}
toLandscapeWidth()
}
}
複製代碼
根據以上思路封裝了一個 SFSplitViewController
組件來實現像微信同樣的佈局功能。
使用起來也很簡單,把 SFSplitViewController
做爲 RootController 就能夠了,要求 master 和 detail 的容器必須是 UINavigationController
類型。
使用方法以下:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let rootVC = SFSplitViewController(master: UINavigationController(rootViewController: MainViewController()),
detail: UINavigationController(rootViewController: PlaceholderViewController()))
rootVC.placeholderViewControllerClass = PlaceholderViewController.self
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = rootVC
window?.makeKeyAndVisible()
return true
}
複製代碼
完整的代碼請參考個人 github: SFSplitViewController