UIScrollView底層實(shí)現(xiàn)原理 - 簡單實(shí)現(xiàn)滾動(dòng)

20161208.jpg

****UIScrollView****是系統(tǒng)提供給我們的一種可以滾動(dòng)的視圖.
今天來研究一下它底層的實(shí)現(xiàn)原理.

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

可以知道UIscrollView繼承于UIView. 并且它可以進(jìn)行拖拽和縮放, 所以我們?nèi)IScrollView.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:**** 那我們是不是也才可以自己寫一個(gè)ScrollView呢???

Let's do it ??

首先創(chuàng)建一個(gè)滾動(dòng)視圖繼承于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;
    
    // 復(fù)位
    [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

這就是簡單的實(shí)現(xiàn)了UIScrollVeiw的滾動(dòng)功能. 如果有興趣可以在將contentSize等屬性及方法進(jìn)行補(bǔ)充.

知識(shí)點(diǎn)補(bǔ)充 - ****關(guān)于****frame****和****bounds

先說下iOS的坐標(biāo)系

iOS坐標(biāo)系.jpeg

iOS坐標(biāo)系以左上角為坐標(biāo)原點(diǎn)

****frame:**** 是以父視圖的坐標(biāo)系為標(biāo)準(zhǔn)來確定當(dāng)前視圖的位置
****bounds:**** 是以自身的左上角為坐標(biāo)系
****frame****可以說是描述一個(gè)可視的范圍****,****而****bounds****是描述可視范圍在內(nèi)容上的區(qū)域****, ****所有的子控件都是相對于內(nèi)容的****.****

以上是記錄我的學(xué)習(xí)過程, 還請大神們多多指導(dǎo), 哪里不對還請指正.
****PS:**** 如果覺得小弟寫的還可以點(diǎn)個(gè)??, 或者關(guān)注我, 以鼓勵(lì)我更快的成長, 小弟在此感激不盡.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容