如何使用视觉格式语言设置动态高度

How to set dynamic height with Visual Format Language

NSString *format = [NSString stringWithFormat:@"H:|-10-[self]-10-|"];
NSString *formatVertical = [NSString stringWithFormat:@"V:|-40-[self(300)]|"];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:viewsDictionary]];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:formatVertical options:0 metrics:nil views:viewsDictionary]];

使用 formatVertical 我可以设置视图的高度。但我想让这个值成为动态值,以便能够在所有不同的屏幕上显示相同的外观。

有什么我可以实现的吗?

我认为,您可以使用指标。 Objective-C解决方案:

NSString *format = [NSString stringWithFormat:@"H:|-10-[self]-10-|"];
NSString *formatVertical = [NSString stringWithFormat:@"V:|-40-[self(height)]|"];
NSNumber *height = [NSNumber numberWithFloat:self.view.frame.size.height / 2];
NSDictionary *metrics = [NSDictionary dictionaryWithObjectsAndKeys:height, @"height", nil];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:viewsDictionary]];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:formatVertical options:0 metrics:metrics views:viewsDictionary]]; 

来自 raywenderlich.com 的 swift 的解决方案:

private enum Metrics {
      static let padding: CGFloat = 15.0
      static let iconImageViewWidth: CGFloat = 30.0
    }
let metrics = [
      "horizontalPadding": Metrics.padding,
      "iconImageViewWidth": Metrics.iconImageViewWidth]

let topRowHorizontalFormat = """H:|-horizontalPadding-[iconImageView(iconImageViewWidth)]-[appNameLabel]-[skipButton]-horizontalPadding-|"""
let topRowHorizontalConstraints = NSLayoutConstraint.constraints(
    withVisualFormat: topRowHorizontalFormat,
    options: [.alignAllCenterY],
    metrics: metrics,
    views: views)
allConstraints += topRowHorizontalConstraints

let summaryHorizontalConstraints = NSLayoutConstraint.constraints(
    withVisualFormat: "H:|-horizontalPadding-[summaryLabel]-horizontalPadding-|",
    metrics: metrics,
    views: views)
allConstraints += summaryHorizontalConstraints

https://www.raywenderlich.com/174078/auto-layout-visual-format-language-tutorial-2

视觉格式语言很好,除了它无法实现的一些布局属性 - 例如 height/width 百分比和居中。

来自 "K. Davydenko" 的答案将 工作...有点。它仍然为您的子视图设置固定高度。所以如果你把它放在错误的地方(例如,在超级视图布局之前),或者如果视图发生变化(例如设备旋转),你将无法得到你想要的东西。

由于除了 VFL 格式外添加 NSLayoutConstraint 相当简单,因此这是更好的选择:

UIView *v = [UIView new];
v.translatesAutoresizingMaskIntoConstraints = NO;
v.backgroundColor = [UIColor blueColor];

[self.view addSubview:v];

NSDictionary *viewsDictionary = @{@"self":v};

NSString *format = [NSString stringWithFormat:@"H:|-10-[self]-10-|"];

// vertical formatting (40-pts from the top), but do NOT set a height 
// (and do not include the trailing "|")
NSString *formatVertical = [NSString stringWithFormat:@"V:|-40-[self]"];

NSMutableArray *constraints = [NSMutableArray new];

[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:viewsDictionary]];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:formatVertical options:0 metrics:nil views:viewsDictionary]];

// now add a constraint to set the Height of your subview equal to
// the height of the superview, with a 0.5 multiplier
// This will keep your view 1/2 the height of the superview, even
// when the superview's size changes
NSLayoutConstraint *c = [NSLayoutConstraint
                         constraintWithItem:v
                         attribute:NSLayoutAttributeHeight
                         relatedBy:NSLayoutRelationEqual
                         toItem:self.view
                         attribute:NSLayoutAttributeHeight
                         multiplier:0.5
                         constant:0.0];

[constraints addObject:c];

[self.view addConstraints:constraints];