• view是UIView(或其子类)的实例
  • view知道如何在界面上绘制自己
  • view是一个responder(UIView是UIResponder的子类),可以接受用户的交互,如:taps,swipes
  • view可以有多个subview,但只能有一个直接的superview
  • view的subviews会和它作为一个整体被操作(移除/隐藏/移动等)
  • view可以从nib中创建,也可以通过代码创建

The Window

  • view hierarchy的最顶层是app的window(UIWindow)
  • UIWindow是UIView的子类
  • 一个app只有一个window
  • window在app启动的时候被创建
  • window不会被销毁,也不会被替换
    • app delegate有一个window变量,对其进行强引用
  • 所有可见的views都是window的子节点
  • window必须覆盖设备的整个屏幕
    • main storyboard通过UIApplicationMain自动处理
    • 通过代码实现
      • let w = UIWindow(frame: UIScreen.mainScreen().bounds)
      • let w = UIWindow()
  • 通常不直接向window里添加view,而是获取一个view controller,然后将其赋值给window的rootViewController,这时,它的view将成为window的root view
  • window的其它views都是root view的subview
  • 直到window调用UIWindow.makeKeyAndVisible,app的界面才可见
  • window的创建、配置和显示:
    • 有main storyboard
      • 在application:didFinishLaunchingWithOptions:调用之前:
        • UIApplicationMain实例化UIWindow
          • 设置它的frame
          • 将它赋值给app delegate的window
        • 实例化storyboard的初始view controller
          • 将它赋值给window的rootViewController
      • 在application:didFinishLaunchingWithOptions:调用之后:
        • 调用window的makeKeyAndVisible
        • rootViewController自动获取它的main view
        • window将此main view设置为它的root view
    • 没有main storyboard
import UIKit
@UIApplicationMain
class AppDelegate : UIResponder, UIApplicationDelegate {
    var window : UIWindow?
    func application(application: UIApplication,
		didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
            self.window = UIWindow()
            self.window!.rootViewController = UIViewController()
            self.window!.backgroundColor = UIColor.whiteColor()
            self.window!.makeKeyAndVisible()
            return true
    }
}
  • 获取window的方法:
    • 通过UIView的window变量(如果是nil,则它一定不可见)
    • UIApplication.sharedApplication().delegate!.window!

Subview and Superview

  • 可以通过isDescendantOfView方法来判断一个view是否是另一个的subview
  • view有一个tag(数字)
  • 可以通过调用它的任一父view的viewWithTag:方法来获取它
  • addSubview使一个view成为另一个view的subview
  • removeFromSuperview将一个view从其superview的结构树中删除
  • 添加、删除subview的回调:
    • didAddSubview:, willRemoveSubview:
    • didMoveToSuperview, willMoveToSuperview:
    • disMoveToWindow, willMoveToWindow:
  • addSubview会将view放在其superview的subviews数组的最后(最后绘制,显示在最上面)
  • view的subviews是从0开始的数组,操作方法:
    • insertSubview:atIndex:
    • insertSubview:belowSubview:, insertSubview:aboveSubview:
    • exchangeSubviewAtIndex:withSubviewAtIndex:
    • bringSubviewToFront:, sendSubviewToBack:
  • 没有删除所有subviews的函数,但可以这么做:
    • myView.subviews.forEach {$0.removeFromSuperview()}

Visibility and Opacity

  • view的hidden变量控制它是否隐藏
  • view的backgroundColor变量控制它的背景色
  • 如果view的backgroundColor是nil(默认值),则它的背景透明
  • view的alpha变量控制它的背景和内容的透明度,0.0全透明,1.0完全不透明
  • view的透明度是相对于其superview的(可以理解成相对于其superview的alpha的百分比)
  • 透明和隐藏的view都不接收touch事件

Frame

  • view的frame变量(CGRect)决定它在superview中的位置、大小(使用superview的坐标系)
  • superview的坐标系的原点默认在其左上角,x轴向右,y轴向下
  • 修改view的frame会改变它的位置和大小
  • 通常在UIView的designated初始化函数init(frame:)中设置它的frame
  • view的frame默认为CGRectZero

Bounds and Center

  • view的bounds变量是它在自己的坐标系中的rectangle(方形的位置、大小)
  • 修改view的origin将移动其坐标系的原点
  • 移动superview的origin,将导致其subview向相反的方向移动同样的距离
  • view的center变量是其几何中心点在superview中的位置
  • view之间可以进行坐标转换:
    • convertPoint:fromView:, convertPoint:toView:
    • convertRect:fromView:, convertRect:toView:

Window Coordinates and Screen Coordinates

  • UIScreen的coordinateSpace
    • 它的坐标系随着app的旋转而旋转,(0.0,0.0)始终保持在app的左上角
  • UIScreen的fixedCoordinateSpace
    • 它的坐标系不会变,(0.0,0.0)始终固定在设备的左上角
  • UICoordinateSpace提供的坐标系转换函数:
    • convertPoint:fromCoordinateSpace:, convertPoint:toCoordinateSpace:
    • convertRect:fromCoordinateSpace:, convertRect:toCoordinateSpace:

Transform

  • view的transform变量改变view的绘制效果(旋转、缩放、移动等)
  • transform是CGAffineTransform类型
  • view的默认transform是CGAffineTransformIdentity,不改变显示效果
  • 对view所做的任何transform都以view的center为中心点
  • 如果view的transform不是identity的,就不要设置它的frame
  • 只有superview的transform是identity的时候,subview才会自动resizing