UIView-入门

UIView在屏幕上定义了长方形的区域,并定义了在该区域中内容的管理接口。在运行时,一个view对象能够处理在它区域内的内容以及用户交互事件。值得注意的是,控制程序的应用界面必须在主线程中完成。因此,必须在应用的主线程中调用UIView类的方法。

UIViewd的主要职责:

  1. 绘图与动画
  2. 布局和子视图管理
  3. 事件处理

绘画周期

当view首次出现,或者当layout发生改变而引起的全部or部分试图的内容出现时,系统会让view来绘制内容。若view包含使用UIKit或者Core Graphics的自定义内容时,会调用view的drawRect:方法。
当试图的实际内容发生改变时,coder有责任通知系统重新绘制内容。可以通过调用方法:① setNeedsDisplay;② setNeedsDisplayInRect: 来完成。这些方法会让系统在下一个绘制周期进行试图的更新。由于它将会等到下个绘制周期才更新视图,因此可以在多个view上调用这些方法,使得它们同时更新。

常用属性

  • @property (nonatomic, getter=isOpaque) BOOL opaque
    • 决定view是否为不透明的。这个属性提示绘画系统如何对待view,若设置为YES:绘画系统认为view是完全不透明的,如此可以优化一些绘画操作以及提高性能;若设置为NO:绘画系统将view与其他内容复合。该值默认为YES。当该值为YES时,alpha属性的设置结果是不可控的,若希望view透明,则应该将该值设置为NO。
  • @property (nonatomic) BOOL clipsToBounds
    • 该属性决定当前view的bounds是否限制它的子视图。设置为YES:导致子视图会根据receiver的bounds而修剪;设置为NO:子视图超出receiver bounds的可见部分不会被修剪,默认为NO。
  • @property (nonatomic) UIViewContentMode contentMode
    • 当bounds发生改变时,该属性决定了views如何展示它的内容。
  • @property (nonatomic) CGFloat contentScaleFactor
    • view的比例尺因子,决定了当view的内容从逻辑坐标空间到设备坐标空间映射。通常设置为1.0或2.0, 值越大,表示每个点在view中表示更多的像素。例如:如果比例尺因子为2.0,则若frame的大小为100*100,则实际展示内容的像素大小为:200 * 200。
  • @property (nonatomic, getter = isExclusiveTouch) BOOL exclusiveTouch
    • 该属性决定view是否独占处理触摸事件。当属性设置为YES时会阻塞在相同window中其他view的触摸事件,默认设置为NO。
  • @property (nonatomic) NSInteger tag
    • 在应用中唯一标示该view对象
  • @property (nonatomic, readonly, retain) CALayer *layer
    • view的核心动画层,用于绘画。
  • @property (copy, nonatomic) NSArray *motionEffects
    • view的动画效果数组
  • @property (nonatomic, getter=isMultipleTouchEnabled) BOOL multipleTouchEnabled
    • 是否允许多点触控
  • @property (nonatomic, readonly, copy) NSArray *subviews
    • view的直接子视图数组
  • @property (nonatomic, readonly) UIView *superView
    • view的父视图
  • @property (nonatomic, getter == isUserInteractionEnabled) BOOL userInteractionEnabled
    • 决定是否忽略用户事件,是否将事件从事件队列中移除。但设置为NO时:用户事件(例如:触摸或者键盘)将会被忽略,并从事件队列中移除。设置为YES:事件将会正常的传递到view。
  • @property (nonatomic, retain) UIColor *tintColor
    • 在视图层次中第一个非默认的色彩颜色值。如果系统在层次中无法找到非默认的颜色,该属性将会替换系统定义的颜色。
    • 如果view的tintAdjustmentMode设置为UIViewTintAdjustmentModeDimed,则tintColor的默认值会自动变得模糊。

常用方法


子类化重写方法

在对UIView子类化时,只有一些方法重写才有意义。由于UIView是一个高度可配置的类,因此除了override之外,有许多其他的方式实现复杂的视图行为。

