1、View 的创建与设置
- UIView 创建出来默认是透明的,在 iOS6 的时候是白色的。
// 实例化 view 对象,并设置 view 大小
UIView *view = [[UIView alloc] init];
// 将 view 加到 window 上显示出来
[self addSubview:view];
// 控件矩形框在父控件中的位置和尺寸,以父控件的左上角为坐标原点
view.frame = CGRectMake(10, 20, 200, 100);
// 控件矩形框的位置和尺寸,以自己左上角为坐标原点,所以 bounds 的 x、y 一般为 0
view.bounds = CGRectMake(0, 0, 200, 100);
// 设置中心位置:控件中点的位置,以父控件的左上角为坐标原点
view.center = self.center;
// 设置背景颜色
view.backgroundColor = [UIColor greenColor];
// 设置背景颜色半透明
view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
// 设置视图透明度
/*
范围:0.0 ~ 1.0 ,0.0 透明,1.0 不透明(默认)
视图上的文字等内容的透明度也同时被改变
*/
view.alpha = 1.0;
// 用于区分不同的 view ,所有继承 view 的类对象都可以设置 tag 值
view.tag = 100;
// 设置用户交互属性:YES:打开用户交互属性,NO:关闭用户交互属性
view.userInteractionEnabled = YES;
// 圆角半径
view.layer.cornerRadius = 20;
// 子图层是否剪切图层边界,默认为 NO
view.layer.masksToBounds = YES;
// 边框粗细
view.layer.borderWidth = 5;
// 边框颜色
view.layer.borderColor = [[UIColor blueColor] CGColor];
// 不允许子视图的范围超过父视图的范围
view.clipsToBounds = NO;
// 获得自己的所有子控件对象:数组元素的顺序决定着子控件的显示层级顺序(下标越大的,越显示在上面)
NSArray *subviews = view.subviews;
// 获得自己的父控件对象
UIView *superview = view.superview;
// 从父视图中移除
[view removeFromSuperview];
// 根据一个 tag 标识找出对应的控件
UIView *view = [self viewWithTag:100];
2、View 的层次设置
// 将 view 放到最上层
[self bringSubviewToFront:view];
// 将 view 放倒最下面
[self sendSubviewToBack:view];
// 位置进行交换
[self exchangeSubviewAtIndex:0 withSubviewAtIndex:2];
// 将 view1 放在 view3 上面
[self insertSubview:view1 aboveSubview:view3];
// 将 view3 放在 view2 下面
[self insertSubview:view3 belowSubview:view2];
// 将 view1 放在1的位置
[self insertSubview:view1 atIndex:1];
3、View 的旋转与缩放设置
-
3.1 单一形变
// 控件的形变属性
@property(nonatomic) CGAffineTransform transform;
// 旋转:(CGFloat angle) 旋转 45 度,需要输入的参数为弧度,45/180 * M_PI,1 度 = PI/180 弧度
self.testView.transform = CGAffineTransformMakeRotation(0.25 * M_PI);
[self.testView.layer setAffineTransform: CGAffineTransformMakeRotation(0.25 * M_PI)];
// 缩放:(CGFloat sx, CGFloat sy) (1, 2) 宽度和高度的放大倍数
self.testView.transform = CGAffineTransformMakeScale(1, 2);
[self.testView.layer setAffineTransform: CGAffineTransformMakeScale(1, 2)];
// 平移:(CGFloat tx, CGFloat ty) (100, 100) 水平和垂直方向的移动距离
self.testView.transform = CGAffineTransformMakeTranslation(100, 100);
[self.testView.layer setAffineTransform: CGAffineTransformMakeTranslation(100, 100)];
-
3.2 叠加形变
// 旋转 + 缩放
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(0.25 * M_PI);
self.testView.transform = CGAffineTransformScale(rotationTransform, 2, 2);
// 旋转 + 平移
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(0.25 * M_PI);
self.testView.transform = CGAffineTransformTranslate(rotationTransform, 200, 100);
// 缩放 + 平移
CGAffineTransform scaleTransform = CGAffineTransformMakeScale(2, 2);
self.testView.transform = CGAffineTransformTranslate(scaleTransform, 100, 100);
// 旋转 + 缩放 + 平移
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(0.25 * M_PI);
CGAffineTransform rotationScaleTransform = CGAffineTransformScale(rotationTransform, 2, 2);
self.testView.transform = CGAffineTransformTranslate(rotationScaleTransform, 200, 100);
-
3.3 累加形变
// 连续旋转
self.testView.transform = CGAffineTransformRotate(self.testView.transform, 0.25 * M_PI);
// 连续缩放
self.testView.transform = CGAffineTransformScale(self.testView.transform, 2, 2);
// 连续平移
self.testView.transform = CGAffineTransformTranslate(self.testView.transform, 100, 100);
// 还原所有形变
self.testView.transform = CGAffineTransformIdentity;
[self.testView.layer setAffineTransform:CGAffineTransformIdentity];
4、View 的跟随模式设置
// 父视图设置
// 父视图允许子视图跟随:default is YES
fatherView.autoresizesSubviews = YES;
// 子视图设置
/*
UIViewAutoresizingNone = 0, // 不跟随
UIViewAutoresizingFlexibleLeftMargin = 1 << 0, // 左边距 随父视图变化
UIViewAutoresizingFlexibleRightMargin = 1 << 2, // 右边距 随父视图变化
UIViewAutoresizingFlexibleTopMargin = 1 << 3, // 上边距 随父视图变化
UIViewAutoresizingFlexibleBottomMargin = 1 << 5 // 下边距 随父视图变化
UIViewAutoresizingFlexibleWidth = 1 << 1, // 宽度 随父视图变化
UIViewAutoresizingFlexibleHeight = 1 << 4, // 高度 随父视图变化
*/
sonView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
5、View 的动画设置
-
-
5.1 block 方式
- 设置控件位置、尺寸、透明度等的代码,放在 animateWithDuration: block 中,将自动以动画的方式改变。
// 移动时间 2 秒
[UIView animateWithDuration:2 animations:^{
// 改变控件的位置和尺寸,改变后的位置或大小
view.frame = CGRectMake([UIScreen mainScreen].bounds.size.width - 60, 20, 50, 50);
} completion:^(BOOL finished) {
// 上一个设置完成后
[UIView animateWithDuration:2 animations:^{
// 改变控件的位置和尺寸,改变后的位置或大小
view.frame = CGRectMake(10, [UIScreen mainScreen].bounds.size.height - 110, 100, 100);
}];
}];
-
5.2 动画块方式
- 设置控件位置、尺寸、透明度等的代码,放在 beginAnimations: 和 commitAnimations 之间,将自动以动画的方式改变。
// 开始一个动画块
[UIView beginAnimations:nil context:nil];
// 动画设置
// 设置动画时间:default = 0.2
[UIView setAnimationDuration:2.0];
// 设置延时:设置指定的时间后开始执行动画,default = 0.0
[UIView setAnimationDelay:1.0];
// 设置动画开始执行时间:default = now ([NSDate date])
[UIView setAnimationStartDate:[NSDate dateWithTimeIntervalSinceNow:10]];
// 设置动画执行节奏
/*
UIViewAnimationCurveEaseInOut, // slow at beginning and end 开始喝结束慢速,默认
UIViewAnimationCurveEaseIn, // slow at beginning 开始慢速
UIViewAnimationCurveEaseOut, // slow at end 结束慢速
UIViewAnimationCurveLinear // 匀速
*/
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
// 设置重复次数:default = 0.0. May be fractional
[UIView setAnimationRepeatCount:CGFLOAT_MAX];
// 设置是否自动返回:default = NO. used if repeat count is non-zero
[UIView setAnimationRepeatAutoreverses:YES];
// 设置是否从当前状态开始动画:default = NO
[UIView setAnimationBeginsFromCurrentState:YES];
// 设置代理:default = nil
[UIView setAnimationDelegate:self];
// 设置动画开始时执行的代理方法,自定义方法:default = NULL
[UIView setAnimationWillStartSelector:@selector(startAnimations)];
// 设置动画结束时执行的代理方法,自定义方法:default = NULL
[UIView setAnimationDidStopSelector:@selector(stopAnimations)];
// 动画之行后效果
// 设置透明度,改变后的透明度
view.alpha = 0.0;
// 改变控件的位置和尺寸,改变后的位置或大小
view.center = CGPointMake(250, 250);
view.frame = CGRectMake(100, 180, 50, 50);
// 结束一个动画块
[UIView commitAnimations];
6、frame 与 NSValue 的相互转换
// Frame 转 NSValue
NSValue *freamValue = [NSValue valueWithCGRect:frame];
// NSValue 转 Frame
frame = [freamValue CGRectValue];
7、系统api详细说明
// 含义:获取UIView的layer层类型。默认的UIView的layer层类型为CALayer。
// 示例:使用自定义的layer类型来绘制自定义视图。
@property(class, nonatomic, readonly) Class layerClass;
// 含义:控制用户是否可以交互。如果将此属性设置为NO,那么用户无法与该视图进行交互。
// 示例:将某个视图设置为不可交互,防止用户误操作。
@property(nonatomic, getter=isUserInteractionEnabled) BOOL userInteractionEnabled;
// 含义:为视图分配一个整型的标记。可以通过这个标记来区分视图。
// 示例:使用tag属性来定位特定的视图。
@property(nonatomic) NSInteger tag;
// 含义:返回与UIView关联的CALayer对象。UIView的大部分绘制都是通过CALayer实现的。
// 示例:对UIView添加动画效果。
@property(nonatomic, readonly, strong) CALayer *layer;
// 含义:判断UIView是否可以成为focus。
// 示例:使用这个属性来快速判断哪些视图可以被选中。
@property(nonatomic, readonly) BOOL canBecomeFocused;
// 含义:判断UIView是否处于focus状态。
// 示例:使用这个属性来判断当前哪个视图处于focus状态,来做一些响应。
@property(nonatomic, readonly, getter=isFocused) BOOL focused;
// 含义:为UIView分配一个focus组,该组名由字符串指定。
// 示例:将多个视图分组,以便在focus环节中导航。
@property(nonatomic, readwrite, nullable, copy) NSString *focusGroupIdentifier;
// 含义:设置focus组的优先级,数值越大,优先级越高。
// 示例:在focus环节中,在多个组中决定哪个组的视图可以被优先选择。
@property(nonatomic, readwrite) UIFocusGroupPriority focusGroupPriority;
// 含义:设置focus过程中的视觉效果。
// 示例:在focus环节中,为视图添加特效。
@property(nonatomic, readwrite, nullable, copy) UIFocusEffect *focusEffect;
// 含义:设置视图的语言识别方式。
// 示例:将页面上的文字和图标等都转换为特定语言和文化习俗。
@property(nonatomic) UISemanticContentAttribute semanticContentAttribute;
// 含义:获取UIView所处的方向。
// 示例:在国际化项目中,动态适配不同语言和文化习俗。
@property(nonatomic, readonly) UIUserInterfaceLayoutDirection effectiveUserInterfaceLayoutDirection;
// 这个方法用于初始化UIView的frame属性,即设置UIView的大小、位置等属性。
- (instancetype)initWithFrame:(CGRect)frame;
// 这个方法用于从xib或storyboard中加载UIView。
- (nullable instancetype)initWithCoder:(NSCoder *)coder;
// 这个方法根据传入的语义内容属性来返回当前用户界面的布局方向。可以用于根据界面语言不同来调整界面布局。例如,对于从左到右的语言,可以使用以下代码来控制UIView的布局方向为从左到右:
+ (UIUserInterfaceLayoutDirection)userInterfaceLayoutDirectionForSemanticContentAttribute:(UISemanticContentAttribute)attribute;
// 这个方法根据传入的语义内容属性和视图布局方向来返回确定的UI用户界面的布局方向。可以用于在特定语言环境下显式地控制UIView布局方向。
+ (UIUserInterfaceLayoutDirection)userInterfaceLayoutDirectionForSemanticContentAttribute:(UISemanticContentAttribute)semanticContentAttribute relativeToLayoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection;
// 例如,可以使用以下代码根据语言环境来控制整个应用程序用户界面布局方向:
if ([UIApplication.sharedApplication.preferredLanguages.firstObject containsString:@"ar"]) { // 判断是否为阿拉伯语言
[UIView userInterfaceLayoutDirectionForSemanticContentAttribute:UISemanticContentAttributeForceRightToLeft relativeToLayoutDirection:UIUserInterfaceLayoutDirectionLeftToRight];
}
// 该属性表示视图在父视图坐标系中的位置和尺寸,其中包含了视图的起点坐标(origin)和视图的尺寸(size)。
@property(nonatomic) CGRect frame;
// 该属性表示视图自身坐标系中的位置和尺寸,其中包含了视图的起点坐标(origin)和视图的尺寸(size)。
@property(nonatomic) CGRect bounds;
// 该属性表示视图的中心点在父视图坐标系中的位置。
@property(nonatomic) CGPoint center;
// 该属性表示视图的仿射变换(Affine Transform),可以实现视图的旋转、缩放、平移等操作。
@property(nonatomic) CGAffineTransform transform;
// 该属性表示视图的三维变换(CATransform3D),可以实现视图在三维空间中的旋转、缩放、平移等操作。
@property(nonatomic) CATransform3D transform3D;
// 该属性表示视图的内容缩放比例,在Retina屏幕中,该值为2.0,在非Retina屏幕中,该值为1.0。
@property(nonatomic) CGFloat contentScaleFactor;
// 该属性表示视图是否支持多点触控。
@property(nonatomic, getter=isMultipleTouchEnabled) BOOL multipleTouchEnabled;
// 该属性表示视图是否独占触摸事件,即在该视图上触摸时,其他视图无法响应触摸事件。
@property(nonatomic, getter=isExclusiveTouch) BOOL exclusiveTouch;
// 该属性表示视图的子视图是否自动适应父视图的尺寸变化。
@property(nonatomic) BOOL autoresizesSubviews;
// 该属性表示视图与父视图之间的自动调整行为,包括宽度和高度的自动调整、位置的自动调整等。
@property(nonatomic) UIViewAutoresizing autoresizingMask;
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;
// 这个方法用于获取响应事件的视图,通常在处理事件响应时会用到。该方法会遍历视图层级结构,从最外层父视图开始逐层寻找响应事件的视图,一旦找到就返回该视图,否则返回nil。
// 被遍历的顺序是视图层级结构的反向,即从最后一个子视图往上遍历。如果子视图中有重叠或者嵌套关系,hitTest返回的是最上层的可响应视图。示例代码:
// point为触摸点坐标,event为触摸事件
UIView *hitTestView = [self.view hitTest:point withEvent:event];
- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;
// 这个方法用于判断某个点是否在视图的范围内,通常在处理事件响应时也会用到。该方法需要重写才能生效,如果没有重写,默认所有点都在视图范围内。示例代码:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
if (CGRectContainsPoint(self.bounds, point)) {
return YES;
}
return NO;
}
- (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;
// 这个方法用于将视图上的坐标系转换为另一个视图的坐标系,通常在视图布局或动画中会用到。例如,将一个视图上的坐标转换为另一个视图上的坐标,或者将屏幕上的坐标转换为视图上的坐标。示例代码:
CGPoint convertPoint = [self.view convertPoint:self.button.frame.origin toView:self.label];
- (CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view;
// 这个方法与上一个方法相反,用于将另一个视图坐标系中的点转换为当前视图坐标系中的点。示例代码:
CGPoint convertPoint = [self.view convertPoint:self.label.frame.origin fromView:self.button];
- (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;
// 这个方法将视图上的矩形区域转换为另一个视图上的矩形区域。通常应用于视图层级结构中不同的视图之间的布局,以便确定它们之间的关系。示例代码:
CGRect convertRect = [self.view convertRect:self.button.frame toView:self.label];
- (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;
// 这个方法与上一个方法相反,用于将另一个视图的矩形区域转换为当前视图的矩形区域。示例代码:
CGRect convertRect = [self.view convertRect:self.label.frame fromView:self.button];
- (CGSize)sizeThatFits:(CGSize)size;
// 这个方法用于计算视图的最合适大小。可以通过给定一个大小作为参数,获得视图最适合的大小。此方法适用于根据其内容动态调整视图大小的视图,例如UILabel、UITextView等。示例代码:
// 水平和垂直方向上都没有限制
CGSize size = [self.label sizeThatFits:CGSizeMake(MAXFLOAT, MAXFLOAT)];
- (void)sizeToFit;
// 这个方法也是计算视图的最合适大小,但它会直接修改视图的尺寸。在调用该方法之后,视图的大小会根据其内容自动调整。此方法适用于根据其内容动态调整视图大小的视图,例如UILabel、UITextView等。示例代码:
[self.label sizeToFit];
// 该属性表示当前UIView所在的父视图。例如,当一个UIView作为另一个UIView的子视图时,父视图属性superview值为该UIView的父视图。
// 使用场景:当需要在UIView中获取当前父视图信息时,可使用该属性。
@property(nullable, nonatomic, readonly) UIView *superview;
// 该属性表示当前UIView的所有子视图。
// 使用场景:当需要在UIView中获取当前所有子视图信息时,可使用该属性。
@property(nonatomic, readonly, copy) NSArray<__kindof UIView *> *subviews;
// 该属性表示当前UIView所在的UIWindow。例如,当一个UIView添加到UIWindow上时,该属性值为该UIWindow。
// 使用场景:当需要在UIView中获取当前所在的UIWindow信息时,可使用该属性。
@property(nullable, nonatomic, readonly) UIWindow *window;
// 该属性表示UIView的布局边距。UIView的位置和尺寸可以相对于这些边距进行布局。
// 使用场景:当需要通过调整UIView的布局边距来调整UIView的位置和尺寸时,可使用该属性。
@property(nonatomic) UIEdgeInsets layoutMargins;
// 该属性表示UIView的方向性布局边距。与layoutMargins相似,方向性布局边距是相对于UIView的位置和尺寸进行布局的。
// 使用场景:当需要进行复杂的方向性布局时,可使用该属性。
@property(nonatomic) NSDirectionalEdgeInsets directionalLayoutMargins;
// 该属性表示当前UIView是否保留它的父视图的布局边距。一旦设置了该选项,UIView的布局边距将会与其父视图的布局边距相同。
// 使用场景:当需要使一个UIView的布局边距与其父视图的布局边距相同时,可使用该属性。
@property(nonatomic) BOOL preservesSuperviewLayoutMargins;
// 该属性表示当前UIView是否从安全区域中获取布局边距。当该选项开启时,布局边距被设置为从安全区域中获取的布局边距。
// 使用场景:当需要使UIView从安全区域中获取布局边距时,可使用该属性。
@property(nonatomic) BOOL insetsLayoutMarginsFromSafeArea;
// 该属性表示UIView的安全区域内的布局边距。
// 使用场景:当需要获取UIView的安全区域内的布局边距信息时,可使用该属性。
@property(nonatomic, readonly) UIEdgeInsets safeAreaInsets;
// 该属性表示UIView的布局边距指南。指南是用于约束UIView的布局元素。
// 使用场景:当需要使用指南对UIView进行布局时,可使用该属性。
@property(readonly, strong) UILayoutGuide *layoutMarginsGuide;
// 该属性表示UIView用于放置可读内容的指南。例如,UILabel或UITextView的内容可以使用Readable Content指南进行布局,以确保其易于阅读。
// 使用场景:当需要使用指南布局可读内容时,可使用该属性。
@property(nonatomic, readonly, strong) UILayoutGuide *readableContentGuide;
// 该属性表示UIView的安全区域布局指南。指南是用于约束UIView的布局元素。
// 使用场景:当需要使用指南对UIView的安全区域进行布局时,可使用该属性。
@property(nonatomic, readonly, strong) UILayoutGuide *safeAreaLayoutGuide;
// 该属性表示UIView的键盘布局指南。键盘布局指南可用于约束UIView的布局元素与键盘交互。
// 使用场景:当需要优化UIView与键盘交互时,可使用该属性。
@property(nonatomic, readonly, strong) UIKeyboardLayoutGuide *keyboardLayoutGuide;
// 将当前UIView从其父视图中移除。
// 示例:当某个视图不再需要显示或需要将视图添加到其他父视图时,可以使用此方法将其从当前父视图中移除。
- (void)removeFromSuperview;
// 将指定的UIView插入到当前UIView的指定位置。
// 示例:当需要将一个视图插入到当前视图的某个指定位置时,可以使用此方法。
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;
// 交换指定位置处的两个UIView。
// 示例:当需要交换两个视图在当前视图中的位置时,可以使用此方法。
- (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2;
// 将指定的UIView添加到当前UIView中作为子视图。
// 示例:当需要将一个视图以子视图的形式添加到当前视图中时,可以使用此方法。
- (void)addSubview:(UIView *)view;
// 将指定UIView插入到指定UIView的下面。
// 示例:当需要将指定的UIView插入到当前UIView中某个指定位置下面时,可以使用此方法。
- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;
// 将指定UIView插入到指定UIView的上面。
// 示例:当需要将指定的UIView插入到当前UIView中某个指定位置上面时,可以使用此方法。
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;
// 将指定UIView带到当前UIView的最前面。
// 示例:当需要将指定的UIView带到当前UIView最前面以进行前景展示时,可以使用此方法。
- (void)bringSubviewToFront:(UIView *)view;
// 将指定UIView发送到当前UIView的后面。
// 示例:当需要将指定的UIView发送到当前UIView的后面以进行背景展示时,可以使用此方法。
- (void)sendSubviewToBack:(UIView *)view;
// 子视图添加到父视图后调用此方法。
// 示例:当需要在子视图完成添加到父视图后进行后续操作时,可以重写此方法。
- (void)didAddSubview:(UIView *)subview;
// 即将从父视图中移除子视图时调用此方法。
// 示例:当需要在子视图即将从父视图中移除时进行后续操作时,可以重写此方法。
- (void)willRemoveSubview:(UIView *)subview;
// 将要移动到新的父视图时调用此方法。
// 示例:当需要在当前UIView即将添加到新的父视图之前进行后续操作时,可以重写此方法。
- (void)willMoveToSuperview:(nullable UIView *)newSuperview;
// 当UIView添加到父视图后调用此方法。
// 示例:当需要在当前UIView添加到父视图之后进行后续操作时,可以重写此方法。
- (void)didMoveToSuperview;
// 将要移动到新的UIWindow时调用此方法。
// 示例:当需要在当前UIView即将添加到新的UIWindow之前进行后续操作时,可以重写此方法。
- (void)willMoveToWindow:(nullable UIWindow *)newWindow;
// 当UIView添加到UIWindow后调用此方法。
// 示例:当需要在当前UIView添加到UIWindow之后进行后续操作时,可以重写此方法。
- (void)didMoveToWindow;
// 判断当前UIView是否为指定UIView的子类。
// 示例:当需要判断当前UIView是否为某个指定UIView的子类时,可以使用此方法。
- (BOOL)isDescendantOfView:(UIView *)view;
// 在当前UIView及其所有子视图中搜索指定标记Tag的UIView。
// 示例:当需要寻找当前UIView及其所有子视图中指定标记Tag的UIView时,可以使用此方法。
- (nullable __kindof UIView *)viewWithTag:(NSInteger)tag;
// 当前UIView的布局失效,标记为需要更新布局。
// 示例:当需要在当前UIView中更新布局时,可以使用此方法。
- (void)setNeedsLayout;
// 立即更新布局。
// 示例:当需要当前UIView立即更新布局时,可以使用此方法。
- (void)layoutIfNeeded;
// 更新子视图布局。
// 示例:当需要在当前UIView中更新子视图的布局时,可以重写此方法。
- (void)layoutSubviews;
// 当视图的layoutMargins属性发生更改时调用此方法。
// 示例:当需要在当前UIView的layoutMargins属性发生更改时进行后续操作时,可以重写此方法。
- (void)layoutMarginsDidChange;
// 当视图的安全边距发生更改时调用此方法。
// 示例:当需要在当前UIView的安全边距发生更改时进行后续操作时,可以重写此方法。
- (void)safeAreaInsetsDidChange;
// 含义:是否裁剪超出视图边界的子视图。
// 使用场景:当 UIView 的子视图超出视图边界时,设置 clipsToBounds 为 YES 可以实现超出部分的裁剪,常用于图片和文字的裁剪。
@property(nonatomic) BOOL clipsToBounds;
// 含义:视图的背景颜色。
// 使用场景:在创建 UIView 的时候,可以设置其背景颜色,常用于 UI 布局中的背景填充。
@property(nullable, nonatomic, copy) UIColor *backgroundColor;
// 含义:视图的透明度。
// 使用场景:设置视图的透明度可以实现淡入淡出的效果,常用于视图切换和动画效果。
@property(nonatomic) CGFloat alpha;
// 含义:视图是否不透明。
// 使用场景:设置视图的不透明度可以提高视图的显示效率,常用于处理视图层次结构时,提高整个视图组的渲染效率。
@property(nonatomic, getter=isOpaque) BOOL opaque;
// 含义:是否在视图绘制之前清除上下文。
// 使用场景:设置视图的清除行为可以提高整个视图组的渲染效率,常用于处理动态变化的视图组。
@property(nonatomic) BOOL clearsContextBeforeDrawing;
// 含义:视图是否隐藏。
// 使用场景:设置视图的隐藏状态可以控制视图组的显示和隐藏,常用于处理视图的显示效果。
@property(nonatomic, getter=isHidden) BOOL hidden;
// 含义:视图内容的显示模式。
// 使用场景:设置视图的显示模式可以控制视图的放大缩小效果,常用于图片、视频等内容的调整。
@property(nonatomic) UIViewContentMode contentMode;
// 含义:使用另一个视图作为当前视图的遮罩。
// 使用场景:设置 maskView 为遮罩视图可以实现不同形状的视图显示效果,常用于圆形图片和可点击区域的实现。
@property(nullable, nonatomic, strong) UIView *maskView;
// 含义:视图的 tint 颜色。
// 使用场景:设置视图的 tint 颜色可以提高视觉效果,常用于图标和按钮的调整。
@property(null_resettable, nonatomic, strong) UIColor *tintColor;
// 含义:视图 tint 的自动调整模式。
// 使用场景:设置 tintAdjustmentMode 可以控制视图 tint 的自动调整行为,常用于实现深色和浅色主题切换。
@property(nonatomic) UIViewTintAdjustmentMode tintAdjustmentMode;
// 这个方法用于绘制`UIView`的内容,每当需要绘制该视图时,系统都会调用此方法。
// 在这个方法中,我们可以使用`Core Graphics`或`UIKit`提供的绘制方法进行绘制。
// 一般来讲,我们不建议手动调用此方法,而是让系统在需要的时候自动调用。
// 常见的用法是在继承`UIView`的自定义视图中重写此方法并通过`setNeedsDisplay`方法来触发绘制行为。
- (void)drawRect:(CGRect)rect;
// 当调用此方法时,系统会在下一个绘制周期中调用`drawRect:`方法,并重新绘制视图。
// 这个方法用于标记视图需要进行重绘的时候,我们可以在`UIView`的子类中使用此方法来触发重绘。
- (void)setNeedsDisplay;
// 这个方法与`setNeedsDisplay`方法类似,不同的是它只会刷新视图上指定区域的内容而不是整个视图。
// 当需要在大视图中修改某个小区域的内容时,可以使用这个方法将需要重新绘制的区域标记出来,以避免不必要的性能损耗。
- (void)setNeedsDisplayInRect:(CGRect)rect;
// 这个方法用于监听`UIView`的`tintColor`属性是否变化。当`tintColor`属性的值发生变化时,系统会自动调用该方法。通常情况下,我们不需要手动调用此方法。
// 这个方法的主要作用是在`tintColor`改变时对视图进行相应的配置,例如改变视图内部的颜色等。
- (void)tintColorDidChange;
// 该属性表示当前视图是否启用了动画效果。
// 举例说明:在修改某个视图的 frame 属性时,如果想要禁用该视图的动画效果,可以先将 areAnimationsEnabled 属性设置为 NO,然后再修改该视图的 frame 属性,最后再将 areAnimationsEnabled 属性设置为 YES。
// 这样做可以确保在修改视图的 frame 属性时不会产生动画效果。
@property(class, nonatomic, readonly) BOOL areAnimationsEnabled;
// 该属性表示当前视图继承自父视图的动画持续时间。
// 如果当前视图没有设置自己的动画持续时间,且父视图设置了动画持续时间,则当前视图的动画持续时间等于父视图的动画持续时间;
// 如果父视图也没有设置自己的动画持续时间,则当前视图的动画持续时间为默认值 0.25 秒。
@property(class, nonatomic, readonly) NSTimeInterval inheritedAnimationDuration;
// 该方法的作用是开启或关闭UIView的动画效果,默认是开启状态。
// 开启动画效果可以让用户在执行交互操作时能够感知到视图的变化,但是在某些情况下关闭动画效果可以提高程序的性能。
// 例子:如果一个视图的布局非常复杂,而用户在执行某些操作时需要频繁刷新该视图,可以在需要刷新的时候暂时关闭动画效果,提高刷新速度。
+ (void)setAnimationsEnabled:(BOOL)enabled;
// 该方法的作用是在不执行UIView的动画效果的情况下执行一个动作,即使设置了动画效果也会被忽略。
// 该方法可以避免一些场景下因为视图变化导致的闪烁等问题。
// 例子:在某些情况下,我们需要立即改变一个视图的状态,但是由于视图比较复杂或者需要加载一些数据时,这个状态的改变不可避免地会带来一些视觉上的变化,这时可以使用该方法,让改变的过程立即生效,避免闪烁等问题。
+ (void)performWithoutAnimation:(void (NS_NOESCAPE ^)(void))actionsWithoutAnimation;
// 作用:执行带有选项和完成处理程序的基本动画。
// 使用场景:可以用于视图的渐变、缩放、移动、旋转等基本动画,如在视图中添加弹簧效果、淡入淡出效果等。
+ (void)animateWithDuration:(NSTimeInterval)duration
delay:(NSTimeInterval)delay
options:(UIViewAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^ __nullable)(BOOL finished))completion;
// 作用:执行基本动画。
// 使用场景:常用于视图的简单动画,如移动、旋转、缩放等。
+ (void)animateWithDuration:(NSTimeInterval)duration
animations:(void (^)(void))animations
completion:(void (^ __nullable)(BOOL finished))completion;
// 作用:执行基本动画。
// 使用场景:常用于视图的简单动画,如移动、旋转、缩放等。
+ (void)animateWithDuration:(NSTimeInterval)duration
animations:(void (^)(void))animations;
// 作用:执行带有弹簧效果、选项和完成处理程序的动画。
// 使用场景:当需要视图具有弹簧效果,如发生震动、跳动等效果时,可以使用该方法。
+ (void)animateWithDuration:(NSTimeInterval)duration
delay:(NSTimeInterval)delay
usingSpringWithDamping:(CGFloat)dampingRatio
initialSpringVelocity:(CGFloat)velocity
options:(UIViewAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^ __nullable)(BOOL finished))completion;
// 作用:设置将视图添加到屏幕上的动画效果。
// 使用场景:常用于视图的转换效果,如将一个视图移动到另一个视图上时,可以使用该方法实现平滑的过渡动画。
+ (void)transitionWithView:(UIView *)view
duration:(NSTimeInterval)duration
options:(UIViewAnimationOptions)options
animations:(void (^ __nullable)(void))animations
completion:(void (^ __nullable)(BOOL finished))completion;
// 作用:从一个视图转换到另一个视图时添加动画效果。
// 使用场景:在视图之间切换时,可以使用该方法实现平滑的过渡动画。
+ (void)transitionFromView:(UIView *)fromView
toView:(UIView *)toView
duration:(NSTimeInterval)duration
options:(UIViewAnimationOptions)options
completion:(void (^ __nullable)(BOOL finished))completion;
// 作用:在一些系统动画过程中,为视图添加一个动画效果。
// 使用场景:系统级别的一些动画效果,如应用程序在后台进入后台状态、横竖屏切换时等。
+ (void)performSystemAnimation:(UISystemAnimation)animation
onViews:(NSArray<__kindof UIView *> *)views
options:(UIViewAnimationOptions)options
animations:(void (^ __nullable)(void))parallelAnimations
completion:(void (^ __nullable)(BOOL finished))completion;
// 作用:可以在动画中悬停,反转和重复特定的动画效果。
// 使用场景:可以在视图的过渡动画、弹簧效果等过程中添加动画效果,提供更好的用户交互体验。
+ (void)modifyAnimationsWithRepeatCount:(CGFloat)count
autoreverses:(BOOL)autoreverses
animations:(void(NS_NOESCAPE ^)(void))animations;
// 这是一个UIView的类方法,用来进行关键帧动画的设置和执行。其参数包括动画时长,延迟时间,动画选项,动画代码块以及完成回调。使用场景包括以下几种:
// 对于一些比较复杂的动画效果,需要按照某种特定的时间轴进行分步骤执行,使用关键帧动画可以更自由地控制不同部分的动画效果。
// 需要对同一个控件进行多个不同的动画效果,使用关键帧动画可以更方便地设置多个动画效果。
// 需要在动画执行完成后进行一些操作,比如刷新数据、更新界面等。使用完成回调可以更方便地实现这些操作。
+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration
delay:(NSTimeInterval)delay
options:(UIViewKeyframeAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^ __nullable)(BOOL finished))completion;
// 这是UIView中关键帧动画的一个设置方法,用来设置每一个关键帧的开始时间、持续时间以及动画代码块。使用场景包括以下几种:
// 针对每一个关键帧需要控制不同的动画效果,可以在每个关键帧中设置不同的代码块。
// 一个复杂的动画效果需要多个关键帧来进行控制,可以使用该方法来分别设置每一个关键帧的代码块。
+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime
relativeDuration:(double)frameDuration
animations:(void (^)(void))animations;
// 表示UIView中添加的手势识别器的数组,类型为UIGestureRecognizer。
@property(nullable, nonatomic, copy) NSArray<__kindof UIGestureRecognizer *> *gestureRecognizers;
// 添加手势识别器到UIView中,使UIView能够响应特定的手势。
- (void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer;
// 从UIView中删除一个手势识别器,停止该手势与UIView的交互。例如,当我们在某个UIView中添加了一个旋转手势,并且当用户结束旋转时我们不再需要该手势时,我们可以通过该方法将手势识别器从UIView中删除。
- (void)removeGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer;
// 该方法是一个手势识别器的代理方法,用于决定一个特定手势是否应该开始。
// 例如,当我们想限制某个UIView上所有手势的触发范围,我们可以在该方法中添加限制条件,例如只有当手指触摸的区域在UIView的某个子视图范围内时才开始识别手势。
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
// 该属性表示视图的运动效果数组,以 UIMotionEffect 对象的形式存储,用于在视图的移动或者旋转时添加动态效果。
@property (copy, nonatomic) NSArray<__kindof UIMotionEffect *> *motionEffects;
- (void)addMotionEffect:(UIMotionEffect *)effect;
// 这个方法是用来给UIView添加运动效果的,可以使得视觉效果更加生动。这个方法需要传入一个UIMotionEffect参数,代表要添加的运动效果。常见的运动效果有两种:UIInterpolatingMotionEffect和UIParallaxMotionEffect。
// 举个例子,假设我们有一个UIImageView,我们可以给它添加一个UIInterpolatingMotionEffect运动效果,使得它能根据设备的方向来变换透视角度。代码如下:
UIInterpolatingMotionEffect *motionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"layer.transform" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
motionEffect.minimumRelativeValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-0.1, 0, 1, 0)];
motionEffect.maximumRelativeValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(0.1, 0, 1, 0)];
[imageView addMotionEffect:motionEffect];
- (void)removeMotionEffect:(UIMotionEffect *)effect;
// 这个方法是用来移除UIView上的指定运动效果的。我们可以使用这个方法从UIView上移除一个已经添加的运动效果。这个方法需要传入一个UIMotionEffect参数,代表要移除的运动效果。
// 举个例子,假设我们已经给UIImageView添加了一个UIInterpolatingMotionEffect运动效果,现在想要把它移除,可以使用如下代码:
UIInterpolatingMotionEffect *motionEffect = /* 获取已经添加的运动效果 */;
[imageView removeMotionEffect:motionEffect];
@interface UIView (UIConstraintBasedLayoutCoreMethods)
- (void)updateConstraintsIfNeeded;
- (void)updateConstraints NS_REQUIRES_SUPER;
- (BOOL)needsUpdateConstraints;
- (void)setNeedsUpdateConstraints;
@end
@interface UIView (UIConstraintBasedCompatibility)
@property(nonatomic) BOOL translatesAutoresizingMaskIntoConstraints;
@property(class, nonatomic, readonly) BOOL requiresConstraintBasedLayout;
@end
@interface UIView (UIConstraintBasedLayoutLayering)
- (CGRect)alignmentRectForFrame:(CGRect)frame;
- (CGRect)frameForAlignmentRect:(CGRect)alignmentRect;
@property(nonatomic, readonly) UIEdgeInsets alignmentRectInsets;
@property(readonly, strong) UIView *viewForFirstBaselineLayout;
@property(readonly, strong) UIView *viewForLastBaselineLayout;
UIKIT_EXTERN const CGFloat UIViewNoIntrinsicMetric;
@property(nonatomic, readonly) CGSize intrinsicContentSize;
- (void)invalidateIntrinsicContentSize;
- (UILayoutPriority)contentHuggingPriorityForAxis:(UILayoutConstraintAxis)axis;
- (void)setContentHuggingPriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis;
- (UILayoutPriority)contentCompressionResistancePriorityForAxis:(UILayoutConstraintAxis)axis;
- (void)setContentCompressionResistancePriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis;
@end
@interface UIView (UIConstraintBasedLayoutFittingSize)
- (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize;
- (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize withHorizontalFittingPriority:(UILayoutPriority)horizontalFittingPriority verticalFittingPriority:(UILayoutPriority)verticalFittingPriority;
@end
@interface UIView (UILayoutGuideSupport)
@property(nonatomic, readonly, copy) NSArray<__kindof UILayoutGuide *> *layoutGuides;
- (void)addLayoutGuide:(UILayoutGuide *)layoutGuide;
- (void)removeLayoutGuide:(UILayoutGuide *)layoutGuide;
@end
@class NSLayoutXAxisAnchor, NSLayoutYAxisAnchor, NSLayoutDimension;
@interface UIView (UIViewLayoutConstraintCreation)
@property(nonatomic, readonly, strong) NSLayoutXAxisAnchor *leadingAnchor;
@property(nonatomic, readonly, strong) NSLayoutXAxisAnchor *trailingAnchor;
@property(nonatomic, readonly, strong) NSLayoutXAxisAnchor *leftAnchor;
@property(nonatomic, readonly, strong) NSLayoutXAxisAnchor *rightAnchor;
@property(nonatomic, readonly, strong) NSLayoutYAxisAnchor *topAnchor;
@property(nonatomic, readonly, strong) NSLayoutYAxisAnchor *bottomAnchor;
@property(nonatomic, readonly, strong) NSLayoutDimension *widthAnchor;
@property(nonatomic, readonly, strong) NSLayoutDimension *heightAnchor;
@property(nonatomic, readonly, strong) NSLayoutXAxisAnchor *centerXAnchor;
@property(nonatomic, readonly, strong) NSLayoutYAxisAnchor *centerYAnchor;
@property(nonatomic, readonly, strong) NSLayoutYAxisAnchor *firstBaselineAnchor;
@property(nonatomic, readonly, strong) NSLayoutYAxisAnchor *lastBaselineAnchor;
@end
@interface UIView (UIConstraintBasedLayoutDebugging)
- (NSArray<__kindof NSLayoutConstraint *> *)constraintsAffectingLayoutForAxis:(UILayoutConstraintAxis)axis;
@property(nonatomic, readonly) BOOL hasAmbiguousLayout;
- (void)exerciseAmbiguityInLayout;
@end
@interface UILayoutGuide (UIConstraintBasedLayoutDebugging)
- (NSArray<__kindof NSLayoutConstraint *> *)constraintsAffectingLayoutForAxis:(UILayoutConstraintAxis)axis;
@property(nonatomic, readonly) BOOL hasAmbiguousLayout;
@end
@interface UIView (UIStateRestoration)
@property (nullable, nonatomic, copy) NSString *restorationIdentifier;
- (void)encodeRestorableStateWithCoder:(NSCoder *)coder;
- (void)decodeRestorableStateWithCoder:(NSCoder *)coder;
@end
@interface UIView (UISnapshotting)
- (nullable UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates;
- (nullable UIView *)resizableSnapshotViewFromRect:(CGRect)rect afterScreenUpdates:(BOOL)afterUpdates withCapInsets:(UIEdgeInsets)capInsets;
- (BOOL)drawViewHierarchyInRect:(CGRect)rect afterScreenUpdates:(BOOL)afterUpdates;
@end
@interface UIView (UserInterfaceStyle)
@property(nonatomic) UIUserInterfaceStyle overrideUserInterfaceStyle;
@end
@interface UIView (UIContentSizeCategoryLimit)
@property(nonatomic, copy, nullable) UIContentSizeCategory minimumContentSizeCategory;
@property(nonatomic, copy, nullable) UIContentSizeCategory maximumContentSizeCategory;
@property(nonatomic, copy, readonly) NSString *appliedContentSizeCategoryLimitsDescription;
@end
8、其他问题