如何以编程方式添加自动布局 XIB?

How to do Auto Layout XIB being added programmatically?

我正在尝试以编程方式添加子视图,以便人们可以水平滚动到另一个部分。但看起来子视图不适合 SuperView 并且内容不显示

这是我来自 ViewController.m

的代码
- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    for (int i = 0; i < 2; i++)
    {
        CGRect frame;
        frame.origin.x = self.scrollView.frame.size.width * i;
        frame.size = self.scrollView.frame.size;
        self.scrollView.pagingEnabled = YES;

        NewsSection *sectionView = [[NewsSection alloc] initWithFrame:frame];            

        [self.scrollView addSubview:sectionView];
    }

    self.scrollView.contentSize =  CGSizeMake(self.scrollView.frame.size.width * 2, self.scrollView.frame.size.height);


}

这是我的故事板和约束条件。

这是我的 NewsSection.xib

这是我的代码 NewsSection.m

-(id) initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if(self) {
        [[NSBundle mainBundle] loadNibNamed:@"NewsSection" owner:self options:nil];

        [self addSubview:self.view];
    }
    return self;
}

这就是我看到的结果

更新: 产品代码在这里 https://github.com/noppanit/UIScrollViewAutoLayout

很难从外部判断需要做什么。

您很可能需要做的一些事情:

将视图上的 translatesAutoresizingMaskIntoConstraints 设置为 NO,这样它就不会创建与现有视图层次结构上的约束冲突的全新约束集。

在代码中为新添加的视图添加约束,将其锚定到新的视图层次结构中。您必须在将其添加为子视图后添加约束。您可能需要设置前沿和顶部约束,然后是高度和宽度或尾随和底部约束。

您可能需要使用方法

+ constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:

我将从阅读有关 UIScrollView 和 Autolayout 的文章开始:https://developer.apple.com/library/ios/technotes/tn2154/_index.html

现在,这里有一些示例代码可以让您继续前进。您只需要让 NewsView 由 ViewController 管理,例如NewsViewController,并在 setupNewsView 中使用之前初始化 NewsViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setupNewsView];
}

- (void) setupNewsView
{
     UIView *newsView = [[NewsSection alloc] initWithFrame:CGRectZero];

    self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
    newsView.translatesAutoresizingMaskIntoConstraints = NO;

    [self.scrollView addSubview:newsView];

    NSDictionary *viewsDict = @{ @"newsView": newsView };

    [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[newsView]|"
                                                                            options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom
                                                                            metrics:nil
                                                                              views:viewsDict]];
    [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[newsView]|"
                                                                        options:0
                                                                        metrics:nil
                                                                          views:viewsDict]];

    [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:newsView
                                                                attribute:NSLayoutAttributeWidth
                                                                relatedBy:NSLayoutRelationEqual
                                                                   toItem:self.scrollView
                                                                attribute:NSLayoutAttributeWidth
                                                               multiplier:1.0f
                                                                 constant:0.0f]];

    [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:newsView
                                                                attribute:NSLayoutAttributeHeight
                                                                relatedBy:NSLayoutRelationEqual
                                                                   toItem:self.scrollView
                                                                attribute:NSLayoutAttributeHeight
                                                               multiplier:1.0f
                                                                 constant:0.0f]];
}

编辑:

对不起。我之前错过了在我的解决方案中添加这一行:

[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[newsView]|"
                                                                        options:0
                                                                        metrics:nil
                                                                          views:viewsDict]];

关于您的代码示例:首先,完全按照我的代码示例描述填写您的 ViewController。我已经将更改合并到第一个示例中。同时删除覆盖 viewDidLayoutSubviews.

的代码

然后,您需要更改 NewsView 的初始值设定项。

现在看起来像这样:

-(id) initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if(self) {
        [[NSBundle mainBundle] loadNibNamed:@"NewsSection" owner:self options:nil];

        [self addSubview:self.view];
    }
    return self;
}

这里的一个问题是您加载了 nib 但没有将来自 nib 的视图分配给您的视图对象。引用 (https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/NSBundle_UIKitAdditions/index.html) 描述了 loadNibNamed:owner:options: returns 所有顶级对象。由于我们的 xib 中有一个顶级对象,因此我们需要将其分配给我们自己。这有点 hacky 并且引入了 nib 将来会泄漏的问题。所以最好在这里用 XIB 制作一个 UIViewController。

为了使您的代码正常工作,NewsView 的初始值设定项应如下所示。但它不会连接您的插座。

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self = [[NSBundle mainBundle] loadNibNamed:@"NewsSection" owner:self options:nil][0];
    }
    return self;
}