IOS APP开发中View的几种实现方式

 xib文件有以下几个重要的属性:

        xib文件名

        File’s Owner

        xib文件中的视图的Class

        xib文件中的视图的Outlet指向

File’s Owner 可以关联到某类,然后通过IBOutlet 可以提供视图中各种逻辑

自定义视图类,xib中设置布局,类中实现逻辑

test_xib.zip

纯代码实现

完全由代码实现,虽然更加灵活,但代码量会大大加大,特别是自动布局写起来很麻烦。

Xib文件

File’s Owner

File’s Owner为nil的xib(通用视图)

新建BlueView.xib, 由于它会放到其它View上作为subview,所以这儿size是Freeform, Status Bar是:None

调整大小

完成布局:

 

使用:

结论:

  • File’s Owner为nil的xib文件中的视图属于通用视图,在工程中可以复用

  • 从xib加载进来的View在父视图中的位置是不确定的,因此需要开发者自行指定

  • 视图中的所有子视图会被原封不动地Load进来

File’s Owner指定为要使用它的那个类(专用视图)

 以与上例相同的方式创建GreenView.xib

 

设置它的File's Owner

 

加载view时,方法可以更简单一些

结论:

  • File’s Owner不为nil的xib文件中的视图属于专用视图,在工程中不应该被复用

  • 只要self主动调用loadNibNamed方法,self持有的IBOutlet指向的视图就会被初始化

  • 存取xib中的视图用不着views[0]的方式,可以通过IBOutlet类型的property进行存取

File’s Owner设置为任意一个NSObject的子类 

其实这个owner不必必需是使用它的类,它可以是任何一个NSObject的子类。

比如我们可以转么定义这么一个类,所有需要关系的view都可以将Owner指向这里。

Owener 为某个特定的类:

ViewController中的使用:

结论:

  • File’s Owner类可以封装视图中的各种逻辑,而不仅仅是提供视图内容

  • 只要通过File’s Owner类主动调用loadNibNamed方法,该IBOutlet指向的视图就会被初始化

Custom Class

使用xib文件自定义了一个view,它对应的Custom Class为YellowView,YellowView是自定义的一个UIView的子类,用它来提供一些页面布局调整、业务逻辑等操作

 

为YellowView类再定义一个专用的label(File's Owner为YellowView)

 

定义一个YellowView类,当然它也可以是一个第三方插件中的定义的view,如一个进度条、一个视频播放器等等。

使用:

 

> when using loadNibNamed:owner:options:, the File's Owner should be NSObject, the main view should be your class type, and all outlets should be hooked up to the view, not the File's Owner.

 

使用xib文件实现UIViewController的View的布局

其实就是将这个File's Owner 设置为要使用它的那个viewController

 

但还要将viewController的View设置为我们定义的这个布局文件,否则在viewController在加载view时会报错

右键点击"Files's Owner", 里面有个默认的IBOutlet变量view, 看一下后面有没有做关联,如果没有就用左键拉到下面的View和视图做个关联

 

使用

使用布局文件制作一个BlackView,并定义一个BlackViewController为它提供一些逻辑实现

 

 

然后在另一个页面中使用它

可以看到 加载view的方法和前面例子中不一样

initWithNibName使用起来更方便了一些,当然它必需用在UIViewController中

 

>  initWithNibName方法 是延迟加载,UIViewController中的view只有当用到它的使用才会自动加载。而loadNibNamed方法是即时加载。

在运行中切换UIViewController的布局文件

如果需要在应用中动态切换nib文件,则可以重载下面两个属性 

override var nibName: String?{
  if Constant.InterfaceOrientation == UIInterfaceOrientationMask.portrait{
        // 锁定竖屏
        return "IndexViewP"
    }else {
        // 锁定横屏
        return "IndexViewL"
    }
}

override var nibBundle: Bundle?{
    return Bundle.main
}

 

self.window?.rootViewController = ViewController()
self.window?.makeKeyAndVisible()

  

结论:

 将xib的File’s Owner设成一个UIViewController子类,可以将这个xib文件的视图展示和外部响应事件(例如点击一个按钮触发的点击事件,该视图的手势事件等)全部封装在一个View Controller中,如果把按钮的点击事件封装在一个UIView类中,貌似破坏了MVC模式,因此最好将xib的File’s Owner设成一个UIViewController子类,该类可以通过addChildViewController方法将其添加到现有的View Controller上。如果只是希望加载视图,可以通过viewcontroller.view存取。

使用Child View Controllers

如果希望ViewController A加载并响应a XIBView中的按钮点击事件,这时必须建立一个a XIBView到ViewController A的IBAction,如果ViewController A需要拥有多个这样的XIB,那么ViewController A会变得非常的庞大,此时可以通过为每一个XIB设置一个ViewController,再让ViewController A加载这些Child View Controllers,这样可以将这些事件的响应职责和视图的描绘工作分派给专门的Child View Controller,在减小ViewController A体积的同时,也可以提高各个xib的可复用性。

 

 

总结

关于通用的布局文件

  • 如果只是单纯的界面展示,那么File’s Owner可以随意。
  • 如果其中包含了按钮、手势等用户输入事件,那么File’s Owner最好设置为UIViewController类的子类。

关于loadNibNamed方法的补充

因为 NSBundle.mainBundle().loadNibNamed("RedView", owner: redViewOwner, options: nil) 返回的是一个数组

而xib文件中是可以有多个视图控件,从xib中load出来的views数组中视图对象的排列顺序和xib scene中的对象排列顺序一致(其实就是xml文件中元素的排序而已)

 

代码手写UI

 优点:

可以专注于编码环境

版本管理时的优势,检查追踪改动以及进行代码合并相对容易一些

代码重用性,优化

缺点:

 不到运行时大家都不知道会是什么样子

 开发速度慢。相比可视化的IB来说,代码量大量增多,也就更容易出现bug

 维护时代码定位和寻找相对不方便

而相对的现在xib,StoryBoard文件的自动布局已经越来越强大了,除非有特别需求,一般情况下使用它们无疑可以极大地加快开发效率

xib, StoryBoard

技巧:

1. 在一组view层次中进行选择

按住Cmd和Shift,然后在需要选择的view上方按右键,就可以列出在点击位置上所有的view的列表

2. 添加辅助线
在左边的层级列表中双击某个view,然后Cmd+_或者Cmd+|即可在选中的view上添加一条水平或者垂直中心的辅助线。当然这个辅助线是可以随意移动的。
3. storyboard的代码操作

 

从xib中加载view的执行步骤

先调用init(coder aDecoder: NSCoder)(从xml文件中加载view),

之后调用awakeFromNib()(当.nib文件被加载的时候,会发送一个awakeFromNib的消息到.nib文件中的每个对象,每个对象都可以定义自己的awakeFromNib函数来响应这个消息,执行一些必要的操作),

然后是layoutSubviews()(只有在这里frame的值才是正确的值,所以从xib中加载view时,前两个方法里只适合创建下级view对象,只有在本方法里才能去定位下级view)

 

在自动布局中使用ScrollVIew

Storyboard中的UIScrollView使用自动布局,使其能够滚动

posted @ 2015-02-02 12:58  随心~  阅读(461)  评论(0)    收藏  举报