当前篇:iOS界面开发—开篇
下一篇:iOS界面开发—导航控制器和标签控制器
前言
本系列文章用来总结我自己做iOS开发的一些UI方面的经验,我从零开始跌跌撞撞做了三年iOS开发,能力有限,经验有限,如果有读者读到我的文章,有发现不对的地方,或者有更好的解决方法的地方,还望提出来一起讨论。
本系列文章不对开发语言进行讲解,代码用Swift4进行展示,同时不对UIKit框架的组件进行详细讲解。
我习惯用纯代码进行UI开发,因此文章里基本不会出现storyboard和xib,所以可能一些地方不适用于可视化界面开发,同时我很少用autolayout,我觉得手机屏幕尺寸固定有限,用代码布局妥妥的够了,也方便贴代码。
创建工程
首先创建一个UIStudy的工程,开发者账号及证书用你自己的就行,如果没有可以用虚拟机做测试,更改项目配置如下:
我们把Main Interface清空,表示不使用storyboard构建界面,现在编译应用可能会看到报错,提示safeArea在iOS 9.0之后才支持,可以把配置文件中的Deployment Target升到9.0,也可以在storyboard文件中把User Safe Area Layout Guides关掉
LaunchScreen.storyboard文件也一样,由于我们项目中没有用Main.storyboard来构建应用,所以可以选择删掉,但是LaunchScreen.storyboard文件暂时不能删掉,因为我们还需要用它来确保应用的窗口大小。
注意项目配置截图中Launch Images Source和Launch Screen File两个选项,它们是用来设置应用启动界面的,如果两个选项都没设置,那么应用可能不是全屏的,我们也可以用图片作为启动界面,需要给出每一种屏幕尺寸对应的图片,否则应用界面可能也不是全屏的,我们这里就不用图片了,就用LaunchScreen.storyboard文件作为启动界面就行了。
现在运行应用,我们看到的是一个黑框,如果需要显示图形界面,就需要手动创建了,这就是为什么我不用Main.storyboard的原因,因为不写代码可能不会知道应用的界面是怎么显示出来的。
手动显示界面
如果我们要让应用正常显示图形界面,就需要自己动手创建,核心就在于UIWindow。想要显示一个图形界面就需要创建一个 UIWindow ,设置rootViewController,然后让其成为主窗口:
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow.init(frame: UIScreen.main.bounds)
window!.backgroundColor = UIColor.white
window!.rootViewController = ViewController()
window!.makeKeyAndVisible()
return true
}
打开AppDelegate.swift编写以上代码,运行应用,我们就能看见一个白色的界面了,这个界面的内容就是ViewController中定义的内容,现在还是空的界面,稍候我们会在上面显示一些内容。
创建UIWindow时一定要指定frame,否则在iOS 8及以上系统中应用无法响应事件,同时最好设置一下背景色,否则可能会在某些极其特殊的情况下屏幕中间会出现黑块。
简单布局扩展
import UIKit
//MARK: 简单布局扩展
extension UIView {
//MARK: iPhone X适配属性
/** 高度减去iPhone X底部不安全高度*/
var safeAreaBottom: CGFloat {
if #available(iOS 11.0, *) {
return height - safeAreaInsets.bottom
} else {
return height
}
}
/** iPhone X顶部不安全高度*/
var safeAreaTop: CGFloat {
if #available(iOS 11.0, *) {
return safeAreaInsets.top
} else {
return 0
}
}
/** iPhone X安全区域高度*/
var safeAreaHeight: CGFloat {
if #available(iOS 11.0, *) {
return height - safeAreaInsets.bottom - safeAreaInsets.top
} else {
return height
}
}
var height: CGFloat {
get {
return self.frame.size.height
}
set {
self.frame.size.height = newValue
}
}
var width: CGFloat {
get {
return self.frame.size.width
}
set {
self.frame.size.width = newValue
}
}
var size: CGSize {
get {
return self.frame.size
}
set {
self.frame.size = newValue
}
}
var top: CGFloat {
get {
return self.frame.origin.y
}
set {
self.frame.origin.y = newValue
}
}
var bottom: CGFloat {
get {
return self.top + self.height
}
set {
self.frame.origin.y = newValue - self.height
}
}
var left: CGFloat {
get {
return self.frame.origin.x
}
set {
self.frame.origin.x = newValue
}
}
var right: CGFloat {
get {
return self.left + self.width
}
set {
self.frame.origin.x = newValue - self.width
}
}
var origin: CGPoint {
get {
return self.frame.origin
}
set {
self.frame.origin = newValue
}
}
var centerX: CGFloat {
get {
return self.center.x
}
set {
self.center.x = newValue
}
}
var centerY: CGFloat {
get {
return self.center.y
}
set {
self.center.y = newValue
}
}
//MARK: 适应性布局设置
//例如:当改变left位置的时候,自适应宽度好保持视图right位置不变
func autoLeft(_ new: CGFloat) {
let widthChanged = left - new
left = new
width += widthChanged
}
func autoRight(_ new: CGFloat) {
let widthChanged = right - new
width -= widthChanged
}
func autoTop(_ new: CGFloat) {
let heightChanged = top - new
top = new
height += heightChanged
}
func autoBottom(_ new: CGFloat) {
let heightChanged = bottom - new
height -= heightChanged
}
}
请将上面代码写进项目中,方便我们在设置frame时更好的理解布局的意图,可以像我这样组织代码文件:
Hello World
下面我们在界面中显示一串Hello World,打开ViewController.swift文件编写代码:
import UIKit
class ViewController: UIViewController {
let label = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(label)
label.text = "Hello World"
label.sizeToFit()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
label.centerX = view.width / 2
label.centerY = view.height / 2
}
}
手动布局的套路就是,在viewDidLoad方法中添加子视图,在viewWillLayoutSubviews方法中设置子视图位置,在viewDidLoad方法中获取view.frame是不准确的。使用viewWillLayoutSubviews或者layoutSubviews方法需要注意的就是在UIScrollView中,滑动事件也会触发布局方法,在滑动的时候不要去设置子视图位置。
运行应用,界面中央出现了一串大大的Hello World字样。
以上就是创建一个应用,显示一个图形界面,以及自定义图形界面内容的全过程,后面的UI开发都是基于此,无非就是把ViewController换成UITabBarController,UINavigationController而已。
当前篇:iOS界面开发—开篇
下一篇:iOS界面开发—导航控制器和标签控制器