UIViewController 能够理解为 App 的界面,负责管理 UIView 中显示的内容和用户的交互,主要有如下做用:swift
let vc = UIStoryboard(name: "storyboard名", bundle: nil).instantiateInitialViewController()
复制代码
let vc = UIStoryboard(name: "storyboard名", bundle: nil).instantiateViewController(withIdentifier: "Storyboard ID")
复制代码
let vc = UIViewController()
复制代码
这种方式本质是 xib 建立 UIView,而后让这个 UIView 成为 UIViewController 的默认 View。markdown
Also create XIB file
,能够直接经过下面两种方式初始化:// 方式一
let vc = UIViewController()
// 方式二
let vc = UIViewController(nibName: "xib的名字", bundle: nil)
复制代码
(1)将 xib 文件 的File’s Owner
的类绑定为 UIViewController。 (2)将File’s Owner
的view
属性设置为xib
文件(拽线设置便可)。闭包
在入门知识里初步介绍了 UIViewController 与其属性view
的关系,其实它们之间的关系没有那么简单,须要进一步分析。app
init、init(nibName...)(初始化、分配内存)—> loadView(加载view)—> viewDidLoad(view已经加载)—> viewWillAppear(view即将显示)—> viewWillLayoutSubviews(将要布局子view)—> viewDidLayoutSubviews(已经布局子view)—> viewDidAppear(view已经显示)—> viewWillDisappear(view即将消失)—> viewDidDisappear(view已经消失)—> dealloc(释放内存)
复制代码
UIViewController 的 view 的延迟加载:第一次使用的时候才会去加载,并非建立 UIViewController 时加载。ide
func loadView() {
// 若是UIViewController是经过storyboard建立的,从storyboard中加载视图来建立view
if storyboard建立 {
// ...
return
}
// 若是UIViewController是经过xib建立的,从xib中加载视图来建立view
if xib建立 {
// ...
return
}
// 若是上面都不是,则会建立一个普通的view视图
let view = UIView(frame: UIScreen.main.bounds)
self.view = view
}
复制代码
super.loadView()
。override func loadView() {
let myView = UIView(frame: UIScreen.main.bounds)
view = myView
}
复制代码
从一个 UIViewController 跳转到另外一个 UIViewController 有两种方式,分别为模态跳转和导航跳转。布局
Present Modally
,这根线是一个 UIStoryboardSegue 对象(简称 Segue),能够设置相关的属性。identifier
。performSegue(withIdentifier: , sender:)
方法完成跳转。present
。dismiss
。presentedViewController
: 被 present 的控制器。presentingViewController
:正在 presenting 的控制器。这种操做的前提是 UIViewController 包含在 UINavigationController 中。post
Show
。navigationController?.pushViewController
。navigationController?.popViewController
。顺向传值即按照 UIViewController 跳转的顺序进行传值,好比控制器A跳转到控制器B,A向B的传值就是顺向传值。顺向传值只须要在目标控制器中声明须要接收的参数,而后在源控制器中进行传值便可。ui
逆向传值即按照 UIViewController 跳转的顺序反向进行传值,好比控制器A跳转到控制器B,控制器B在返回控制器A时进行传值,这种方式就是逆向传值。逆向传值不能像顺向传值那样简单进行,须要借助于下面三种方式。spa
代理模式须要弄清楚被代理对象和代理对象,而后按照下面的规范进行。设计
能够理解为代理模式中协议的闭包替代,比代理模式更简单。
NotificationCenter.default.addObserver(self, selector: #selector(handlerNoti), name: NSNotification.Name("abc"), object: nil)
复制代码
NotificationCenter.default.post(name: NSNotification.Name("abc"), object: nil, userInfo: ["info" : inputTf.text!])
复制代码
alert
和actionSheet
。default
、cancel
和destructive
,一个 UIAlertController 中只能有一个cancel
样式的 UIAlertAction。class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func showAlert(_ sender: Any) {
let alertVC = UIAlertController(title: "舒适提示", message: "天气转凉,你们注意保暖,当心感冒", preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default) { _ in
print("点击了ok")
}
let cancel = UIAlertAction(title: "Cancel", style: .cancel) { _ in
print("点击了cancel")
}
alertVC.addAction(ok)
alertVC.addAction(cancel)
present(alertVC, animated: true, completion: nil)
}
@IBAction func showSheet(_ sender: Any) {
let alertVC = UIAlertController(title: "选择头像", message: "请选择合适的方式来处理", preferredStyle: .actionSheet)
let ok = UIAlertAction(title: "相册", style: .default) { _ in
print("用户选择了相册")
}
let des = UIAlertAction(title: "拍照", style: .destructive) { _ in
print("用户选择了拍照")
}
let cancel = UIAlertAction(title: "取消", style: .cancel) { _ in
print("点击了取消")
}
alertVC.addAction(ok)
alertVC.addAction(des)
alertVC.addAction(cancel)
present(alertVC, animated: true, completion: nil)
}
}
复制代码
UINavigationBar
,最下面默认隐藏的UIToolBar
,中间是 UIViewController 的view
。pushViewController
:压栈。popViewController
:出栈。UINavigationBar
是 UINavigationController 的属性,其属性设置会影响内部全部的 UIViewController。UINavigationItem
是 UIViewController 的属性,用于配置当前 UIViewController 显示时UINavigationBar
上显示的内容。UINavigationBar
内部也维持一个栈,栈中存放的是一个个 UINavigationItem
。当一个 UIViewController push 到 UINavigationController 时,它的UINavigationItem
也会被 push 进 UINavigationBar
的栈。所以UINavigationBar
的栈和 UINavigationController 的栈一一对应。titleView
属性,则展现标题视图。title
属性,则显示标题文字。// 全部界面显示大标题
navigationController?.navigationBar.prefersLargeTitles = true
// 当前界面是否显示大标题,never表示不显示大标题即显示小标题
navigationItem.largeTitleDisplayMode = .never
复制代码
rightBarButtonItem
属性,则显示右侧按钮,不然显示空白。leftBarButtonItem
属性,则显示左侧按钮。backButtonItem
属性,则显示返回按钮。title
属性,则显示标题文字封装的返回按钮。Back
封装的返回按钮。注意:默认状况下返回按钮和左侧按钮是不一样时显示的,只显示返回按钮而不显示左侧按钮。
leftBarButtonItem
属性,则默认的返回按钮会被替代,自带的返回和从屏幕边缘滑动返回的效果失效,此时只能经过popViewController
返回。backButtonItem
属性或设置了backButtonTitle
,能够起到更改返回按钮文字和图片的目的,可是返回按钮的<
图标会一直存在,这种方式自带的返回和从屏幕边缘滑动返回的效果依然有效。barTintColor
设置。tintColor
设置。view
,下面是UITabBar
。addChildViewController
添加 UIViewController,经过UIViewController 的UITabBarItem
属性设置展现的文字、默认图片、选中图片和角标。UITabBarDelegate
。tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem)
方法。tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController)
方法。能够经过 UITabBar 的barTintColor
设置。
// 默认文字颜色
vc.tabBarItem.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.white], for: .normal)
// 选中文字颜色
vc.tabBarItem.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.orange], for: .highlighted)
复制代码
let item = UITabBarItem.appearance()
// 默认文字颜色
item.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.white], for: .normal)
// 选中文字颜色
item.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.orange], for: .highlighted)
复制代码
// 选中的图片文字颜色
vc.tabBarController?.tabBar.tintColor = UIColor.orange
// 未选中的文字颜色
vc.tabBarController?.tabBar.unselectedItemTintColor = UIColor.white
// 角标的背景色
vc.tabBarItem.badgeColor = UIColor.orange
// 角标的颜色
vc.tabBarItem.badgeTextAttributes(for: .normal) = UIColor.white
复制代码