iOS 8 自动布局问题

标签 ios objective-c ios7 ios8 autolayout

我在 iOS 8 中遇到了一个烦人的自动布局问题,而同样的设置在 iOS 7 中工作正常。

我已经简化并隔离了有问题的情况,下面是它应该的工作方式 - 以及它确实在 iOS 7 中的工作方式:

Constraints working in iOS 7

该特征由一个容器 View (蓝色)和三个 subview 组成:

  • 标签
  • ImageView (带有切片、缩放图像)
  • 一个按钮

我添加了一个 slider ,通过修改容器的宽度约束来控制容器 View 的宽度。

自动布局约束将标签锚定在左侧,按钮锚定在右侧, ImageView 在没有宽度约束的情况下锚定在两侧。

在 iOS 8 中,完全相同的设置如下所示:

Constraints broken in iOS 8

请注意 ImageView (黑线)如何锚定在容器 View 右侧的偏移量外部

我已经尝试了所有方法,但我无法弄清楚为什么这在 iOS 8 中表现不同。我已经多次删除并替换所有约束,但我仍然得到相同的结果。

这些是对每个 subview 设置的约束,分别是:

Sub views constraints

这些是容器 View 的约束:

Container view constraints

container view 的宽度约束是这样被 slider 控制的:

Width constraint connection

- (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.right65.5!

作为documented ,Autolayout 使用对齐矩形,UIImageView 使用其图像 alignmentRectInsets。所以,您的 self.line65.5pt 额外的右边宽度。

当然,您没有在xcassets 编辑器中设置Alignment Insets,我相信这是一个错误

screenshot

这是一个丑陋但有效的解决方法:(

- (void)viewDidLoad {
    [super viewDidLoad];
    self.line.image = [self.line.image imageWithAlignmentRectInsets:UIEdgeInsetsZero];
}

关于iOS 8 自动布局问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26287942/

相关文章:

ios - 从其 super View iOS 7 问题中获取 UITableViewCell

iphone - 无法从 C++ 文件访问对象属性 (Cocos2D/Box2d)

objective-c - 在App和Cocoa Touch Framework目标中使用静态库

objective-c - 创建多条画线

ios - 以编程方式设置 RoundedRect 按钮

ios - 使用 NSUserDefaults 的整数值

ios - 使用两个 UIPickerView 时出现问题 - 第一个世界,第二个世界没有

ios - 按下公开按钮时, map 标注展开动画就像 map 中的动画一样

objective-c - iOS MDM : Common key/id for iOS MDM and supporting MDM iOS application

ios - 有没有办法检查 "increase contrast"是否在 iOS 的辅助功能设置中启用?