如何使用视觉格式语言设置动态高度
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];
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];