Jos*_*eph 22 objective-c autolayout nslayoutconstraint ios7
我试图使用可视化格式语言来居中视图.
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_progressView(300)]-|" options:NSLayoutFormatAlignAllCenterY metrics:0 views:views]];
(views是一个NSDictionaryOfVariableBindings包含_progressView)
它不会将我的视图(宽度:300)置于self.view(宽度:768)内.它将它与8像素边距对齐,好像我只会写@"H:|-[_progressView(300)".
是使用类似的东西来中心视图的唯一方法:?
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_progressView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
谢谢
Dru*_*erB 34
这种格式字符串
@"H:|-[_progressView(300)]-|"
不会告诉AutoLayout居中progressView.相反,它说progressView应该是300宽,并且在超视图边缘的两侧都有一个系统定义的标准边距.显然这不能满足,因此Auto Layout会删除一些约束(您可能会在控制台上获得一些日志).在您的情况下丢弃的约束可能是右侧的边距.
要真正将视图置于其超级视图中,您必须使用详细约束方法而不是可视字符串格式,正如您已经想到的那样.但是,您可以轻松地将其放入这样一个很好的类别中:
@interface UIView (MyLayout)
- (void)centerHorizontallyInSuperview;
@end
@implementation UIView (MyLayout)
- (void)centerHorizontallyInSuperview {
    NSLayoutConstraint *c;
    c = [NSLayoutConstraint constraintWithItem:self
                                     attribute:NSLayoutAttributeCenterX
                                     relatedBy:NSLayoutRelationEqual                                                             
                                        toItem:self.superview
                                     attribute:NSLayoutAttributeCenterX 
                                    multiplier:1 
                                      constant:0];
    [self.superview addConstraint:c];
}
@end
Rob*_*Rob 17
三种方法:
您可以根据DrummerB的建议将约束添加到方法或类别中.
你也是有效的iOS 9,可以使用更新,更简洁的语法,使用锚点和使用activateConstraints:
[NSLayoutConstraint activateConstraints:@[
    [centerView.centerXAnchor constraintEqualToAnchor:view.centerXAnchor],
    ...
]];
或者在Swift 3中:
NSLayoutConstraint.activate([
    centerView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    ...
])
你可以使用UILayoutGuide对象:
UILayoutGuide *leftGuide = [[UILayoutGuide alloc] init];
[view addLayoutGuide:leftGuide];
UILayoutGuide *rightGuide = [[UILayoutGuide alloc] init];
[view addLayoutGuide:rightGuide];
并使用VFL将它们定义为彼此相等:
H:|[leftGuide][_progressView(==300)][rightGuide(==leftGuide)]|
如果你不能使用布局指南(例如你需要支持9.0之前的iOS版本,你想在IB中创建它等),你可以使用不可见的UIView对象(零的alpha或透明的背景颜色)非常相似的方式.只需将这些"spacer"视图添加到视图层次结构中,使用上面的水平约束,但只需配置视图就可以看不到它们.
这种技术是解决"视图中心如何"问题的一种麻烦的方法,但是如果你想要均匀地分隔十几个视图并且UIStackView由于某种原因你不能使用a ,那么它非常有用.您可以使用所需的许多UILayoutGuide(或不可见UIView)对象以获得所需的效果.
为了完整起见,我应该指出,它可能通过使用来达到效果options的NSLayoutFormatAlignAllCenterX/ Y,简列如/sf/answers/1044238681/,但我承认,我觉得不必要的混乱.
就个人而言,我认为第一种方法对您的场景最有意义.第二种方法在尝试均匀分布一堆控件时很有用,但对于这种简单的场景来说太笨拙了.第三种方法是求知欲,但我不会在任何实际应用中提出建议.
对于那些需要它的人,@ DrummerB的ObjC类别为Swift扩展:
extension UIView {
    func centerInSuperview() {
        self.centerHorizontallyInSuperview()
        self.centerVerticallyInSuperview()
    }
    func centerHorizontallyInSuperview(){
        let c: NSLayoutConstraint = NSLayoutConstraint(item: self, attribute: .CenterX, relatedBy: .Equal, toItem: self.superview, attribute: .CenterX, multiplier: 1, constant: 0)
        self.superview?.addConstraint(c)
    }
    func centerVerticallyInSuperview(){
        let c: NSLayoutConstraint = NSLayoutConstraint(item: self, attribute: .CenterY, relatedBy: .Equal, toItem: self.superview, attribute: .CenterY, multiplier: 1, constant: 0)
        self.superview?.addConstraint(c)
    }
}