初始化

  • initWithFrame
    • 实现该方法能够实现自定义初始化的操作
  • initWithCoder
    • 如果此刻从nib文件中载入视图,并需要自定义初始化操作时可以实现该方法
  • layerClass
    • 当希望view是哟高另外的核心动画层时可以重写该方法。例如:如果view使用tiling显示可滑动的大面积区域,可以重写该方法来返回CATiledLayer类。

绘画与打印

  • drawRect:
    • 如果要绘制自定义内容,则需要实现该方法。
  • drawRect:forViewPrintFormatter:
    • 只有需要在打印过程中绘制不同的视图内容时才需要实现该方法。

限制

  • requiresConstraintBasedLayout
    • 如果希望view的constraints正常工作,则需要实现该方法。
  • updateConstrains
    • 如果需要在子类之间创建自定义的constraints则需要实现该方法。
  • aligmentRectForFrame, frameForAlignmentRect
    • 实现上述两个方法能够定义当前的view与其他view的对齐方式。

布局

  • sizeThatFits
    • 如果希望view相较于正常调整大小操作而言有不同的默认大小时,可以实现该方法。例如:可以通过实现该方法避免当view缩小时子视图无法正常显示的问题。
  • layoutSubviews
    • 除了constraint和提供的自动调节大小之外,如果需要对子视图的布局更精准的控制,可以实现该方法。
  • didAddSubview:,willRemoveSubview:
    • 通过实现上述方法,能够追踪子视图的添加和移除操作
  • willMoveToSuperView:didMoveToSuperview
    • 通过实现上述方法,能够追踪当前view在试图层次中的动作。
  • willMoveToWindow:, didMoveToWindow
    • 通过实现上述方法,能够追踪当前view在另一个window中的动作。

事件处理

  • touchesBegan:withEvent:, touchesMoved:withEvent:, touchesEnded:withEvent:, touchesCancelled:withEvent:
    • 通过实现上述方法,能够直接处理触摸事件。(对于手势输入,使用gesture recognizers)
  • gestureRecongizerShouldBegin:
    • 通过实现上述方法,能够使view直接处理触摸事件,并且能够避免触发额外动作时的附加gesture recognizers。

其他

  • addConstrains:
    • 定义view和它的子视图的自动布局行为
  • autoresizingMask
    • 当父视图的frame改变时,提供自动布局行为。这些行为可以与constraints相结合。
  • contentMode
    • 为view的内容提供与view的frame相对的布局行为。该属性会影响view的内容大小如何适应view,是否缓存或重新绘制
  • contentStretch
    • 定义view可伸展的部分。该行为主要用于实现拥有复杂布局的按钮和自他可变大小视图,其中每次的重绘制会影响性能

其他方法

