
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.

上代碼
//
// 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ì)我更快的成長, 小弟在此感激不盡.