美文网首页
iOS界面开发—开篇

iOS界面开发—开篇

作者: 明明是个呆子 | 来源:发表于2018-02-07 11:48 被阅读0次

    当前篇:iOS界面开发—开篇
    下一篇:iOS界面开发—导航控制器和标签控制器

    前言

    本系列文章用来总结我自己做iOS开发的一些UI方面的经验,我从零开始跌跌撞撞做了三年iOS开发,能力有限,经验有限,如果有读者读到我的文章,有发现不对的地方,或者有更好的解决方法的地方,还望提出来一起讨论。

    本系列文章不对开发语言进行讲解,代码用Swift4进行展示,同时不对UIKit框架的组件进行详细讲解。

    我习惯用纯代码进行UI开发,因此文章里基本不会出现storyboard和xib,所以可能一些地方不适用于可视化界面开发,同时我很少用autolayout,我觉得手机屏幕尺寸固定有限,用代码布局妥妥的够了,也方便贴代码。

    创建工程

    首先创建一个UIStudy的工程,开发者账号及证书用你自己的就行,如果没有可以用虚拟机做测试,更改项目配置如下:

    屏幕快照 2018-02-06 上午10.36.04.png

    我们把Main Interface清空,表示不使用storyboard构建界面,现在编译应用可能会看到报错,提示safeArea在iOS 9.0之后才支持,可以把配置文件中的Deployment Target升到9.0,也可以在storyboard文件中把User Safe Area Layout Guides关掉

    278DBDD7-DA03-4314-B635-2F9DF15C15E2.png

    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时更好的理解布局的意图,可以像我这样组织代码文件:

    屏幕快照 2018-02-06 上午11.48.48.png

    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界面开发—导航控制器和标签控制器

    相关文章

      网友评论

          本文标题:iOS界面开发—开篇

          本文链接:https://www.haomeiwen.com/subject/eknwzxtx.html