从笔尖和自动布局创建的UIView不限于superview

时间:2015-01-12 23:36:03

标签: ios objective-c uiview autolayout

在我的上一个ios项目中,我一直在使用包含这些组件和约束的子视图:

V:|-5-[image(70)]-5-[label]-5-[button]-5-|
H:|-5-[label]-5-|

如果在带有IB的ViewController中创建此子视图,则一切正常。 现在我需要在其他一些ViewControllers中创建这个子视图,所以我认为这是从笔尖创建可重用的自定义子视图而不是在每个视图控制器中创建它的好时机。 我已经使用了相同的组件和约束,并且已将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方法中。 &GT;&GT;仍然是相同的警告。
  • 我改变了弹出式约束的优先级。例如,这个:

    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]];
    

这会删除所有垂直和水平警告,但我的弹出窗口非常大。

1 个答案:

答案 0 :(得分:0)

也许在自定义视图的文本字段中使用adjustsFontSizeToFitWidth以及minimumFontSize属性可以实现您正在寻找的结果。否则,使用UITextView可能会有用,因为它可以滚动浏览您的内容。