如何以编程方式添加自动布局 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;
}
我正在尝试以编程方式添加子视图,以便人们可以水平滚动到另一个部分。但看起来子视图不适合 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;
}