【问题标题】:UIView created from nib and autolayout not constrained to superview从 nib 和自动布局创建的 UIView 不受超级视图的限制
【发布时间】: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


【解决方案1】:

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

【讨论】:

  • 我用 minimumFontSize 尝试了adjustsFontSizeToFitWidth,但没有成功。我宁愿不使用 UITextView。我的 UILabel 有 numberoflines 0 所以它应该使用所需的行数而不是一个非常大的行。
  • hmmm,把lineBreakMode设置成NSLineBreakByWordWrapping怎么样?
  • 另外,似乎我正在查看 ios6 文档作为我的第一个答案,来自 8.1 文档:"In iOS 6 and earlier, this property is effective only when the numberOfLines property is set to 1."
  • 我使用的是 NSLineBreakByWordWrapping。关于adjustsFontSizeToFitWidth,我真的不希望我的标签改变它的大小,而是有多行。无论如何,我已经看到我有一些自动布局警告,所以我要编辑我的问题。
  • 我查看了您的第三次编辑,但奇怪的是您仍然遇到与 NSAutoresizingMaskLayoutConstraint 相关的错误,这显然是指自动调整掩码。仍然有一些东西试图使用这些面具。此外,您如何设置笔尖及其插座可能存在一些问题,特别是我指的是笔尖的“所有者”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-17
  • 1970-01-01
  • 2011-11-25
相关资源
最近更新 更多