UIImageView autoresizingmask 在某些情况下不起作用
Posted
技术标签:
【中文标题】UIImageView autoresizingmask 在某些情况下不起作用【英文标题】:UIImageView autoresizingmask not working in certain cases 【发布时间】:2016-11-10 22:11:03 【问题描述】:我正在试验一个打破障碍的 ios 应用程序,以了解有关 UI 功能的更多信息。目前,我在尝试使其适用于屏幕旋转时遇到问题。
我能够在屏幕旋转后正确地重新排列块,但在获取 UIImageView 以重新排列桨时遇到问题。
我的代码拆分如下,VC调用初始化一个BlockModel类的对象。这个对象存储了一个CGRect属性(也就是桨的ImageView对应的CGRect)。
然后 VC 创建一个使用桨图像初始化的 imageView,在图像视图上设置 autoresinging 属性(以具有灵活的外部掩码),根据模型对象中的 CGRect 设置框架并将 imageView 添加为子由 VC 处理的主视图的视图。
代码如下。
当我旋转时,我看到 ImageView 没有被自动重新定位。
如果我在 vC 中完成所有图像视图和 CGRect 创建,那么它可以工作(代码示例 2)。
这是预期的行为吗?如果是的话,如果 CGRect 是从另一个对象的属性中获得的,为什么自动调整大小不会启动?
完整的Xcode项目代码是here(github链接)
编辑 如果我将 imageView 存储为属性,看起来事情不起作用。我这样做是为了快速访问它。如果 imageView 存储为属性,为什么它不起作用?
初始化模型的代码
self.myModel = [[BlockerModel alloc] initWithScreenWidth:self.view.bounds.size.width andHeight:self.view.bounds.size.height];
模型初始化代码
-(instancetype) initWithScreenWidth:(CGFloat)width andHeight:(CGFloat)height
self = [super init];
if (self)
self.screenWidth = width;
self.screenHeight = height;
UIImage* paddleImage = [UIImage imageNamed:@"paddle.png"];
CGSize paddleSize = [paddleImage size];
self.paddleRect = CGRectMake((self.screenWidth-paddleSize.width)/2, (1 - PADDLE_BOTTOM_OFFSET)*self.screenHeight, paddleSize.width, paddleSize.height);
return self;
VC 中初始化 imageView 的代码
self.paddleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"paddle"]];
self.paddleView.backgroundColor = [UIColor clearColor];
self.paddleView.opaque = NO;
self.paddleView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleBottomMargin;
NSLog(@"Paddle rect is %@",NSStringFromCGRect(self.myModel.paddleRect));
[self.paddleView setFrame:self.myModel.paddleRect];
[self.view addSubview:self.paddleView];
如果我改为在 VC 中使用此代码来初始化 imageView,则一切正常
UIImage* paddleImage = [UIImage imageNamed:@"paddle.png"];
CGSize paddleSize = [paddleImage size];
CGRect paddleRect = CGRectMake((self.view.bounds.size.width-paddleSize.width)/2, (1 - PADDLE_BOTTOM_OFFSET)*self.view.bounds.size.height, paddleSize.width, paddleSize.height);
UIImageView *paddleView = [[UIImageView alloc] initWithImage:paddleImage];
paddleView.backgroundColor = [UIColor clearColor];
paddleView.opaque = NO;
paddleView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleBottomMargin;
[paddleView setFrame:paddleRect];
[self.view addSubview:paddleView];
【问题讨论】:
【参考方案1】:发现问题。我正在使用模型对象来处理我所有的“游戏对象位置”逻辑。例如,VC 会根据触摸事件计算 X 轴增量并将它们转发给模型对象。此外,CADisplayLink 事件将被转发,以便模型可以根据自上次事件以来的速度和时间更新球的位置。然后它将使用更新的位置来检测碰撞。之所以使用这种拆分,是因为模型类还具有检测与侧面、桨/球等碰撞的方法。
问题在于模型对象正在重写 paddleView 的 CGRect,方法是将它从 VC 接收到的增量添加到它存储的当前 paddleRect 的 origin.x 中。这个 paddleRect 没有考虑到 CGRect 的自动调整,这是通过旋转后自动调整大小来完成的。
修复是让 VC 在调用模型中的方法更新所有游戏属性并检测碰撞之前设置 paddleRect 的 CGRect(设置为 paddleView 帧)。这种方式模型只处理共谋检测的逻辑,并基于它更新球的运动和速度。 VC 使用当前 paddleView 位置,因此会自动考虑到 CGRect 的自动调整,这是通过在旋转后自动调整大小来完成的。
github 链接中的源代码已更新。
【讨论】:
以上是关于UIImageView autoresizingmask 在某些情况下不起作用的主要内容,如果未能解决你的问题,请参考以下文章
使 UIImageview 根据另一个 UIImageview 旋转而旋转