首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iOS 8自动布局问题

iOS 8自动布局问题
EN

Stack Overflow用户
提问于 2014-10-09 21:08:22
回答 3查看 2.7K关注 0票数 12

在iOS 8中发生的自动布局有一个恼人的问题,而在iOS 7中同样的设置也很好。

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

该特性由一个容器视图(蓝色)和三个子视图组成:

  • 标签
  • 图像视图(具有切片、缩放的图像)
  • 扣子

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

自动布局约束将标签锚定在左侧,按钮固定在右侧,图像视图被锚定在两侧,而没有宽度约束。

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

请注意图像视图(黑线)是如何与容器视图右侧的偏移量锚定的。

我已经尝试了所有的方法,我不明白为什么在iOS 8中这种情况会有所不同,我已经多次删除和替换了所有的约束,但是仍然得到了相同的结果。

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

这些是容器视图的约束:

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

代码语言:javascript
复制
- (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来解决类似的问题,这就是为什么我在包含视图和根视图上调用它时非常明确的原因。我试过以上所有的组合,但似乎没有什么不同。

我开始失去寻找解决方案的希望,但也许这里的人已经处理过类似的情况,并能让这个问题变得更清晰?

编辑:,我应该补充说,我也尝试过设置从图像视图到标签和按钮的约束,而不是设置包含视图的边缘,结果是相同的。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-10-10 12:23:22

这不是自动布局的问题,但必须是iOS 8中关于处理切片图像资产的一个bug。

使用您的示例项目:

代码语言:javascript
复制
    UIImage *img = [UIImage imageNamed:@"pointer-dark-left"];
    NSLog(@"alignmentRect: %@", NSStringFromUIEdgeInsets(img.alignmentRectInsets));
    NSLog(@"capInsets: %@", NSStringFromUIEdgeInsets(img.capInsets));

这段代码打印

代码语言:javascript
复制
// 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

作为记录在案,Autolayout使用对齐矩形,而UIImageView使用它的图像alignmentRectInsets。因此,您的self.line具有额外的右宽度的65.5pt。

当然,您没有在xcassets编辑器中设置对齐内嵌,我相信它是bug

这里有一个丑陋的,但正在工作的解决办法:

代码语言:javascript
复制
- (void)viewDidLoad {
    [super viewDidLoad];
    self.line.image = [self.line.image imageWithAlignmentRectInsets:UIEdgeInsetsZero];
}
票数 7
EN

Stack Overflow用户

发布于 2014-10-09 21:28:32

我觉得你把限制因素联系错了。

我构建了一个具有相同组件的应用程序,它运行得很好。也许您可以清除所有约束并重新设置。

我添加代码以编程方式完成它。

代码语言:javascript
复制
#import "ViewController.h"

@interface ViewController () {    
    NSLayoutConstraint* csViewWidth;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    NSDictionary *views = @{
                        @"label": self.uiLabel,
                        @"image": self.uiImage,
                        @"button": self.uiButton
                        };

    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[label]-[image]-[button]-|"
                                                                options:0
                                                                metrics:nil
                                                                  views:views];
    [self.view addConstraints:constraints];

    NSArray *panelConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[panel(320)]" options:0 metrics:nil views:@{ @"panel": self.uiPanel }];
    csViewWidth = [panelConstraint firstObject];
    [self.view addConstraints:@[csViewWidth]];
}

- (IBAction)onSliderChanged:(UISlider*)sender {
    float containerWidth = self.view.frame.size.width;
    csViewWidth.constant = sender.value * containerWidth;
}

@end

该解决方案经过测试,工作良好。没有必要调用setNeedsLayout和layoutIfNeeded。

票数 1
EN

Stack Overflow用户

发布于 2014-10-10 15:00:26

那不是因为iOS的错误

图像被切错了

我用您的项目进行了测试,它现在按预期的方式工作。

切片必须是这样的:

  • 第一:圆圈后面
  • 第二名:第一名后一名
  • 第三:在最后

在你的切片,你告诉ios采取长尾巴,这是打破了你的布局。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26287942

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档