子视图

  • -(void)addSubview:(UIView *)view
    • 在view的子视图列表之后加入一个新的子视图(追加)。
  • -(void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview
    • 在视图层次中指定的siblingSubview之上插入一个视图。
  • -(void)insertSubview:(UIVIew *)view atIndex:(NSInteger)index
    • 在指定位置插入视图,index不能超过view中包含的子视图的个数。
  • -(void)insertSubview:(UIVIew *)view belowSubview:(UIView *)siblingSubview
    • 在视图层次中指定siblingSubview之下插入一个视图。
  • -(void)sendSubviewToBack:(UIView *)view
    • 将指定的子视图view移动到所有sibling视图的后面。例如:我们希望增加一个全屏的按钮button,单击时能够取消键盘。如果按添加的顺序,此时button在最前面,被覆盖在其下的field无法响应触控事件,调用该函数之后,button将移动到field之后,如此单击空白处时会触发button的事件。
  • -(void)bringSubViewToFront:(UIView *)view
    • 将指定的子视图移动到所有sibling视图的前面,与sendSubViewToBack:相反。
  • -(UIView *)viewWithTag:(NSInteger)tag
    • 获得当前view的层次结构中与tag相匹配的视图。该函数会搜索当前的view以及所有它的子视图。
  • -(void)exchangeSubViewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2
    • 交换子视图在view子视图列表中的位置
【注】一个子视图只能有一个superView,如果插入的子视图已经有superView了,会移除原有的superView,将superView替换成新插入到的view。

事件

  • -(BOOL)endEditing:(BOOL)fore
    • 导致视图和它嵌入的text fields取消first responder状态。fore为YES时:强制取消first responder状态;NO,非强制。返回值为YES:表明view成功取消first responder状态;NO:未成功。
  • -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
    • 返回在receiver视图层次中的最远后代中包含指定point子视图。该方法通过pointInside:withEvent:方法遍历视图层次中每一个子视图,从而决定哪个子视图应该接受触摸事件。如果pointInside:withEvent返回YES,则继续遍历子视图的层次结构找到包含指定point的最远子视图。如果view不包含point,则这个视图层次分支将会被忽略。
    • 该方法很少直接调用,一般会重写该方法来隐藏子视图的触摸事件。
  • -(void)tintColorDidChange
    • 当tintColor属性改变时会触发该方法的调用。

布局

  • -(CGSize)sizeThatFits:(CGSize) size
    • 计算适合子视图的最佳视图大小。
  • -(void)sizeToFits
    • 重新调整大小和移动receiver视图使其包含它的子视图
  • -(CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize
    • 返回满足constrants的视图大小。其中targetSize表示你是否希望符合限制的最小or最大大小。

限制(Constraints)

  • -(void)addConstraint:(NSLayoutConstraint *)constraint
    • 在receiving视图或者它的子视图布局中添加一个限制
  • -(void)addConstraints:(NSArray *)constraints
    • 在receiving视图或者它的子视图布局中添加多个限制
  • -(BOOL)needsUpdateConstraints
    • 检查视图的限制是否需要更新
  • -(void)removeConstraint:(NSLayoutConstraint *)constraint
    • 移除一个指定的限制
  • -(void)removeConstraints:(NSArray *)constraints
    • 移除多个指定的限制
  • -(void)updateConstraints
    • 如果自定义视图发现视图的某一个限制非法,需要立即移除这个限制,然后会调用setNeedsUpdateConstrains来通知constraints需要更新。在更新布局前,updateConstraints会被触发,允许当自定义视图的属性没有改变时验证view内容所有的限制
    • 【注】在实现最后一个一定要调用方法:[super updateConstraints]
  • -(void)updateConstraintsIfNeeded
    • 更新revceiving视图和子视图的限制。无论何止一个视图触发了一个新的布局,系统会调用这个方法来保证视图的constraints和它的子视图都从当前视图层次和它的constraints更新了信息。该方法由系统自动条用,也可以手动调用来检查最新的constraints。该方法不能被重写!

动画


属性

UIView完成了大部分的动画操作,但是仍然需要设置一些属性来自定义动画:
  • @property (nonatomic) frame
    • frame矩形,标书view在其父视图的坐标系统中的位置和大小。设置该属性会相应的改变center和bounds属性。
  • @property (nonatomic) CGRect bounds
    • 描述view在本身的协同系统中的位置和大小。bounds矩形代表了与view的frame矩形相同的可见部分,bounds的默认矩形设置为(0,0),通过改变bounds的值能够选择显示view的不同部分。bounds矩形的大小与frame矩形相耦合,因此改变任意一个会影响另一个。bounds大小的改变会相对于它的中心点放大或缩小。
    • 改变frame矩形会自动重新显示receiver,而不会触发drawRect:。如果希望在frame矩形改变时触发drawRect:,则需要将contentMode属性设置为UIViewContentModeRedraw
  • @property (nonatomic) center
    • 该属性表示frame的中心点。center属性指定了它的父视图的坐标系统,设置该属性会改变frame属性。
    • 该属性的改变可以动画,使用beginAnimations:context:方法开始,通过commitAnimations方法结束动画。
  • @property (nonatomic) transform
    • 相对于bounds的center,指定应用到receiver的变形。transform的原始值为center属性的值,或者如果发生改变了则为layer的anchorPoint属性。
    • 该属性的改变可以动画,使用beginAnimations:context:方法开始,通过commitAnimations方法结束动画。
  • @property (nonatomic) CGFloat alpha
    • 透明度,取值范围:[0.0, 1.0]。值越接近1.0,透明度越低。
  • @property (nonatomic, copy) backgroupColor
    • 背景颜色。该值可以通过动画设置,默认值为nil,即透明背景颜色。

方法

  • -(void)beginAnimations:(NSString *)animationId context:(void *)context
    • 标识动画块的起始位置,该方法会通知系统需要执行一个或多个特定的动画。其中,animationId是应用中动画的标识符,context中包含了与动画相关的自定义数据。
  • -(void)commitAnimations
    • 标识动画的提交位置,如果当前的动画集是离中心最远的集,则该方法会在应有返回到运行循环时启动动画。如果当前动画集嵌套在另一个动画集中,该方法会等待直到外层动画集的动画提交,然后在某一点一起提交所有动画。
  • +(void)setAnimationBeginsFromCurrentState:(BOOL)fromCurrentState
    • 设置动画是否从当前状态开始放映。设置为YES:当动画在运行时,当前view运行中的动画位置用于新动画的起始位置;设置为NO:在新动画开始之前,运行中的动画结束,即新动画使用最后的view位置作为开始状态。
    • 若当前没有运行中或者出发了一个动画块,则该方法没有任何作用。
  • +(void)setAnimationStartDate:
    • 设置当前动画快的开始时间
  • +(void)setAnimationTransition:(UIViewAnimationTransition) transition forView:(UIView *)view cache:(BOOL)cache
    • 设置view在一个动画块中的过度。transition定义:

  • +(void)setAnimationWillStartSelector:(SEL)selector
    • 当动画开始时,设置发送到动画代理的消息
  • +(void)setAnimationCurve:(UIViewAnimationCurve)curve
    • 设置当一个动画块中动画属性改变时的曲线。该方法必须在beginAnimations:contextcommitAnimations之间调用。
  • +(void)setAnimationDelay:(NSTimeInterval)delay
    • 设置动画块中动画属性改变前需要等待的时间。该方法必须在beginAnimations:contextcommitAnimations之间调用。
  • +(void)setAnimationDelegate:(id)delegate
    • 设置动画消息的代理,可以指定当动画开始或结束时希望接收消息情况下的动画代理。而delegate是一个定义使用setAnimationWillStartSelector:和setAnimationDidStopSelector:方法的注册方法。view在动画周期中维护了对该对象的强引用。
  • +(void)setAnimationDidStopSelector:(SEL)selector
    • 设置当动画结束时发送给动画代理的消息
    • selector的格式:
      • (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *context)
      • 其中finished包含一个BOOL值。YES:在停止之前动画运行完成;NO:其他情况
  • +(void)setAnimationDuration:(NSTimeInterval)duration
    • 设置一个动画块中动画的持续时间,单位为秒(seconds)。
  • +(void)setAnimationRepeatAutoreverses:(BOOL)repeatAutireverses
    • 设置一个动画块中德动画是否自动反转。如果设置autoreversing,单个动画周期在动画过程中改变的属性值会回到初始值。在动画结束时,受影响的视图会立即更新映射的新值。
    • 如果将该函数与setAnimationRepeatCount:结合,可以创建指定循环次数的动画。另外,需要记住repeat count表示完成周期的个数。
  • +(void)setAnimationRepeatCount:(float)repeatCount
    • 设置一个动画块中,动画重复的次数。

相关

在transition过程中改变view的现实

  1. 开启一个动画块
  2. 在容器view中设置transition
  3. 从容器view中移除子视图
  4. 将新的子视图移动到容器视图中
  5. 提交动画块
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值