容器视图的框架设置为CGRectZero使用编程自动布局时 [英] Container View's Frame Set to CGRectZero when Using Programmatic Auto Layout
问题描述
我有一个的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
.
推荐答案
原来的解决方案是简单地的初始化调用
,而不是覆盖方法。这导致视图以正确显示。 H / T亚伦·汤普森(<一个href=\"https://twitter.com/aaptho/status/612815498661773312\">https://twitter.com/aaptho/status/612815498661773312). setTranslatesAutoresizingMaskIntoConstraints
TooltipView
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屋!