容器视图的框架设置为CGRectZero使用编程自动布局时 [英] Container View's Frame Set to CGRectZero when Using Programmatic Auto Layout

查看:171
本文介绍了容器视图的框架设置为CGRectZero使用编程自动布局时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个的UIView 的子类,将可以在任何视图控制器的底部似乎表明一个提示/错误信息/成功消息的/ etc工具提示。工具提示视图有两个子视图:一个的UILabel 上的右侧的左侧和的UIView ,这可以是任何东西(但经常被用作一个的UIButton )。

I have a UIView subclass that will be a tooltip that can appear on the bottom of any view controller to show a hint/error message/success message/etc. The tooltip view has two subviews: a UILabel on the left-hand side and a UIView on the right hand side, that can be anything (but is often used as a UIButton).

TooltipView.h

@interface TooltipView : UIView

@property (nonatomic, readonly) UILabel *textLabel;

@property (nonatomic) UIView *rightView;

TooltipView.m

static CGFloat const kSubviewToSuperviewSpacing = 7.0f;
static CGFloat const kTextLabelToRightViewHorizontalSpacing = 7.0f;

@implementation TooltipView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];

    if (self) {
        _textLabel = [[UILabel alloc] init];
        _textLabel.numberOfLines = 0;
        [_textLabel setTranslatesAutoresizingMaskIntoConstraints:NO];

        [self addSubview:_textLabel];
    }

    return self;
}

- (void)setRightView:(UIView *)rightView {
    if (_rightView != rightView) {
        _rightView = rightView;

        [self addSubview:_rightView];

        [self setNeedsDisplay];
    }
}

- (BOOL)translatesAutoresizingMaskIntoConstraints {
    return NO;
}

- (void)updateConstraints {
    self.didUpdateConstraints = YES;

    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.textLabel
                                                     attribute:NSLayoutAttributeLeading
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:NSLayoutAttributeLeading
                                                    multiplier:1.0f
                                                      constant:kSubviewToSuperviewSpacing]];

    NSMutableDictionary *metricsDictionary = [@{@"subviewToSuperviewSpacing": @(kSubviewToSuperviewSpacing)} mutableCopy];

    NSMutableDictionary *viewsDictionary = [@{@"textLabel": self.textLabel} mutableCopy];

    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-subviewToSuperviewSpacing-[textLabel]-subviewToSuperviewSpacing-|"
                                                                 options:0
                                                                 metrics:metricsDictionary
                                                                   views:viewsDictionary]];

    if (self.rightView) {
        metricsDictionary[@"textLabelToRightViewHorizontalSpacing"] = @(kTextLabelToRightViewHorizontalSpacing);
        viewsDictionary[@"rightView"] = self.rightView;

        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-subviewToSuperviewSpacing-[rightView]-subviewToSuperviewSpacing-|"
                                                                     options:0
                                                                     metrics:metricsDictionary
                                                                       views:viewsDictionary]];

        [self addConstraint:[NSLayoutConstraint constraintWithItem:self.rightView
                                                         attribute:NSLayoutAttributeTrailing
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:self
                                                         attribute:NSLayoutAttributeTrailing
                                                        multiplier:1.0f
                                                          constant:kSubviewToSuperviewSpacing]];
    }

    [super updateConstraints];
}

我也有一个视图控制器与的UILabel rightView 来进行测试。它的子类的UIViewController ,它的唯一的方法是覆盖的loadView

I also have a view controller to test this with a UILabel as the rightView. It subclasses UIViewController, and its only method is overriding loadView:

- (void)loadView {
    TooltipView *tooltipView = [[TooltipView alloc] initWithFrame:CGRectZero];

    tooltipView.textLabel.text = @"Test 1";

    UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    testLabel.text = @"Hello there";
    [testLabel setTranslatesAutoresizingMaskIntoConstraints:NO];

    tooltipView.rightView = testLabel;

    self.view = tooltipView;

}

最后,在我想要显示工具提示视图控制器,我添加了TooltipViewController作为一个子视图控制器。最终,这会被一些事件触发,但是出于测试目的,我这个正在 viewWillAppear中加入:

Finally, in the view controller where I want to display a tooltip, I add the TooltipViewController as a child view controller. Eventually, this will be triggered by some event, but for testing purposes, I have this being added in viewWillAppear:.

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    self.aViewController = [[TooltipViewController alloc] init];
    self.aViewController.view.backgroundColor = [UIColor whiteColor];

    [self addChildViewController:self.aViewController];

    [self.view addSubview:self.aViewController.view];

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|"
                                                                  options:0
                                                                  metrics:nil
                                                                    views:@{@"view": self.aViewController.view}]];

    [self.aViewController.view addConstraint:[NSLayoutConstraint constraintWithItem:self.aViewController.view
                                                      attribute:NSLayoutAttributeHeight
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:nil
                                                      attribute:NSLayoutAttributeNotAnAttribute
                                                     multiplier:1.0f
                                                       constant:150.0f]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.aViewController.view
                                                      attribute:NSLayoutAttributeBottom
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self.view
                                                      attribute:NSLayoutAttributeBottom
                                                     multiplier:1.0f
                                                       constant:0.0f]];

    [self.aViewController didMoveToParentViewController:self];
}

然而,在运行时,为textLabel rightView 似乎是正确设置,但帧的帧的 tooltipView 设置为 CGRectZero ,没有三视图出现在屏幕上。

However, at runtime, the frames of the textLabel and rightView seem to be set correctly, but the frame of the tooltipView is set to CGRectZero, and none of the three views appear on screen.

在此先感谢!

修改

我甚至已经试过删除为textLabel rightView 完全,所以只领先一个普通的UIView,尾随,底部和高度的限制。没有什么是模糊的,但视图的框架仍然是 CGRectZero

I've even tried removing the textLabel and rightView entirely, so just a plain UIView with leading, trailing, bottom, and height constraints. Nothing is ambiguous, but the frame of the view is still CGRectZero.

推荐答案

原来的解决方案是简单地的初始化调用 setTranslatesAutoresizingMaskIntoConstraints TooltipView ,而不是覆盖方法。这导致视图以正确显示。 H / T亚伦·汤普森(<一个href=\"https://twitter.com/aaptho/status/612815498661773312\">https://twitter.com/aaptho/status/612815498661773312).

It turns out the solution was simply to call setTranslatesAutoresizingMaskIntoConstraints in the initializer of TooltipView rather than overriding the method. This caused the view to appear correctly. h/t to Aaron Thompson (https://twitter.com/aaptho/status/612815498661773312).

这篇关于容器视图的框架设置为CGRectZero使用编程自动布局时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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