前言:
我们要适配iPad。需要用iPad上面有那种modal弹出来的效果。在iPhone上,该push就push,该modal就modal。这个逻辑不变,但是到了iPad上,就需要按照UI设计的来,在特定的页面,modal。
然后,就引发问题了。
在当前控制器 有 或者 没有 NavigationBar的时候,你都得在iPad上把你的下一个控制器present出来,如果你的下一个控制器是带了系统的NavigationBar的,这时候就可能丢失NavigationBar。
应对这样的情况,我枚举了情况,也枚举了代码。
Swift
代码地址:https://github.com/gityuency/Autolayout
示例代码类名 【FormSheetViewController】
示例效果 1 当前控制器 有 导航栏
示例效果 2 当前控制器 没有 导航栏
代码:
FormSheetViewController
import UIKit
class FormSheetViewController: UIViewController {
deinit {
print("FormSheetViewController 控制器销毁了")
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "导航栏出现了"
}
func resolveCircle() {
if navigationController != nil {
navigationController?.popViewController(animated: true)
} else {
dismiss(animated: true, completion: nil)
}
}
/// 设置当前控制器没有 NavigationBar
@IBAction func actionNoNavi(_ sender: UIButton) {
resolveCircle()
let vc = FormSheetViewController()
UIApplication.shared.keyWindow?.rootViewController = vc
}
/// 设置当前控制器 有 NavigationBar
@IBAction func actionAddNavi(_ sender: Any) {
resolveCircle()
let vc = FormSheetViewController()
let navi = UINavigationController(rootViewController: vc)
UIApplication.shared.keyWindow?.rootViewController = navi
}
/// 方案一:
@IBAction func actionOne(_ sender: UIButton) {
let vc = ControllerPopOniPad()
vc.modalPresentationStyle = .formSheet
vc.modalTransitionStyle = .crossDissolve
self.present(vc, animated: true, completion: nil)
}
/// 方案二:
@IBAction func actionTwo(_ sender: UIButton) {
let vc = ControllerPopOniPad()
let navi = UINavigationController(rootViewController: vc)
navi.modalPresentationStyle = .formSheet
navi.modalTransitionStyle = .crossDissolve
self.present(navi, animated: true, completion: nil)
}
/// 方案三:
@IBAction func actionThree(_ sender: UIButton) {
let vc = ControllerPopOniPad()
vc.modalPresentationStyle = .formSheet
vc.modalTransitionStyle = .crossDissolve
self.navigationController?.present(vc, animated: true, completion: nil)
}
/// 方案四:
@IBAction func actionFour(_ sender: UIButton) {
let vc = ControllerPopOniPad()
let navi = UINavigationController(rootViewController: vc)
navi.modalPresentationStyle = .formSheet
navi.modalTransitionStyle = .crossDissolve
self.navigationController?.present(navi, animated: true, completion: nil)
}
/// 方案五:
@IBAction func actionFiv(_ sender: UIButton) {
//操作1
let vc = ControllerPopOniPad()
let navi = UINavigationController(rootViewController: vc)
navi.modalPresentationStyle = .formSheet
navi.modalTransitionStyle = .crossDissolve
//vc.preferredContentSize = CGSize(width: 300, height: 300) //可以直接设置 VC
navi.preferredContentSize = CGSize(width: 300, height: 300) //设置Navi也可以
self.present(navi, animated: true, completion: nil)
//操作2
//let vc = ControllerUseSystemNaviBar()
//vc.modalPresentationStyle = .formSheet
//vc.modalTransitionStyle = .crossDissolve
//vc.preferredContentSize = CGSize(width: 200, height: 600)
//self.present(vc, animated: true, completion: nil)
}
}
ControllerPopOniPad
import UIKit
class ControllerPopOniPad: UIViewController {
deinit {
print("ControllerPopOniPad 销毁了")
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "导航栏: 不再写代码"
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .bookmarks, target: nil, action: nil)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: nil, action: nil)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
dismiss(animated: true, completion: nil)
}
}
结语:
因为有时候,页面顶部的效果需要,所以我们会隐藏系统的NavigationBar,而选择自己在XIB画一个NavigationBar,从而满足页面的效果,尤其是对于那种NavigationBar需要透明,渐变,上面的item各种变化这样的,自己弄一个,用起来也挺方便。
但是吧,有时候代码不是你一个人写,FA国先生有自己的想法,他就喜欢用系统的NavigationBar。我尝试去改了他的代码,结果就是给自己造出了很多bug。场面一度极为混乱,可谓身陷囹圄。
后来在大佬的建议下,给FA国先生写的控制器外面再套一个UINavigationController,再present出来,问题就解决了。因为iPad玩地并不熟练,所以就欠下了一些bug。网上也没有找到药到病除的方法,所以,在这里,写个总结。下次肯定没有bug了