ios controller初始化,application,window,controller和view之间的关系

本文详细介绍了iOS中UIViewController的初始化方式,包括通过nibName和coder,以及它们与NSBundle和NSCoder的关系。同时,文章阐述了UIWindow如何包含rootViewController作为程序入口,以及Storyboard在构建界面中的作用。还提到了UIApplication对象的window数组、keyWindow和statusBarFrame,以及界面变化是由Controller的View或Layer控制的。最后,强调了在Objective-C和Swift中启动应用的主要入口点及其区别。
摘要由CSDN通过智能技术生成

1.查看一下UIViewController的源码可看到:

    public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
    public init?(coder aDecoder: NSCoder)
    
    public var view: UIView!

加上一个没有任何参数的构造器,它共有3个构造方法.上面两种是最常用的.


2.1:public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)

这个构造器,需要传一个xib文件名称和一个NSBundle对象

其中NSBundle有如下几种常用的构造器:

        NSBundle(forClass: <#T##AnyClass#>)
        NSBundle(identifier: <#T##String#>)
        NSBundle(path: <#T##String#>)
        NSBundle(URL: <#T##NSURL#>)

关于它的描述:

An NSBundle object represents a location in the file system that groups code and resources that can be used in a program. NSBundle objects locate program resources, dynamically load and unload executable code, and assist in localization. You build a bundle in Xcode using one of these project types: Application, Framework, plug-ins.

可知NSBundle对象是一个管理文件系统的一个对象,用于对文件进行查找定位的.

也就是说这个方法是通过读取本地的xib配置来构造一个controller

另外NSBundle.mainBundle()获取的是当前APP的所在目录,app之间是不能直接访问文件的参考:

http://security.ios-wiki.com/issue-2-1/


2.2:public init?(coder aDecoder: NSCoder)

NSCoder可以构造一个二进制流数据.这个类似于java的序列化和反序列化.就是把一个对象转换成二进制文件,或者把一个二进制文件转换成对象.

3.总之controller的构造跟文件有关.

/用Main.storyboard文件构造一个storyboard对象
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)

//通过storyboard和一个定义好的标识来构造一个viewcontroller对象
let initViewController: UIViewController = storyboard.instantiateViewControllerWithIdentifier(controllerId) as UIViewController

self.window?.rootViewController = initViewController

还有:

 
       let arr =  NSBundle.mainBundle().loadNibNamed("View", owner: self, options: nil)
        
        let  view = arr[0] as! MyView
        view.label.text = "hello"
        self.view.addSubview(view)

其实storyborad相当于把xib或者说nib集合在了一起.读取了一个xib就可以构造其中的视图对象,然后对视图对象进行设置.最后统一交给layer渲染.


可以知道storyboard对象就相当于一组的NSBundlue或者NSCoder,通过一个标识来取出一个来构造一个controller.

4.还可以知道window对象都包含了一个rootViewController.也就是程序入口.

controller里面都有一个view.这个里面才是放的各种界面元素.

5.可以这样描述:window中包含了一个rootcontroller,这个controller可以通过跳转到别的controller.

6.UIApplication对象中有个windows数组,一个keyWindow对象(This property holds the UIWindow object in the windows array that is most recently sent the makeKeyAndVisible message.最近发出makeKeyAndVisible消息的UIWindow)  它还包含了手机状态栏statusBarFrame,键盘等windows.这些基本都是固定的.

参考:http://www.cnblogs.com/smileevday/archive/2012/11/16/uiwindow.html

7.可以知道进行界面变化的其实是controller中的view或者layer

application.keyWindow?.layer.renderInContext(ctx: CGContext)

self.window?.rootViewController.view.layer
UILabel().layer......................

如果是用objective-c开发,则有main.m文件:

#import <UIKit/UIKit.h>
#import "AppDelegate.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}
可以知道UIApplicationMain方法中的参数之一就是AppDelegate

在swift中这个方法在UIApplication类中

public func UIApplicationMain(argc: Int32, _ argv: UnsafeMutablePointer<UnsafeMutablePointer<Int8>>, _ principalClassName: String?, _ delegateClassName: String?) -> Int32


至于程序入口为什么没有了main.swift之类的入口文件,可以参考:http://00red.com/blog/2014/11/20/swift-main-study/

http://www.devtalking.com/articles/files-and-initialization/的分析


总结:要关心的是从AppDelegate.swift之后的对象.UIApplication,UIWindow都是通过设置,比如不同的手机设备的设置来初始化.controller的关系和之中的界面是通过xib文件来

初始化的.


可以通过以下的属性和方法列表来看出以上关系:

//window 本身继承于UIView

//controller的view和view.layer,后者对UI的控制更强

//controller可以表示两个controller之间的关系

//controller可以管理容器controller和搜索controller

//controller管理着tabbaritem,navigationitem,toolbaritems


application.statusBarFrame
        application.keyWindow
        application.windows
        application.addObserver(<#T##observer: NSObject##NSObject#>, forKeyPath: <#T##String#>, options: <#T##NSKeyValueObservingOptions#>, context: <#T##UnsafeMutablePointer<Void>#>)
        
        self.window?.constraints
        self.window?.keyWindow
        self.window?.screen.bounds//no view
        self.window?.screen.traitCollection
        self.window?.backgroundColor
        self.window?.alpha
        
        self.window?.frame
        self.window?.bounds
        
        self.window?.layer.frame.size
        self.window?.layer.bounds
        
        self.window?.rootViewController?.view
        self.window?.rootViewController?.view.alpha
        self.window?.rootViewController?.view.backgroundColor
        
        self.window?.rootViewController?.view.layer.backgroundColor
        self.window?.rootViewController?.view.layer.opacity
        self.window?.rootViewController?.view.layer
        self.window?.rootViewController?.view.layer.bounds
        self.window?.rootViewController?.view.layer.frame
        self.window?.rootViewController?.view.layer.frame.height
        self.window?.rootViewController?.view.layer.frame.size
        self.window?.rootViewController?.view.layer.borderColor
        self.window?.rootViewController?.view.layer.addSublayer(<#T##layer: CALayer##CALayer#>)
        
       
        self.window?.rootViewController?.view.constraints
        self.window?.rootViewController?.view.frame
        self.window?.rootViewController?.view.frame.origin.y
        self.window?.rootViewController?.view.frame.size.height
        self.window?.rootViewController?.view.frame.midX
        
        self.window?.rootViewController?.view.frame.height
        self.window?.rootViewController?.view.gestureRecognizers
        self.window?.rootViewController?.view.bounds
        self.window?.rootViewController?.view.bounds.height
        self.window?.rootViewController?.view.alpha
        self.window?.rootViewController?.view.addSubview(<#T##view: UIView##UIView#>)
        

        self.window?.rootViewController?.topLayoutGuide.length
        self.window?.rootViewController?.bottomLayoutGuide.length
        
        self.window?.rootViewController?.parentViewController
        self.window?.rootViewController?.presentationController
        self.window?.rootViewController?.presentingViewController
        self.window?.rootViewController?.presentedViewController
        
        self.window?.rootViewController?.presentViewController(<#T##viewControllerToPresent: UIViewController##UIViewController#>, animated: <#T##Bool#>, completion: <#T##(() -> Void)?##(() -> Void)?##() -> Void#>)
        
        self.window?.rootViewController?.dismissViewControllerAnimated(<#T##flag: Bool##Bool#>, completion: <#T##(() -> Void)?##(() -> Void)?##() -> Void#>)
        
        
        self.window?.rootViewController?.tabBarController
        self.window?.rootViewController?.navigationController
        self.window?.rootViewController?.searchDisplayController
        
        self.window?.rootViewController?.tabBarItem
        self.window?.rootViewController?.tabBarItem.badgeValue
        
        self.window?.rootViewController?.navigationItem.leftBarButtonItem
        self.window?.rootViewController?.navigationItem.rightBarButtonItem
        self.window?.rootViewController?.navigationItem.setRightBarButtonItem(<#T##item: UIBarButtonItem?##UIBarButtonItem?#>, animated: <#T##Bool#>)
        self.window?.rootViewController?.navigationItem.backBarButtonItem

        self.window?.rootViewController?.searchDisplayController?.searchBar

     
        self.window?.rootViewController?.editButtonItem()
        self.window?.rootViewController?.toolbarItems


        self.window?.rootViewController?.navigationController?.navigationBar.items
        self.window?.rootViewController?.tabBarController?.tabBarItem//这里仅仅可以管理一个tabBarItem也就是rootViewController所在的项

原因是:

extension UIViewController {
    
    public var tabBarItem: UITabBarItem! // Automatically created lazily with the view controller's title if it's not set explicitly.
    
    public var tabBarController: UITabBarController? { get } // If the view controller has a tab bar controller as its ancestor, return it. Returns nil otherwise.
}

实际上tabbarcontroller类中有一个tabbar,它可以管理所有的tabbaritem


最后要说的是对于一些公共属性,作用域是不同的

比如:self.window?.tintColor = UIColor.orangeColor()将会改变整个应用的主题颜色,比如下拉框,按钮等,而某一个单独的控件如果修改了这一个属性,仅仅对它

本身有效.感觉iOS的越来越像flex,不过iOS的框架要比flex简单太多,功能似乎也更强大.



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值