UIScrollView底层实现原理 - 简单实现滚动

作者: Schorem | 来源:发表于2016-12-08 15:02 被阅读689次
    20161208.jpg

    ****UIScrollView****是系统提供给我们的一种可以滚动的视图.
    今天来研究一下它底层的实现原理.

    NS_CLASS_AVAILABLE_IOS(2_0) @interface UIScrollView : UIView <NSCoding>
    

    可以知道UIscrollView继承于UIView. 并且它可以进行拖拽和缩放, 所以我们去UIScrollView.h中找看有没有这两种手势.

    // Change `panGestureRecognizer.allowedTouchTypes` to limit scrolling to a particular set of touch types.
    @property(nonatomic, readonly) UIPanGestureRecognizer *panGestureRecognizer NS_AVAILABLE_IOS(5_0);
    // `pinchGestureRecognizer` will return nil when zooming is disabled.
    @property(nullable, nonatomic, readonly) UIPinchGestureRecognizer *pinchGestureRecognizer NS_AVAILABLE_IOS(5_0);
    

    ****So:**** 那我们是不是也才可以自己写一个ScrollView呢❓❓❓

    Let's do it ❗️

    首先创建一个滚动视图继承于UIView.

    ![2016120896425屏幕快照 2016-12-08 下午2.37.04.png](http://oh73tojig.bkt.clouddn.com/2016120896425屏幕快照 2016-12-08 下午2.37.04.png)

    上代码

    //
    //  LPScrollView.m
    //  LPScrollView
    //
    //  Created by 刘鹏 on 2016/12/8.
    //  Copyright © 2016年 刘鹏. All rights reserved.
    //
    
    #import "LPScrollView.h"
    
    @implementation LPScrollView
    
    - (instancetype)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        if (self) {
            UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)];
            [self addGestureRecognizer:pan];
        }
        return self;
    }
    
    - (void)panAction:(UIPanGestureRecognizer *)pan {
        
        // 获取手指的偏移量
        CGPoint transP = [pan translationInView:pan.view];
        NSLog(@"%@", NSStringFromCGPoint(transP));
        
        // 修改bounds
        CGRect bounds = self.bounds;
        bounds.origin.y -= transP.y;
        self.bounds = bounds;
        
        // 复位
        [pan setTranslation:CGPointZero inView:pan.view];
        
    }
    
    @end
    

    使用

        LPScrollView *scrollView = [[LPScrollView alloc]initWithFrame:self.view.bounds];
        [self.view addSubview:scrollView];
        
        UIView *redView = [[UIView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
        redView.backgroundColor = [UIColor redColor];
        [scrollView addSubview:redView];
    

    效果图

    2016120852353Untitled.gif

    这就是简单的实现了UIScrollVeiw的滚动功能. 如果有兴趣可以在将contentSize等属性及方法进行补充.

    知识点补充 - ****关于****frame****和****bounds

    先说下iOS的坐标系

    iOS坐标系.jpeg

    iOS坐标系以左上角为坐标原点

    ****frame:**** 是以父视图的坐标系为标准来确定当前视图的位置
    ****bounds:**** 是以自身的左上角为坐标系
    ****frame****可以说是描述一个可视的范围****,****而****bounds****是描述可视范围在内容上的区域****, ****所有的子控件都是相对于内容的****.****

    以上是记录我的学习过程, 还请大神们多多指导, 哪里不对还请指正.
    ****PS:**** 如果觉得小弟写的还可以点个👍, 或者关注我, 以鼓励我更快的成长, 小弟在此感激不尽.

    相关文章

      网友评论

        本文标题:UIScrollView底层实现原理 - 简单实现滚动

        本文链接:https://www.haomeiwen.com/subject/oersmttx.html