KittenYang

跟左上角说拜拜,实现TableView下拉关闭

话不多说,先看今天要实现的效果图:

正如你看到的那样,今天我来介绍一下如何实现UITbaleView实现监听contentView的偏移量,然后去实现相应的操作(比如上面的gif里面就实现了dismissModalView)。其实我要坦白的一点是,这个真的没有什么技术含量,但这件事的意义在于它让你学会思考如何让你的App更加易用和人性化。就拿这个GIF来说,如今iPhone6/iPhone6 Plus的面世导致App在交互上也必须得跟着发生变化,在大屏上很难再够到顶部的 cancel 按钮。所以,用识别TableView下拉一定距离后实现关闭当前界面会十分方便。在我看到,大屏手机上顶部还有交互按钮的App全是反人类,全是没有用心做产品的表现。不是说只要放大界面撑满大屏幕就好了,我们要做的是思考如何舒服地使用大屏。

Back to topic!

代码很简单,只需要实现UIScrollViewDelegate的两个协议方法即可,它们分别是:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{}

1.首先要在你的.h文件中声明作为UIScrollView的委托。

就像这样:

@interface NearbyViewController : BaseViewController<UIScrollViewDelegate>

2.然后在对应的.m文件中实现那两个协议方法

这是写好的样子:

#pragma mark - UITableView Delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    float offset = self.tableView.contentOffset.y;
    if (offset < -160) {
        headerLabel.text = @"可以松手了";
    }

}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    float offset = self.tableView.contentOffset.y;
    if (offset < -160) {
        [self dismissViewControllerAnimated:YES completion:nil];
    }else{
        headerLabel.text = @"继续下拉关闭";
    }
}

现在你可能已经感觉到协议方法里面的代码就是用来监听tableView的偏移量的,没错,但是我们需要搞清楚如何监听偏移量。

3.contentOffset详解

什么是 contentOffset?contentOffset是 UIScrollView 的一个属性,这是它的定义:

@property(nonatomic)     CGPoint     contentOffset;   

我们看到这是一个结构体CGPoint,contentOffset里面有x,y

contentOffset是:当前显示内容的顶点(就是屏幕的左上角那个点)当对于整个ContentView顶点的偏移量

结合我用Paper画的图:

其中橙色的矩形就是整个ContentView,每次你只能看到它的一部分,也就是屏幕能显示的区域,这就是当前显示的内容。

看右上角的那个iPhone草图,当ContentView向上超出屏幕的时,上面的区域就contentOffset,而且contentOffset.x 等于 0,因为水平方面没有偏移,contentOffset.y 有值而且是个正值。我们规定向上超出是正方向

这种偏移量为正数的情况我们可以用来实现监听上拉的距离,请看上方图片左下角的iPhone草图。绿色文字表示的区域就是我们想求得的上拉偏移量。怎么求呢?看图,就是a-b,a是屏幕的高度,b是橙色的contentView的高度减去顶部超出的contentOffset,这样就求得了上拉的距离。


而GIF图中的情况是下拉,这时候就很简单了,因为这个时候contentView的顶部反而比屏幕的上边沿要靠下,也就是屏幕反而会露出一块,这时contentOffset就是负数了。很简单,只要取得这个偏移量然后判断一下就行了:

    float offset = self.tableView.contentOffset.y;
    if (offset < -160) {
        [self dismissViewControllerAnimated:YES completion:nil];
    }

So easy,isn't it?


转载请注明出处,万分感谢!

KittenYang

写写代码,做做设计,看看产品。