大多数情况下,我们都是直接设置 frame 。
今天在 UIView 的头文件里看到官方对 frame 的注释是这样说的:
// animatable. do not use frame if view is transformed since it will not correctly reflect the actual location of the view. use bounds + center instead.
@property(nonatomic) CGRect frame;
意思是说如果 View 已经设置了形变,那么就需要用 bounds + center 来设置 View 的大小和位置,因为 frame 的信息已经不能表示其真实位置了。
系统的自动布局就是使用 bounds + center 的方式来布局的,所以能保证在应用了形变的情况下布局依然正常。
基于 frame 的手动布局就需要考虑这个问题了,不能再使用直接设置 frame 的方式,而要改成 bounds + center 的方式。
调整起来也很简单,只要增加一个分类,支持设置 origin 和 size 就可以替换 frame 了。
@interface UIView (ZGeometry)
@property(nonatomic, assign) CGPoint origin;
@property(nonatomic, assign) CGSize size;
@end
#import "UIView+ZGeometry.h"
@implementation UIView (ZGeometry)
- (void)setOrigin:(CGPoint)origin {
CGRect bounds = self.bounds;
CGFloat x = origin.x + CGRectGetWidth(bounds) * 0.5;
CGFloat y = origin.y + CGRectGetWidth(bounds) * 0.5;
self.center = CGPointMake(x, y);
}
- (CGPoint)origin {
CGPoint center = self.center;
CGRect bounds = self.bounds;
CGFloat x = center.x - CGRectGetWidth(bounds) * 0.5;
CGFloat y = center.y - CGRectGetWidth(bounds) * 0.5;
return CGPointMake(x, y);
}
- (void)setSize:(CGSize)size {
CGRect bounds = self.bounds;
bounds.size = CGSizeMake(MAX(0, size.width), MAX(0, size.height));
self.bounds = bounds;
}
- (CGSize)size {
return self.bounds.size;
}
@end