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的结合上。

时间: 2024-10-26 08:35:05

iOS开发实战——CollectionView点击事件与键盘隐藏结合案例(二)的相关文章

iOS开发实战——CollectionView中cell的间距设置

我在前面多篇博客中详细讲解了CollectionView的使用与自定义CollectionViewCell的设计,可以参考<iOS开发实战--CollectionView点击事件与键盘隐藏结合案例><iOS高级开发--CollectionView修改cell的文本及模型重构>这几篇博客.但是今天还是需要来讲讲CollectionView实现中的一个小小的坑,这是我最近在网上浏览时发现很多开发者经常犯的错,所以我觉得有必要来好好谈一谈. 一个CollectionView控件中,两个c

[转]iOS Safari 中click点击事件失效的解决办法

iOS Safari 中click点击事件失效的解决办法 问题起因: 在微信公众号开发(微站)过程中用jquery的live方法绑定的click事件点击无效(不能执行) 问题描述 当使用委托给一个元素添加click事件时,如果事件是委托到 document 或 body 上,并且委托的元素是默认不可点击的(如 div, span 等),此时 click 事件会失效. 解决办法 解决办法有 4 种可供选择: ?将 click 事件直接绑定到目标?元素(??即 .target)上 将目标?元素换成 

Xamarin iOS开发实战第1章使用C#编写第一个iOS应用程序

Xamarin iOS开发实战第1章使用C#编写第一个iOS应用程序 C#原本是用来编写Windows以及Windows Phone的应用程序.自从Xamarin问世后,C#的作用就发生了很大的变化.它不仅可以编写关于Windows以及Windowsx Phone的应用程序,还可以编写iOS.Android的应用程序.本章将讲解如何使用C#编写一个简单的iOS应用程序.本文选自<Xamarin iOS开发实战> 1.1初识Xamarin Xamarin是一个跨平台的开发框架.Xamarin的产

iOS开发——实战OC篇&amp;环境搭建之Xib(玩转UINavigationController与UITabBarController)

iOS开发——实战OC篇&环境搭建之Xib(玩转UINavigationController与UITabBarController) 前面我们介绍了StoryBoard这个新技术,和纯技术编程的代码创建界面,本篇我们将介绍一个老的技术,但是在很多的公司或者库里面还是使用这个技术,既然如此它肯定有他的好处,至于好处这里我就不一一介绍了.在Xcode5之前是只能使用Xib或者代码的,而代码又对于很多初学者来说算是一个难题.毕竟不知道怎么下手.所以我就总结了一下这段时间自己编写程序的一个实例来说明怎么

iOS开发——实战OC篇&amp;环境搭建之纯代码(玩转UINavigationController与UITabBarController)

iOS开发——实战OC篇&环境搭建之纯代码(玩转UINavigationController与UITabBarController) 这里我们就直接上实例: 一:新建一个项目singleView Controller,命名未iCocos 二:由于我们使用的纯代码实现的,所以删除其中的StoryBoard和Viewtroller的两个文件 三:新建一个继承自TabBar Controller的类,我们命名问iCocos ViewController 三:在Appdelegate的实现文件中导入刚刚

李洪强iOS开发之-实现点击单行View显示和隐藏Cell

李洪强iOS开发之-实现点击单行View显示和隐藏Cell 实现的效果:  ....

Xamarin iOS开发实战上册-----2.2.2 使用代码添加视图

Xamarin iOS开发实战上册-----2.2.2  使用代码添加视图 如果开发者想要使用代码为主视图添加视图,该怎么办呢.以下将为开发者解决这一问题.要使用代码为主视图添加视图需要实现3个步骤. 1.实例化视图对象 每一个视图都是一个特定的类.在C#中,经常会说,类是一个抽象的概念,而非具体的事物,所以要将类进行实例化.实例化一个视图对象的具体语法如下: 视图类 对象名=new 视图类(); 以我们接触的第一个视图View为例,它的实例化对象如下: UIView vv=new UIView

Xamarin iOS开发实战1.1.3Xamarin版本

Xamarin iOS开发实战1.1.3Xamarin版本 Xamarin提供了免费版和付费版.免费版本包含Xamarin Studio服务.付费版本分为普通版299美元/年.商业版999美元/年和企业版1899美元/年.开发者可以根据自身需要进行购买,如图1.1所示.本文选自Xamarin iOS开发实战大学霸 图1.1  Xamarin各个版本 注意:针对学生及研究人员,Xamarin提供以99美元/年的价格购买商业版授权. 1.1.4  工具需求 要使用C#编写iOS应用程序,需要使用到3

高德 ios 自定义气泡添加点击事件无效问题

在使用高德地图sdk开发的时候,需要自定义气泡吹出框,发现气泡添加的点击事件或者button都没响应. 原因:自定义的气泡是添加到大头针上的,而大头针的size只有下面很小一部分,所以calloutView是在大头针的外面的.而 iOS 按钮超过父视图范围是无法响应事件的处理方法. 解决办法: 在CustomAnnotationView.m中重写hittest方法: - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {