我正在尝试使用约束构建一个标题视图,它看起来像这样:
我知道如何使用帧来完成这个操作。我会计算文本的宽度、图片的宽度,创建一个包含两者宽度/高度的视图,然后使用框架将两者都添加为子视图到适当位置。
我试图了解如何使用约束来完成此操作。我的想法是内在内容大小会帮助我解决问题,但我在疯狂地尝试中挣扎着让其正常工作。
UILabel *categoryNameLabel = [[UILabel alloc] init];
categoryNameLabel.text = categoryName; // a variable from elsewhere that has a category like "Popular"
categoryNameLabel.translatesAutoresizingMaskIntoConstraints = NO;
[categoryNameLabel sizeToFit]; // hoping to set it to the instrinsic size of the text?
UIView *titleView = [[UIView alloc] init]; // no frame here right?
[titleView addSubview:categoryNameLabel];
NSArray *constraints;
if (categoryImage) {
UIImageView *categoryImageView = [[UIImageView alloc] initWithImage:categoryImage];
[titleView addSubview:categoryImageView];
categoryImageView.translatesAutoresizingMaskIntoConstraints = NO;
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[categoryImageView]-[categoryNameLabel]|" options:NSLayoutFormatAlignAllTop metrics:nil views:NSDictionaryOfVariableBindings(categoryImageView, categoryNameLabel)];
} else {
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[categoryNameLabel]|" options:NSLayoutFormatAlignAllTop metrics:nil views:NSDictionaryOfVariableBindings(categoryNameLabel)];
}
[titleView addConstraints:constraints];
// here I set the titleView to the navigationItem.titleView
我不应该硬编码标题视图的大小。它应该能够通过其内容的大小来确定,但是...
- 除非我硬编码一个框架,否则titleView正在确定其大小为0。
- 如果我设置
translatesAutoresizingMaskIntoConstraints = NO
,应用程序会崩溃,并显示此错误:'Auto Layout still required after executing -layoutSubviews. UINavigationBar's implementation of -layoutSubviews needs to call super.'
更新
我使用了这段代码使它工作了,但仍然需要在titleView上设置框架:
UILabel *categoryNameLabel = [[UILabel alloc] init];
categoryNameLabel.translatesAutoresizingMaskIntoConstraints = NO;
categoryNameLabel.text = categoryName;
categoryNameLabel.opaque = NO;
categoryNameLabel.backgroundColor = [UIColor clearColor];
UIView *titleView = [[UIView alloc] init];
[titleView addSubview:categoryNameLabel];
NSArray *constraints;
if (categoryImage) {
UIImageView *categoryImageView = [[UIImageView alloc] initWithImage:categoryImage];
[titleView addSubview:categoryImageView];
categoryImageView.translatesAutoresizingMaskIntoConstraints = NO;
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[categoryImageView]-7-[categoryNameLabel]|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(categoryImageView, categoryNameLabel)];
[titleView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[categoryImageView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(categoryImageView)];
[titleView addConstraints:constraints];
titleView.frame = CGRectMake(0, 0, categoryImageView.frame.size.width + 7 + categoryNameLabel.intrinsicContentSize.width, categoryImageView.frame.size.height);
} else {
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[categoryNameLabel]|" options:NSLayoutFormatAlignAllTop metrics:nil views:NSDictionaryOfVariableBindings(categoryNameLabel)];
[titleView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[categoryNameLabel]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(categoryNameLabel)];
[titleView addConstraints:constraints];
titleView.frame = CGRectMake(0, 0, categoryNameLabel.intrinsicContentSize.width, categoryNameLabel.intrinsicContentSize.height);
}
return titleView;
UINavigationBar
本身 - 但由于某些原因,您不能向其添加约束 - 失败并显示Cannot modify constraints for UINavigationBar managed by a controller
。 - Petar