【发布时间】:2015-01-12 23:36:02
【问题描述】:
在我上一个 ios 项目中,我一直在使用带有这些组件和约束的子视图:
V:|-5-[image(70)]-5-[label]-5-[button]-5-|
H:|-5-[label]-5-|
如果这个子视图是用 IB 在ViewController 中创建的,那么一切都会很好。
现在我需要在其他一些ViewControllers 中创建这个子视图,所以我认为这是从 nib 创建可重用自定义子视图而不是在每个视图控制器中创建它的好时机。
我使用了这些相同的组件和约束,并将translatesAutoresizingMaskIntoConstraints 设置为NO。
当我想使用这个自定义视图时,这就是我在我的超级视图中所做的:
PopupView *customView = [[PopupView alloc] initWithFrame:CGRectZero];
[customView setMessage:@"This is supposed to a be a large text. This is supposed to a be a large text"];
[self.view addSubview:customView];
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(customView);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[customView]|"
options:0
metrics:nil
views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[customView]|"
options:0
metrics:nil
views:viewsDictionary]];
问题是:如果我的标签的文本太大,customView 的宽度非常大(包含标签所需的宽度)并且不受我的超级视图的限制。我以为我的代码的最后几行可以做到这一点,但似乎我遗漏了一些东西。
我是否需要做任何其他事情以使我的customView 被限制在我的超级视图范围内?
编辑 1: 我认为如果我输入我的代码会更好,这是我真实代码的较短版本,但它也失败了:
PopupView.h
#import <UIKit/UIKit.h>
@interface PopupView : UIView
{
UILabel *messageLb;
}
@property (nonatomic, strong) IBOutlet UILabel *messageLb;
- (void) setMessage:(NSString *)message;
@end
PopupView.m
#import "PopupView.h"
@implementation PopupView
@synthesize messageLb = _messageLb;
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
[self commonInit];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
[self commonInit];
}
return self;
}
- (void)commonInit
{
UIView *view = nil;
NSArray *objects = [[NSBundle mainBundle] loadNibNamed:@"PopupView" owner:self options:nil];
for (id object in objects)
{
if ([object isKindOfClass:[UIView class]])
{
view = object;
break;
}
}
if (view != nil)
{
view.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:view];
}
}
- (void) setMessage:(NSString *)message
{
[_messageLb setText:message];
}
@end
PopupView.xib
View
|___ View (with constraints 0-0-0-0 to its superview)
|___ label (with numberoflines 0 and constraints 5-5-5-5 to its superview)
编辑 2:我发现我有一些昨晚没有看到的自动布局警告(对不起,我太困了)。
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this: (1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand,
refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x145982e0 'UIView-Encapsulated-Layout-Height' H:[UIView:0x14593210(320)]>",
"<NSAutoresizingMaskLayoutConstraint:0x14592030 h=-&- v=-&- 'UIView-Encapsulated-Layout-Top' H:|-(0)-[UIView:0x14593210] (Names: '|':UITransitionView:0x14599db0 )>",
"<NSLayoutConstraint:0x145bdc40 H:|-(0)-[PopupView:0x14592b60] (Names: '|':UIView:0x14593210 )>",
"<NSLayoutConstraint:0x145adeb0 H:[PopupView:0x14592b60]-(0)-| (Names: '|':UIView:0x14593210 )>",
"<NSAutoresizingMaskLayoutConstraint:0x145a32c0 h=--& v=--& PopupView:0x14592b60.midX ==>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x145adeb0 H:[PopupView:0x14592b60]-(0)-| (Names: '|':UIView:0x14593210 )>
我也有这些关于 Vertical 的警告。 我可以看到,由于这种冲突,将我的视图固定到右边距的规则被打破了。 我尝试了两件事但没有成功:
- 我设置 self.view.translatesAutoresizingMaskIntoConstraints = NO;在使用此弹出窗口的 ViewController 的 viewWillAppear 方法中。 >> 还是一样的警告。
-
我更改了弹出框约束的优先级。例如,这个:
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(customView); [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat: @"H:|-0@1-[customView]-0@1-|" options:0 metrics:nil views:viewsDictionary]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat: @"V:|-0@1-[customView]-0@1-|" options:0 metrics:nil views:viewsDictionary]];
这会删除所有垂直和水平警告,但我的弹出窗口还很大。
【问题讨论】:
-
我终于找到了解决办法。我的问题是我在自我(Popview)和他们的子视图之间没有限制。一旦我设置了它们,一切就正常了。我从this post找到的解决方案。
标签: ios objective-c uiview autolayout