软著登字第0220771号 登记号2010SR032498 
IdeaCMS官方交流群
  售后工单 | 帮助中心 | 购买授权
行业动态
当前位置:首页 > 最新动态 > 行业动态 > 正文

iOS UI显示

发布者:user001  来源:简书  发布时间:2015-09-09

概述

在所有拥有UI的系统开发工作中,一般开发人员最先认识的都是UI系统,这也是在自然界人们认知事物的习惯-从表及里的认知过程。

从我个人的经验出发,包括iOS,Android,Qt等完成一个App UI开发,总结来都可以从下图3个部分来完成,那么要系统地掌握一个系统UI开发过程和其中的问题,都可以从这3个方面来认知和展开。


程序UI完成步骤

这篇文章,主要探讨一下第一部分- view显示

问题和结论


view显示


如图 view显示,关于这个主题我们需要搞清楚两件事情(并给出结论):

  1. iOS界面显示到底是什么在显示?

    UIView的层级结构显示

  2. 具体是通过什么方式显示

    • 通过代码

    • nib file

    • storyboard

    • 通过UIViewController进行UIView管理并显示

    • 直接对UIWindow进行addSubView的操作(实际开发中不这么做)

解析

问题1

我们首先看看显示一个简单的“hello view”需要做哪些工作。在Xcode中创建一个Single View Application,打开Main.storyboard,在右下角的Object Library中拖一个Label到Main.storyboard的画布中(靠近左上角放置),修改Label的文字“hello view”,运行,就会看到我们想要的界面。
程序在模拟器中运行起来之后,在Xcode中选择Debug View Hierarchy,回看到如下图的app view 3d渲染: 我们可以看到实际上组成界面的是UIWindow->UIView->UILabel


view hierarchy.png

因为iOS是通过UIScreen类拿到硬件屏幕显示,所以事实上,UIWindow是添加到UIScreen上以最终显示,所以完整的结构是下图所示(撒懒网上找得图哈)


网图

问题2

window.addSubView

验证问题1所展示的例子,是使用storyboard完成的,在代码层具体做了些什么,Interface Builder替我们完成了。这一节我们来探究代码实现。
新建一个Single View Application,打开AppDelegate.swift(OC相应代码很容易参照完成),修改第一个方法如下代码示例1:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {        // Override point for customization after application launch.

        window = UIWindow(frame: UIScreen.mainScreen().bounds)
        var text = UILabel(frame: CGRectMake(20, 20, 100, 50))
        text.backgroundColor = UIColor.greenColor()
        text.text = "Hello World"
        window?.addSubview(text)
        window?.makeKeyAndVisible()        return true
    }

运行,结果如下图:


addSubView.png


可以看到,同样达到了显示一个UILabel到屏幕上的结果,我们可以删除Main.storyboard以证明是我们的代码得到了这样的结果(当然这不是必要的)。
查看注释非常容易理解上面程序做得事:

创建一个UIWindow占满整个UIScreen,然后创建了一个UILabel,把它加到UIWindow,最后把UIWindow设置为主Window并显示。

通过ViewController

通过代码

虽然这样能把UIView显示在屏幕上,并且也可以构建复杂的View hierarchy,但是这是Apple不推荐的,整个iOS开发推荐的管理界面的方法是使用ViewController。
咱们对上面的代码进行修改,把整个方法修改为如下代码示例2:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {        // Override point for customization after application launch.

        window = UIWindow(frame: UIScreen.mainScreen().bounds)
        var text = UILabel(frame: CGRectMake(20, 20, 100, 50))
        text.backgroundColor = UIColor.greenColor()
        text.text = "Hello World"
        var vc = UIViewController()
        vc.view.addSubview(text)
        window?.rootViewController = vc
        window?.makeKeyAndVisible()        return true
    }

运行程序,得到和addSubView.png一样的效果

主要的改动就是引入了UIViewController并把ViewController设置为window.rootViewController,而本来直接加入window子view的UILabel,被UIViewController的View管理起来

在现实开发中,ViewController要控制View显示的方方面面,加载,修改,布局等等,所以,代码示例2在这里创建UIViewController并进行View的组装仅仅是为了易于理解,真正的开发中,代码实现界面显示会是如下的做法:
下图是Xcode Single View Application默认的工程结构,


default project structure.png


打开ViewController.swift,覆盖loadView()方法,修改完的代码示例如下:

import UIKitclass ViewController: UIViewController {    override func viewDidLoad() {        super.viewDidLoad()        // Do any additional setup after loading the view, typically from a nib.
    }    override func didReceiveMemoryWarning() {        super.didReceiveMemoryWarning()        // Dispose of any resources that can be recreated.
    }    override func loadView() {        let v = UIView()        self.view = v        let label = UILabel(frame: CGRectMake(20, 20, 100, 50))
        label.backgroundColor = UIColor.greenColor()
        label.text = "hello world"
        v.addSubview(label)
    }
}

然后我们得修改AppDelegate的第一个方法如下代码示例:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {        // Override point for customization after application launch.

        window = UIWindow(frame: UIScreen.mainScreen().bounds)
        window?.rootViewController = ViewController()
        window?.makeKeyAndVisible()        return true
    }

运行程序,还是会得到addSubView.png一样的效果

除了代码创建UI外,iOS还提供了两种方式来所见即所得地创建UI,storyboard和nib file,两者其实都是本地化存储的iOS对象,在运行时加载组装和代码一起完成UI的构建和显示,现在storyboard是Xcode默认方式,我们从它看起。

storyboard

新建一个Single View Application,给storyboard中加入一个UILabel “hello world",然后修改AppDelegate.swift第一个方法如下代码示例:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {        // Override point for customization after application launch.

        window = UIWindow(frame: UIScreen.mainScreen().bounds)        var mainSb = UIStoryboard(name: "Main", bundle: nil)
        window?.rootViewController = mainSb.instantiateInitialViewController() as? UIViewController
        window?.makeKeyAndVisible()        return true
    }

运行工程,会得到跟没有修改AppDelegate.swift之前一样的结果。其实,这就是默认Single View Application隐性为我们做得事:

加载storyboard,从storyboard中加载initial View Controller,并把initial View Controller设置为window的rootViewController

nib file

新建一个Single View Application,新建一个User Interface -> View, 命名MainNib,创建完成会生成一个MainNib.xib。选中MainNib.xib,点击View上面的File’s Owner,然后在右侧Identity Inspector中Custom Class的Class框里填上工程生成的ViewController。再选择最右边的Connection Inspector,将Outlets下面的View拖向画布(也就是UIView),将ViewController的View和MainNib.xib中的View进行连接。拖一个“Hello World” UILabel到画布中。


add file's owner.png


connect outlets.png


然后修改AppDelegate.swift的第一个方法为如下代码:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {        // Override point for customization after application launch.

        window = UIWindow(frame: UIScreen.mainScreen().bounds)
        window?.rootViewController = ViewController(nibName: "MainNib", bundle: nil)
        window?.makeKeyAndVisible()        return true
    }

运行程序,会看到和用storyboard相同的结果。


至此,UI显示入门就告一段落。当然这里并没有深入涉及UIView的相关内容,这在以后的博客中会有所涉及。


分享到:
点击马上开始!