以编程方式使用自动布局将子视图添加到 UICollectionView 不起作用
Posted
技术标签:
【中文标题】以编程方式使用自动布局将子视图添加到 UICollectionView 不起作用【英文标题】:Adding subview to UICollectionView using auto layout programmatically not working 【发布时间】:2014-08-08 19:54:31 【问题描述】:我从情节提要设置了UICollectionViewController
,它使用流式布局。到目前为止,它工作正常,即它的布局和单元格按预期工作。
现在,我正在尝试将UISearchBar
作为子视图添加到UICollectionView
。这就是我添加搜索栏的方式:
流程布局的sectionInset
设置为UIEdgeInsetsMake(44, 0, 0, 0)
为搜索栏腾出空间。
并在viewDidLoad
中添加如下代码:
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 768.0, 44.0f)];
// have also tried [[UISearchBar alloc] init] here.
[self.searchBar setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.collectionView addSubview:self.searchBar];
NSDictionary* viewDict = @@"mySearchBar": self.searchBar;
NSArray* sHorizontal = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[mySearchBar]|"
options:0
metrics:nil
views:viewDict];
NSArray* sVertical = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[mySearchBar(==44)]"
options:0
metrics:nil
views:viewDict];
[self.collectionView addConstraints:sHorizontal];
[self.collectionView addConstraints:sVertical];
约束非常简单。 searchBar
的左、右和上边缘固定在父视图的左、右和上边缘,其高度为 44。
问题是运行此代码时搜索栏不可见。我在viewDidAppear
中记录了searchBar
的帧值,发现它的帧设置为(0, 0, 0, 44),即宽度没有得到解决。
我还尝试了可视格式字符串H:|[mySearchBar(>=768)]|
,在这种情况下,searchBar
是可见的并且在它的位置,但不会在方向更改时调整大小,即在横向上也保持 768 点宽。
我在这里做错了什么?应该怎么做才能使所需的布局约束起作用?
我正在 iPad 模拟器 ios 7.1 上尝试这个。
我也尝试将搜索栏添加到标题视图,但它的行为与我需要的不同。
【问题讨论】:
如果viewDidLoad
中有搜索栏,为什么还要以编程方式添加搜索栏?它似乎独立于任何其他事件。
这是我添加到 viewDidLoad 以获得搜索栏的代码。它不在那里。 searchBar
是我添加的属性。
【参考方案1】:
解决了!
我仍然不确定为什么以前的方法不起作用,但我得到了这样的预期结果:
NSDictionary* viewDict = @@"mySearchBar": self.searchBar, @"myCollView": self.collectionView;
NSArray* sHorizontal = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[mySearchBar(==myCollView)]|"
options:0
metrics:nil
views:viewDict];
NSArray* sVertical = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[mySearchBar(==44)]"
options:0
metrics:nil
views:viewDict];
[self.collectionView addConstraints:sHorizontal];
[self.collectionView addConstraints:sVertical];
注意视觉格式字符串H:|[mySearchBar(==myCollView)]|
,这意味着搜索栏的宽度应该等于集合视图的宽度。集合视图作为myCollView
添加到viewDict
字典中。这按预期工作,搜索栏会根据方向变化调整大小。
需要注意的几点,之前我也尝试过使用NSLayoutConstraint
类的constraintWithItem:
方法。虽然 api 相当容易理解,但它只创建一个约束。所以我们必须根据所需的约束数量多次调用它,这可能很乏味。不仅如此,就我而言,使用这种方法设置“等宽”约束会崩溃,我不知道为什么。
另一方面,constraintsWithVisualFormat:
返回一个数组,其中包含满足可视格式字符串中的条件所需的所有约束。
【讨论】:
【参考方案2】:好吧,如果它是您想要的搜索栏,您可能希望它位于您的 collectionView 的正上方。这在情节提要中非常简单:您只需将搜索栏和搜索显示控制器拖到您的收藏视图上即可。但是,如果您必须以编程方式执行此操作,那么应该可以这样做:
- (void)viewDidLoad
[super viewDidLoad];
[self.collectionView registerClass:[UISearchBar class]
forSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:@"reuseIdentifier"];
- (UIView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
static NSString *reuseIdentifier = @"reuseIdentifier";
UISearchBar *searchBar = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:reuseIdentifier
forIndexPath:indexPath];
searchBar.delegate = self;
return searchBar;
【讨论】:
是的,我知道这一点。请看问题的最后一行。它的行为不符合我的要求。好吧,因为如果在 Collection 视图上调用 reloadData,搜索栏就会被清除。以上是关于以编程方式使用自动布局将子视图添加到 UICollectionView 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
如何使用自动布局(约束)将子视图添加到 UIPageViewController?