iOS 8自动布局问题

dav*_*son 12 objective-c ios autolayout ios7 ios8

我在iOS 8中出现了自动布局的烦人问题,而​​相同的设置在iOS 7中运行良好.

我已经简化并隔离了有问题的情况,以下是它应该如何工作 - 以及它如何在iOS 7 工作:

在iOS 7中工作的约束

该功能包含一个容器视图(蓝色)和三个子视图:

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

我添加了一个滑块,通过修改容器的宽度约束来控制容器视图的宽度.

自动布局约束将标签锚定到左侧,将按钮锚定到右侧,并且图像视图锚定到两侧而没有宽度约束.

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

iOS 8中的约束条件已被破坏

请注意图像视图(黑色线条)看起来如何锚定在容器视图右侧外部的偏移.

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

这些是在每个子视图上设置的约束,分别是:

子视图约束

这些是容器视图的约束:

容器视图约束

容器视图的宽度约束由滑块操纵,如下所示:

宽度约束连接

- (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];
}
Run Code Online (Sandbox Code Playgroud)

其他在iOS 8中遇到自动布局问题的人似乎已经能够通过调用setNeedsLayout和/或setNeedsUpdateConstraints 直接在包含视图上解决类似问题,这就是为什么我非常明确地在包含视图和根视图.我已经尝试了上述所有组合,但似乎没有任何区别.

我开始失去寻找解决方案的希望,但也许这里的某个人已经处理过类似情况并且可以对这个问题有所了解吗?


编辑:我应该补充一点,我还尝试将约束从图像视图设置为标签和按钮,而不是包含视图的边缘具有相同的结果.


编辑2:这是我在尝试隔离问题时一直使用的测试项目:下载

rin*_*aro 7

这不是自动布局的问题,但必须是iOS 8中关于处理切片图像资源的错误.

使用您的示例项目:

    UIImage *img = [UIImage imageNamed:@"pointer-dark-left"];
    NSLog(@"alignmentRect: %@", NSStringFromUIEdgeInsets(img.alignmentRectInsets));
    NSLog(@"capInsets: %@", NSStringFromUIEdgeInsets(img.capInsets));
Run Code Online (Sandbox Code Playgroud)

此代码打印

// 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}
Run Code Online (Sandbox Code Playgroud)

alignmentRectInsets.right65.5!

作为记录,自动布局可与排列的矩形,并UIImageView使用其图像alignmentRectInsets.所以,你self.line65.5超宽的权利.

当然,你没有在xcassets编辑器中设置Alignment Insets ,我相信这是一个bug.

截图

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

- (void)viewDidLoad {
    [super viewDidLoad];
    self.line.image = [self.line.image imageWithAlignmentRectInsets:UIEdgeInsetsZero];
}
Run Code Online (Sandbox Code Playgroud)