使用自动布局以编程方式将子视图添加到UICollectionView无法正常工作

时间:2014-08-08 19:54:32

标签: ios objective-c uicollectionview autolayout uisearchbar

我从故事板中设置了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。

问题是运行此代码时搜索栏不可见。我在searchBar中记录了viewDidAppear的帧值,发现它的帧设置为(0,0,0,44),即宽度没有得到解析。

我还尝试了视觉格式字符串H:|[mySearchBar(>=768)]|,在这种情况下,searchBar是可见的并且在其位置但不会在方向更改时调整大小,即在景观中也保持768点宽。

我在这里做错了什么?应该怎样做才能使所需的布局约束起作用?

我在iPad模拟器iOS 7.1上尝试这个。

我也尝试将搜索栏添加到标题视图中,但它的行为与我的要求不同。

2 个答案:

答案 0 :(得分:5)

解决了!

我仍然不确定为什么以前的方法不起作用,但我得到了这样的预期结果:

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)]|,这意味着搜索栏的宽度应该等于集合视图的宽度。集合视图作为viewDict添加到myCollView字典中。这正在按预期工作,搜索栏会根据方向更改调整大小。

有几点需要注意,之前我也尝试使用constraintWithItem:类的NSLayoutConstraint方法进行相同的操作。虽然api相当容易理解,但它只创建了一个约束。因此,我们必须将其称为所需约束的次数,这可能是乏味的。不仅如此,在我的情况下,设置相同的宽度'这种方法的约束是崩溃,我无法弄清楚原因。

另一方面,constraintsWithVisualFormat:返回满足可视格式字符串中条件所需的所有约束的数组。

答案 1 :(得分:1)

好吧,如果它是你想要的搜索栏,你可能希望它在你的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;
}