使用约束以编程方式构建titleView(或者通常使用约束构建视图) [英] Building a titleView programmatically with constraints (or generally constructing a view with constraints)

查看:80
本文介绍了使用约束以编程方式构建titleView(或者通常使用约束构建视图)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用如下所示的约束构建titleView:

I'm trying to build a titleView with constraints that looks like this:

我知道如何用帧来做这件事。我会计算文本的宽度,图像的宽度,创建一个宽度/高度包含两者的视图,然后将两者作为子视图添加到带有框架的适当位置。

I know how I would do this with frames. I would calculate the width of the text, the width of the image, create a view with that width/height to contain both, then add both as subviews at the proper locations with frames.

我试图理解如何通过约束来做到这一点。我的想法是内在的内容大小会帮助我在这里,但我正在疯狂地试图让它工作。

I'm trying to understand how one might do this with constraints. My thought was that intrinsic content size would help me out here, but I'm flailing around wildly trying to get this to work.

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的大小。它应该可以通过其内容的大小来确定,但是......

I shouldn't have to hardcode the size of the titleView. It should be able to be determined via the size of its contents, but...


  1. titleView确定它的大小为0,除非我硬编码一帧。

  2. 如果我设置 translatesAutoresizingMaskIntoConstraints = NO 该应用程序崩溃并出现此错误:'自动布局执行-layoutSubviews后仍然需要。 UINavigationBar的-layoutSubviews实现需要调用super。'

  1. The titleView is determining it's size is 0 unless I hardcode a frame.
  2. If I set translatesAutoresizingMaskIntoConstraints = NO the app crashes with this error: 'Auto Layout still required after executing -layoutSubviews. UINavigationBar's implementation of -layoutSubviews needs to call super.'



更新



我得到它使用这段代码,但我仍然需要在titleView上设置框架:

Update

I got it to work with this code, but I'm still having to set the frame on the 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;


推荐答案

你必须设置<$ c $的框架c> titleView 因为您没有在其superview中为其位置指定任何约束。自动布局系统只能根据您指定的约束和<$ c为您找出 size titleView $ c>其子视图的内在内容大小。

You have to set the frame of titleView because you don't specify any constraints for its position in its superview. The Auto Layout system can only figure out the size of titleView for you from the constraints you specified and the intrinsic content size of its subviews.

这篇关于使用约束以编程方式构建titleView(或者通常使用约束构建视图)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