ViewUtils 是一系列类别方法,它扩展了 UIView,包含了你一直希望内置的所有方便属性和功能。ViewUtils 包括
注意:'支持' 表示库已与该版本进行了测试。'兼容' 表示库应该在该 iOS 版本上运行(即它不依赖于任何不可用的 SDK 特性),但不再进行兼容性测试,可能需要调整或修复错误才能正常运行。
ViewUtils 适用于 ARC 和非 ARC项目。没有必要从 ARC 验证过程排除 ViewUtils 文件,也不需要使用 ARC 转换工具转换 ViewUtils。
UIView 本身就是单线程的,因此应该仅在主线程上使用 ViewUtils 方法。
要在应用程序中使用 ViewUtils 类别,只需将 ViewUtils.h 和 .m 文件(不需要演示文件和资源)拖动到您的项目中,并将头文件导入到任何希望使用 ViewUtils 功能的类中,或者将其包含在 prefix.pch 文件中以在整个项目中使用。
ViewUtils 通过以下方法扩展了 UIView
+ (id)instanceWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)bundleOrNil owner:(id)owner;
此方法从 nib 文件中加载视图。要加载的视图必须是文件中的第一个对象。此方法用于加载如 UITableViewCells 或 iCarousel 项目视图等的视图。nib 文件被缓存,以后的加载将性能更好。
- (void)loadContentsWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)bundleOrNil;
这种方法类似于 instanceWithNibName:
,但它不是返回nib文件中的第一个视图,而是将该视图加载并作为方法调用视图的子视图,如果需要,调整加载视图的大小以适合父视图的边界。这对于想要创建由可重用子视图组成的复杂视图非常有用,每个子视图存储在其自己的nib文件中。
- (UIView *)viewMatchingPredicate:(NSPredicate *)predicate;
返回视图本身或第一个匹配指定谓词的子视图。如果没有子视图匹配,则方法返回nil。
- (UIView *)viewWithTag:(NSInteger)tag ofClass:(Class)viewClass;
返回视图本身或第一个具有指定标记值且为指定类的子视图。这比常规的 viewWithTag:
方法更安全。
- (UIView *)viewOfClass:(Class)viewClass;
返回视图本身或第一个具有指定类的子视图。
- (NSArray *)viewsMatchingPredicate:(NSPredicate *)predicate;
- (NSArray *)viewsWithTag:(NSInteger)tag;
- (NSArray *)viewsWithTag:(NSInteger)tag ofClass:(Class)viewClass;
- (NSArray *)viewsOfClass:(Class)viewClass;
这些方法与其单个视图等效方法的工作方式完全相同,但它们返回所有匹配的视图,而不仅仅是第一个匹配的视图。搜索按深度优先顺序进行。
- (UIView *)firstSuperviewMatchingPredicate:(NSPredicate *)predicate;
- (UIView *)firstSuperviewOfClass:(Class)viewClass;
- (UIView *)firstSuperviewWithTag:(NSInteger)tag;
- (UIView *)firstSuperviewWithTag:(NSInteger)tag ofClass:(Class)viewClass;
这些方法像viewMatching/Of/Width版本一样工作,但它们在视图层次结构中向上移动,而不是向下,并将返回第一个匹配指定标准的父视图。
- (BOOL)viewOrAnySuperviewMatchesPredicate:(NSPredicate *)predicate;
- (BOOL)viewOrAnySuperviewIsKindOfClass:(Class)viewClass;
如果视图或其链中的任何父视图符合标准,则该方法返回YES。这对于事件处理非常有用,例如,如果您想知道给定的触摸是否发生在特定的控件或控件类型上,例如,您可以忽略在特定视图中执行的手势。
- (BOOL)isSuperviewOfView:(UIView *)view;
- (BOOL)isSubviewOfView:(UIView *)view;
这些方法允许您确定一个视图是否是另一个视图的子视图。这些方法将在整个父视图链中进行搜索,而不仅仅是单个级别,因此如果一个视图是另一个视图的父视图的父视图,它仍然会返回YES。
- (UIViewController *)firstViewController;
此方法使用响应者链来识别控制器链中负责视图的第一个视图控制器。例如,如果在该按钮上调用此方法,它将返回宿主包含该按钮的视图的视图控制器。
- (UIView *)firstResponder;
如果它是在调用方法视图的子视图中,则返回第一个响应者;如果没有,则返回nil。如果您不知道第一个响应者可能位于哪个子视图树中,请在主窗口或当前前最视图控制器的根视图中调用此方法,应该返回所需的结果。
- (void)setLeft:(CGFloat)left right:(CGFloat)right;
- (void)setWidth:(CGFloat)width right:(CGFloat)right;
- (void)setTop:(CGFloat)top bottom:(CGFloat)bottom;
- (void)setHeight:(CGFloat)height bottom:(CGFloat)bottom;
设置视图的左右边缘或设置宽度而不影响右边缘往往是麻烦的,因为属性是相互关联的。这些设置方法通过允许您通过单个方法调用设置两个属性,使其稍微容易一些。
- (void)crossfadeWithDuration:(NSTimeInterval)duration;
- (void)crossfadeWithDuration:(NSTimeInterval)duration completion:(void (^)(void))completion;
这些方法使用Core Animation执行指定持续时间的淡入淡出过渡。淡入淡出通常用于需要动画某些视图属性,但这些属性本身不支持动画的情况。一个典型的例子是更改UILabel中的文本或UIImageView中的图像。
ViewUtils扩展UIView,以下属性用于设置帧位置和尺寸
@property (nonatomic, assign) CGPoint origin;
视图原点(左上角)在父视图内的位置。这相当于 view.frame.origin
。
@property (nonatomic, assign) CGSize size;
视图的外部尺寸。这相当于 view.frame.size
。
@property (nonatomic, assign) CGFloat top;
@property (nonatomic, assign) CGFloat left;
@property (nonatomic, assign) CGFloat bottom;
@property (nonatomic, assign) CGFloat right;
视图四个角在父视图内的位置。这些位置都是相对于父视图左上角的,因此(例如)view.bottom
属性相当于 view.top + view.height
。
@property (nonatomic, assign) CGFloat width;
@property (nonatomic, assign) CGFloat height;
视图的外部尺寸。这些分别相当于 view.size.width
和 view.size.height
。
@property (nonatomic, assign) CGFloat x;
@property (nonatomic, assign) CGFloat y;
视图锚点(通常是中心)在父视图内的位置。这些分别相当于 view.center.x
和 view.center.y
。
@property (nonatomic, assign) CGSize boundsSize;
@property (nonatomic, assign) CGFloat boundsWidth;
@property (nonatomic, assign) CGFloat boundsHeight;
视口边界尺寸(内部尺寸)。当视口被变换且无法依赖框架大小来准确获取或设置内容尺寸时,边界大小很有用。
@property (nonatomic, readonly) CGRect contentBounds;
通常,您希望将子视图定位在父视图的精确位置以完全填充它的父视图,但为了做到这一点,您必须构造一个具有父视图边界宽度和高度的CGRect,并且原点为0,0。不幸的是,没有保证superview.bounds
的原点是0,0,因为在一个已旋转的UIWindow或已滚动或缩放的UIScrollView中,边界原点已经被改变以正确对齐视图框架内的内容。contentBounds属性返回一个与边界大小匹配的矩形,但其原点始终为0,0。
@property (nonatomic, readonly) CGPoint contentCenter;
通常,您希望将子视图定位在父视图的精确中心,但计算视图的中心是一段繁琐的代码。contentCenter属性返回这个位置。