iOS 8:为啥 NSLayoutAttributeCenterX 无法将我的视图居中? (适用于 iOS 7)
Posted
技术标签:
【中文标题】iOS 8:为啥 NSLayoutAttributeCenterX 无法将我的视图居中? (适用于 iOS 7)【英文标题】:iOS 8: Why is NSLayoutAttributeCenterX failing to center my views? (works in iOS 7)iOS 8:为什么 NSLayoutAttributeCenterX 无法将我的视图居中? (适用于 iOS 7) 【发布时间】:2014-12-04 03:12:04 【问题描述】:我有一些在 ios 7 中可以使用的自动布局代码,但在 iOS 8 中没有。我的代码在两个版本之间没有变化。
情况是我有一个视图控制器,其中包含一些应该垂直堆叠的子视图,如下所示:
但是,当我在 iOS 8 上运行相同的代码时,会发生以下情况:
设置我的约束的代码如下:
- (void) updateViewConstraints
[super updateViewConstraints];
NSDictionary *viewsDictionary = @
@"timeLabel": self.timeLabel,
@"recordingStateImage": self.recordingStateImage,
@"recordButton": self.recordButton,
@"spacer1": spacer1,
@"spacer2": spacer2,
@"superview": self.view
;
if (!portraitConstraints)
//
// Portrait Layout
//
portraitConstraints = [[NSMutableArray alloc] initWithArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[timeLabel][spacer1][recordingStateImage][spacer2(==spacer1)][recordButton(100)]-|"
options:0
metrics:0
views:viewsDictionary]];
[portraitConstraints addObjectsFromArray:@[
[NSLayoutConstraint constraintWithItem:self.timeLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.f
constant:0.f],
[NSLayoutConstraint constraintWithItem:self.recordingStateImage
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.f
constant:0.f],
[NSLayoutConstraint constraintWithItem:self.recordButton
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.f
constant:0.f]
]];
[self.view removeConstraints:self.view.constraints];
[self.view addConstraints:portraitConstraints];
我不确定为什么会这样。我已经检查了以下 SO 问题中提到的解决方法:
Autolayout problems with iOS8 with code that works fine on iOS7 Issue with Auto Layout on iOS 8 (code works perfectly on iOS 7)但他们没有工作(这是在子视图而不是视图控制器的视图上调用 setNeedsLayout)。
如果有人在 iOS 8 上遇到了 NSLayoutAttributeCenterX 和自动布局的问题,我们将不胜感激。
【问题讨论】:
这里的容器视图是什么??? 什么时候调用updateViewConstraints?是否在生命周期方法中,例如 viewDidLoad 或 ViewWillAppear? 不要删除 updateViewConstraints 中的所有约束,它也会删除 XCode 添加的约束,并且你永远不会找回它 我还看到逻辑错误,如果 portraitCopnstaints 为 nill 怎么办?在这种情况下,您不应该删除任何常量。 【参考方案1】:由于我的评论有助于解决问题,并且 OP 需要有关同一问题的更多信息,因此我发表评论作为答案
注意: 删除所有约束是不好的做法,因为它会删除 XCode 添加的所有约束以在设备中正确显示您的视图。
在横向和纵向模式下具有不同的 UI 如果您的视图在横向和纵向上有不同的约束(在紧凑和常规视图中)。 您可以使用尺寸等级 introduce in XCode6 和 backward comparability。 请按照这个blog 很好地解释尺寸等级。download project 在上面的博客中创建。输出: 以横向模式查看 以纵向模式查看:
【讨论】:
jw - 你对让这些东西向后兼容有什么想法吗?我最终做的是将我的旧逻辑保留在updateConstraints
中,但仅在操作系统为
根据苹果大小分类向后兼容developer.apple.com/library/ios/recipes/…
我没有尝试但是这个问题我的帮助***.com/questions/24172860/…【参考方案2】:
事实证明,iOS 8 和 Xcode 6 为视图添加了额外的约束来帮助布局其元素。我通过上面的Jageen 和comment on a github issue 发现了这一点。
该问题的解决方案是不要在 iOS 8 中调用 [self.view removeConstraints]
,因为它会移除这些额外的必需约束。我个人对此的解决方法是利用 iOS 8 的 nib 及其特定方向的约束,并进行操作系统检查以仅在
如果有人对此问题有一个向后兼容的解决方法,可以在视图上调用removeConstraints
,我会非常有兴趣看到它(因为我的纵向和横向布局不同)。
【讨论】:
因为你有不同的纵向和横向布局,你可以使用尺寸类(在 XCode6 中引入具有向后可比性),看看这个例子raywenderlich.com/83276/beginning-adaptive-layout-tutorial【参考方案3】:我遇到了这个问题。在我的情况下,它的原因是这条线
self.view.translatesAutoresizingMaskIntoConstraints = NO; (自己是 UIViewController)
设置约束后,我在控制台的断点期间键入 po self.view.layer,它看起来很好。我在 viewDidLoad 中设置了约束(用 viewWillAppear 和 viewWillLayoutSubviews 进行实验会产生相同的结果)。但是,当我在 viewDidAppear 中添加断点并在控制台中键入相同的命令时,self.view 的宽度和高度都变为零。我删除了上面的行并且它起作用了。 self.view 保留了它的高度和宽度,并且子视图在中心对齐。
【讨论】:
以上是关于iOS 8:为啥 NSLayoutAttributeCenterX 无法将我的视图居中? (适用于 iOS 7)的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Safari Mobile 在 iOS 8 上处理许多输入字段时遇到问题
iOS 8:为啥 NSLayoutAttributeCenterX 无法将我的视图居中? (适用于 iOS 7)