我在 iOS 8 中遇到了一个烦人的自动布局问题,而同样的设置在 iOS 7 中工作正常。
我已经简化并隔离了有问题的情况,下面是它应该的工作方式 - 以及它确实在 iOS 7 中的工作方式:
该特征由一个容器 View (蓝色)和三个 subview 组成:
- 标签
- ImageView (带有切片、缩放图像)
- 一个按钮
我添加了一个 slider ,通过修改容器的宽度约束来控制容器 View 的宽度。
自动布局约束将标签锚定在左侧,按钮锚定在右侧, ImageView 在没有宽度约束的情况下锚定在两侧。
在 iOS 8 中,完全相同的设置如下所示:
请注意 ImageView (黑线)如何锚定在容器 View 右侧的偏移量外部。
我已经尝试了所有方法,但我无法弄清楚为什么这在 iOS 8 中表现不同。我已经多次删除并替换所有约束,但我仍然得到相同的结果。
这些是对每个 subview 设置的约束,分别是:
这些是容器 View 的约束:
container view 的宽度约束是这样被 slider 控制的:
- (IBAction)handleSliderChange:(id)sender
{
self.buttonWidth.constant = self.slider.value * 1024.0;
[self.containerView setNeedsLayout];
[self.containerView setNeedsUpdateConstraints];
[self.containerView layoutIfNeeded];
[self.view setNeedsLayout];
[self.view setNeedsUpdateConstraints];
[self.view layoutIfNeeded];
}
其他在 iOS 8 中遇到自动布局问题的人似乎已经能够通过调用 setNeedsLayout
来解决类似问题。和/或 setNeedsUpdateConstraints
直接 在包含 View 上,这就是为什么我非常明确地在包含 View 和 Root View 上调用它。我已经尝试了上述所有组合,但似乎没有什么不同。
我开始对找到解决方案失去希望,但也许这里有人处理过类似的情况并且可以使这个问题更加清晰?
编辑: 我应该补充一点,我也尝试设置 constraints from the image view to the label and button而不是具有相同结果的包含 View 的边缘。
编辑 2:这是我在尝试隔离问题时一直使用的测试项目: Download
最佳答案
这不是 Auto Layout 的问题,但一定是 iOS 8 中处理切片图像资源的错误。
使用您的示例项目:
UIImage *img = [UIImage imageNamed:@"pointer-dark-left"];
NSLog(@"alignmentRect: %@", NSStringFromUIEdgeInsets(img.alignmentRectInsets));
NSLog(@"capInsets: %@", NSStringFromUIEdgeInsets(img.capInsets));
这段代码打印
// iOS 7
alignmentRect: {0, 0, 0, 0}
capInsets: {0, 5.5, 0, 134}
// iOS 8
alignmentRect: {0, 0, 0, 65.5}
capInsets: {0, 5.5, 0, 134}
alignmentRectInsets.right
为 65.5
!
作为documented ,Autolayout 使用对齐矩形,UIImageView
使用其图像 alignmentRectInsets
。所以,您的 self.line
有 65.5
pt 额外的右边宽度。
当然,您没有在xcassets
编辑器中设置Alignment Insets,我相信这是一个错误。
这是一个丑陋但有效的解决方法:(
- (void)viewDidLoad {
[super viewDidLoad];
self.line.image = [self.line.image imageWithAlignmentRectInsets:UIEdgeInsetsZero];
}
关于iOS 8 自动布局问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26287942/