****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];
效果图
这就是简单的实现了UIScrollVeiw的滚动功能. 如果有兴趣可以在将contentSize等属性及方法进行补充.
知识点补充 - ****关于****frame****和****bounds
先说下iOS的坐标系
iOS坐标系以左上角为坐标原点
****frame:**** 是以父视图的坐标系为标准来确定当前视图的位置
****bounds:**** 是以自身的左上角为坐标系
****frame****可以说是描述一个可视的范围****,****而****bounds****是描述可视范围在内容上的区域****, ****所有的子控件都是相对于内容的****.****
以上是记录我的学习过程, 还请大神们多多指导, 哪里不对还请指正.
****PS:**** 如果觉得小弟写的还可以点个👍, 或者关注我, 以鼓励我更快的成长, 小弟在此感激不尽.