iOS开发实战——CollectionView点击事件与键盘隐藏结合案例

Posted 乞力马扎罗的雪CYF

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS开发实战——CollectionView点击事件与键盘隐藏结合案例相关的知识,希望对你有一定的参考价值。

        我在前一篇博客中《iOS开发实战——CollectionView点击事件与键盘隐藏结合案例》详细实现了CollectionView与键盘组合操作中出现的多种情况,并解决了交互体验上的一些问题。在实际项目中也的确可以采用这种方法来操作。但是问题来了,原来的界面我们是使用UIView来操作的,也就是界面是不可滚动的。然而更为常见的场景是一个ScrollView,界面可以进行上下滚动。所以,这篇博客主要是对前一个案例进行优化。还有一个问题是,在自动布局Masonry结合ScrollView中,会碰到一些坑和技巧,也是我们主要解决的问题。项目代码上传至  https://github.com/chenyufeng1991/ShowHiddenKeyboard

今天要实现的效果如下:



由于大部分功能和之前的类似,我把重点放在ScrollView和Masonry的结合上。

(1)UI布局的思路是:最外面是一个ScrollView,然后里面放一个取名为contentView的UIView,作为放置其他元素的容器。contentView的高度会随着内部元素的总高度的变化而变化,也就是ScrollView需要滚动的总高度。

// 最外部的scrollView
    self.scrollView = [[UIScrollView alloc] init];
    self.scrollView.backgroundColor = [UIColor orangeColor];
    self.scrollView.scrollEnabled = YES;
    self.scrollView.userInteractionEnabled = YES;
    self.scrollView.bounces = NO;
    self.scrollView.delegate = self;
    self.automaticallyAdjustsScrollViewInsets = NO;
    [self.view addSubview:self.scrollView];
    [self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(weakSelf.view).offset(64);
        make.left.equalTo(weakSelf.view);
        make.right.equalTo(weakSelf.view);
        make.bottom.equalTo(weakSelf.view);
    }];

    // 包含所有子View的容器
    self.contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 64, [[UIScreen mainScreen] bounds].size.width, 200)];
    self.contentView.backgroundColor = [UIColor redColor];
    [self.scrollView addSubview:self.contentView];
    [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(weakSelf.scrollView);
        make.width.equalTo(weakSelf.scrollView);
    }];

这里设定ScrollView铺满全屏。而里面的contentView也是铺满整个ScrollView,并且一定要显式的设置宽度等于scrollView的宽度,也就是水平不可滑动。

在设置scrollView时建议加上self.automaticallyAdjustsScrollViewInsets = NO。这个参数比较坑爹,默认是YES,也就是默认在你使用scrollView的时候给你加了内边距,而这个往往是我们不需要的。如果默认置为YES的话,发现UI怎么都调不出我们想要的效果,往往会在顶部一部分。【ps:其实在这里你也可以考虑到是导航栏的原因,看你个人需求是ScrollView是否要到达屏幕顶部还是只到达导航栏底部。】


(2)由于我要让界面有滑动的效果,所以要让ScrollView里面的contentSize大于height,所以我在下面铺了一张很长的图片来模拟。

self.bottomImageView = [[UIImageView alloc] init];
    self.bottomImageView.image = [UIImage imageNamed:@"bottom"];
    [self.contentView addSubview:self.bottomImageView];
    [self.bottomImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(weakSelf.collectionView.mas_bottom).offset(20);
        make.left.equalTo(weakSelf.contentView);
        make.right.equalTo(weakSelf.contentView);
        make.height.equalTo(@500);
    }];

(3)其实自动布局写到这里的时候,所有的设置都已经完成了。但是一运行代码,发现并不是这样的。ScrollView根本就不能滚动。原来想的是:contentView由于add了很多的元素,所以contentView的高度就应该是这些元素实际布局中的总和。Masonry理应有这种自动计算的功能,但事实却不是这样的。调试上面的代码会发现contentView的高度居然是0. 查看约束设置代码,我们的确没有显式的设置高度。很遗憾,Masonry没有自动完成这个功能。所以需要在上面的子元素约束完成以后,实现如下代码:

    // 这里要重新设置容器的高度,其实只要固定底部即可。
    [self.contentView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.bottomImageView);
    }];
更新contentView容器的约束。也就是添加了底部约束到那张长长的图片的底部,这样也就相当于设置了高度。这样ScrollView就能正常滚动了。

(4)对于CollectionView的处理同前一个案例一样,这里不再赘述。由于添加了ScrollView,所以原先touchesEnded方法就不会被调用了,因为手势操作首先会去触发ScrollView中的操作。所以我们就要来实现ScrollViewDelegate中的方法来实现键盘隐藏。

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self hideKeyboard];
}

当ScrollView开始滚动的时候隐藏键盘。由于此时的背景空白区域是contentView,所以添加一个tap手势:

    UITapGestureRecognizer *tapView = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                          action:@selector(hideKeyboard)];
    [self.contentView addGestureRecognizer:tapView];


        经过以上实现后,就能实现ScrollView、CollectionView和键盘之间的事件处理了,也就是上面Gif中的动效。其实实现的关键就是上面ScrollView和Masonry的结合上。


以上是关于iOS开发实战——CollectionView点击事件与键盘隐藏结合案例的主要内容,如果未能解决你的问题,请参考以下文章

ios开发之-- tableview/collectionview获取当前点击的cell

ios开发如何去掉cell的点击阴影

ios:在点击collectionview单元格或tableview单元格时禁用第二个触摸事件

iOS 在CollectionView上做展开收起动画

IOS Swift3卡栈覆盖

iOS开发之资讯类App常用分类控件的封装与实现(CollectionView+Swift3.0+)