UIView入门

初识UIView

UIViewUIKit中重要的一个类,iOS开发者几乎无法绕过它,因为我们的App中,看得见摸得着的UI都是UIView以及它的子类,比如UIWindow,UILabel,UIPickerView,UIProgressView,UIActivityIndicatorView,UIImageView,UITabBar,UIToolbar,UINavigationBar,UITableViewCell,UIActionSheet,UIAlertView,UIScrollView,UISearchBar,UIWebView,UIControl。既然我们绕不过去,就必须了解它。

浏览UIView

打开UIView.h文件(iOS9.1),近600行的代码,似乎彰示着这并不是个小类。当然UIView包含的功能确实不少,因为它既要负责你看得见的,又要负责你摸的着的。之前我们了解到iOS中存在着大量的UIView的子类,那岂不是个个类都是庞然大物?没错,但今天我们只看UIView

浏览UIView.h文件,里面包含了几部分声明:

  • UIView : UIResponder …
  • UIView(UIViewGeometry)
  • UIView(UIViewHierarchy)
  • UIView(UIViewRendering)
  • UIView(UIViewAnimation)
  • UIView(UIViewAnimationWithBlocks)
  • UIView (UIViewGestureRecognizers)

下面具体了解下各部分声明。

UIView(UIViewGeometry)

Strategy名称中我们可以看出些端倪,这部分基本都是与Geometry相关的。

比如,包括指示View位置的property:

@property(nonatomic) CGRect frame;

指示View渲染区域的property:

@property(nonatomic) CGRect bounds;

指示View中心位置的property:

@property(nonatomic) CGPoint center;

指示View内容刻度因子的property:

@property(nonatomic) CGFloat contentScaleFactor;

指示View变换矩阵的property:

@property(nonatomic) CGAffineTransform transform;

等等。

几个property中其他似乎都比较好理解,但是transform property有点晦涩。事实上,transform perperty 表示一个3乘3的矩阵,

a   b   0 
c   d   0
tx  ty  1    

而经过这个变换矩阵后,结果如下:

                                        a   b   0
[x'  y'  1]    =    [x   y   1]    *     c   d   0
                                        tx  ty  1

CGAffineTransform的定义也说明了这点:

struct CGAffineTransform {
  CGFloat a, b, c, d;
  CGFloat tx, ty;
};

当然,我们真正使用的时候,极少直接定义CGAffineTransform里面的字段,而是直接使用Apple提供的宏:

  • CGAffineTransformIdentity
  • CGAffineTransformMake
  • CGAffineTransformMakeTranslation
  • CGAffineTransformMakeScale

UIView(UIViewHierarchy)

同样我们从stratege的名称中,我们可以猜想到这部分与UIView的层级有关。看一下此部分包含的property:

@property(nullable, nonatomic,readonly) UIView superview;
@property(nonatomic,readonly,copy) NSArray<__kindof UIView
> subviews;
@property(nullable, nonatomic,readonly) UIWindow
window;

既然是层级关系,这里包含了指向父UIViewproperty — superview, 以及指向子UIViewproperty — subviews。这里可以确定一点,每个UIView如果在层级关系中,一定存在其父UIView,而且最多只有一个父UIView,而子UIView,可能存在多个,也可能不存在。

最后,UIWindow类型的property指向整个UIView层次结构的顶层。

UIView(UIViewRendering)

这部分中,我们重点关注下包含的方法:

>

  • - (void)drawRect:(CGRect)rect;
  • - (void)setNeedsDisplay;
  • - (void)setNeedsDisplayInRect:(CGRect)rect;

之前我们提过,UIView负责我们看到的,既然如此,视图就会在一定周期内绘制可见部分于屏幕上。当视图改变时,我们需要重绘视图以显示视图的改变。方法setNeedsDisplay以及方法setNeedsDisplayInRect:就是通知程序视图失效,需要重绘。

drawRect:方法则是用于自定义UIView子类时,覆盖该方法以绘制自定义的内容。

Other

我们并没有分析完整的UIView“纸上得来终觉浅,觉知此事要躬行”,学习UIView最好的方法,还是使用它。当然,开头的时候我们就提到,进行iOS开发,几乎不可能不使用UIView及其子类,那么,coding吧。