UIScrollView

一、简介

<<继承关系:UIScrollView --> UIView -->UIResponder-->NSObject

<<是UITableView和UITextView等UIKit类的父类

<<UIScrollView这个类(也就是滚动视图),可以让我们展示比window尺寸大的内容。用户可以通过手势来实现视图的滚动和缩放。

格式为

1--> 设置滚动条样式(属性的作用)

typedef NS_ENUM(NSInteger, UIScrollViewIndicatorStyle) {

    UIScrollViewIndicatorStyleDefault,    // black with white border. good against any background

    UIScrollViewIndicatorStyleBlack,      // black only. smaller. good against a white background

    UIScrollViewIndicatorStyleWhite        // white only. smaller. good against a black background

};(如果属性有枚举类型的话,这里会有枚举类型说明)

scrollView.indicatorStyle = UIScrollViewIndicatorStyleDefault;  (这是具体的例子)

@property(nonatomic) UIScrollViewIndicatorStyle indicatorStyle; // default is UIScrollViewIndicatorStyleDefault(这是属性的说明)

二、UIScrollView的内容视图属性(属性的顺序与苹果API一致)

1-->设置偏移量

scrollView.contentOffset = CGPointMake(314,200);

@property(nonatomic) CGPoint contentOffset; // 默认为 CGPointZero

2-->设置UIScrollView的内容视图的尺寸

scrollView.contentSize =CGSizeMake(314*3,500);//非常重要,这是UIScrollView的内容视图的尺寸,通常contentSize大于UIScrollView的frame

@property(nonatomic) CGSize contentSize; // 默认为CGSizeZero

3、设置内容的边缘

scrollView.contentInset =UIEdgeInsetsMake(0,50,50,0);

@property(nonatomic) UIEdgeInsets contentInset; //默认UIEdgeInsetsZero。在内容周围添加额外的滚动区域。

4、获得要绘制内容的调整区域

UIEdgeInsets edge= self.scrollView.adjustedContentInset;

@property(nonatomic, readonly) UIEdgeInsets adjustedContentInset API_AVAILABLE(ios(11.0),tvos(11.0));

参见:你可能需要为你的 App 适配 iOS 11

5、感知adjustedContentInset的变化,触发的方法

//重写方法

- (void)adjustedContentInsetDidChange

{

[super adjustedContentInsetDidChange];


//执行操作...

}

- (void)adjustedContentInsetDidChange API_AVAILABLE(ios(11.0),tvos(11.0)) NS_REQUIRES_SUPER;//UIScrollViewDelegate中的scrollViewDidChangeAdjustedContentInset方法同样能实现

6、设置UIScrollView的调整行为

typedef NS_ENUM(NSInteger, UIScrollViewContentInsetAdjustmentBehavior) {

    UIScrollViewContentInsetAdjustmentAutomatic, //和scrollableAxes一样,scrollView会自动计算和适应顶部和底部的内边距并且在scrollView 不可滚动时,也会设置内边距.

    UIScrollViewContentInsetAdjustmentScrollableAxes, //自动计算内边距.

    UIScrollViewContentInsetAdjustmentNever, //不计算内边距

    UIScrollViewContentInsetAdjustmentAlways, //根据safeAreaInsets 计算内边距

} API_AVAILABLE(ios(11.0),tvos(11.0));

if(@available(iOS11.0, *)) {

self.tableView.contentInsetAdjustmentBehavior =UIScrollViewContentInsetAdjustmentNever;

}else{

self.automaticallyAdjustsScrollViewInsets =NO;

}

@property(nonatomic) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior API_AVAILABLE(ios(11.0),tvos(11.0));//默认 UIScrollViewContentInsetAdjustmentAutomatic.

7、描述内容布局

  if (@available(iOS 11.0, *)) {

        UILayoutGuide *guide=self.scrollView.contentLayoutGuide;

    } else {

    }

@property(nonatomic,readonly,strong) UILayoutGuide *contentLayoutGuide API_AVAILABLE(ios(11.0),tvos(11.0));

8、整体布局信息

if (@available(iOS 11.0, *)) {

        UILayoutGuide *guide=self.scrollView.frameLayoutGuide;

    } else {

    }

@property(nonatomic,readonly,strong) UILayoutGuide *frameLayoutGuide API_AVAILABLE(ios(11.0),tvos(11.0));

9、设置UIScrollView的代理

scrollView.delegate=self;

@property(nullable,nonatomic,weak) id <UIScrollViewDelegate>delegate; //默认为nil. 弱引用

10、设置UIScrollView是否单方向运动

scrollView.directionalLockEnabled =YES;

@property(nonatomic,getter=isDirectionalLockEnabled) BOOL directionalLockEnabled; // 默认 NO

11、设置UIScrollView是否反弹

scrollView.bounces =NO;

@property(nonatomic) BOOL bounces; //默认的YES。如果是YES,从内容的边缘反弹回来

12、设置控制垂直方向遇到边框是否反弹

   scrollView.alwaysBounceVertical = NO;//控制垂直方向遇到边框是否反弹@property(nonatomic) BOOL alwaysBounceVertical; //默认是NO。如果YES和bounces是YES,即使内容小于界限,允许垂直拖动。

13、设置控制水平遇到边框是否反弹

    myScrollView.alwaysBounceHorizontal = NO;//控制水平遇到边框是否反弹

@property(nonatomic) BOOL alwaysBounceHorizontal; // 默认是NO.如果YES和bounces是YES,即使内容小于界限,允许水平拖动。

14、设置是否翻页

    myScrollView.pagingEnabled = NO; //是否翻页

@property(nonatomic,getter=isPagingEnabled) BOOL pagingEnabled __TVOS_PROHIBITED;//默认是NO。如果是,请停在视图边界的倍数上。

15、设置控制控件是否能滚动

    myScrollView.scrollEnabled = YES;//控制控件是否能滚动

@property(nonatomic,getter=isScrollEnabled) BOOL scrollEnabled; // 默认是YES。关闭任何拖拽。

16、设置垂直方向的滚动指示

    myScrollView.showsVerticalScrollIndicator =YES; //垂直方向的滚动指示

@property(nonatomic) BOOL showsVerticalScrollIndicator;//默认是YES

17、设置水平方向的滚动指示

 myScrollView.showsHorizontalScrollIndicator = NO;//水平方向的滚动指示

@property(nonatomic) BOOL showsVerticalScrollIndicator; //默认是YES

18、表示滚动指示器从封闭滚动视图中被嵌入的距离

UIEdgeInsets e = UIEdgeInsetsMake(0, 0, keyboardBounds.size.height, 0);

[[self tableView] setScrollIndicatorInsets:e];

@property(nonatomic) UIEdgeInsets scrollIndicatorInsets; // 默认为UIEdgeInsetsZero. 

19、设置滚动控制器的风格

typedefNS_ENUM(NSInteger, UIScrollViewIndicatorStyle) {

    UIScrollViewIndicatorStyleDefault,     //默认

    UIScrollViewIndicatorStyleBlack,       //黑色风格

    UIScrollViewIndicatorStyleWhite        //白色风格

};

scrollView .indicatorStyle=UIScrollViewIndicatorStyleDefault;

@property(nonatomic) UIScrollViewIndicatorStyle indicatorStyle; // 默认是 UIScrollViewIndicatorStyleDefault

20、设置滑动速度

  scrollView .decelerationRate=3;//浮点数,规定用户提起手指后的滚动减速速率

@property(nonatomic) CGFloat decelerationRate NS_AVAILABLE_IOS(3_0);//你的应用程序可以使用UIScrollViewDecelerationRateNormal和UIScrollViewDecelerationRateFast常量作为引用点以获得一个合理的减速速率。

21、设置滚动视图内容的偏移量,可以带动画效果

[scrollView setContentOffset:CGPointMake(_pageSize.width * self.page, 0) animated:NO];

- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated; // animate at constant velocity to new offset//

contentOffset,

内容视图原点的偏移点(以点的形式表示)。

animated,

若YES,用一个恒定的速度以动画形式移动到新的偏移处;NO则立即移动

22、设置滚动视图滚动到某个可见区域,可以带动画效果

[scrollView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];//scrollView滚动到顶部

- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated; //rect,定义内容视图区域的矩形。animated,若滚动应被动画化则传入YES,否则为NO。

该方法滚动内容视图以使rect中定义的区域可以刚好显示在滚动视图中。若区域已经是可见的,该方法什么也不做。

23、显示一个短暂的滚动指示器

[scrollView flashScrollIndicators];//建议在scrollView展示给用户时调用一下,以提醒用户该处可滑动

- (void)flashScrollIndicators; // displays the scroll indicators for a short time. This should be done whenever you bring the scroll view to front.

24、获取用户是否触及视图内容

BOOL isTracking=[scrollView isTracking];//只读属性

@property(nonatomic,readonly,getter=isTracking) BOOL tracking; //若用户已触摸内容视图但可以还示开始拖动时该属性值为YES。

25、表明用户是否开始滚动内容

 BOOL dragging=[scrollView dragging];//只读属性

@property(nonatomic,readonly,getter=isDragging) BOOL dragging; //该属性持有的值可能需要滚动一段时间或距离才会被设定成YES

26、获取视图是否开始减速(用户停止拖动但视图仍在滚动)

BOOL decelerating=[scrollView decelerating];//只读属性

@property(nonatomic,readonly,getter=isDecelerating) BOOL decelerating; //若用户已不再拖拽内容但滚动还在发生时返回YES。

27、设置视图是否延迟处理触摸事件

BOOL delaysContentTouches=[scrollView delaysContentTouches];

@property(nonatomic)BOOL delaysContentTouches; //规定滚动视图是否延迟处理触摸下压手势,若该属性值为YES,滚动视图会延迟处理下压手势直到可以确定该操作的意图是否是滚动。若值为NO,滚动视图会立即调用touchesShoudBegin:withEvent:inContentView:。默认值为YES。

28、设置控制触摸内容视图时是否总是导致跟踪

_scrollView.canCancelContentTouches=YES;

@property(nonatomic) BOOL canCancelContentTouches;//控制触摸内容视图时是否总是导致跟踪。若该属性的值为YES,内容中的视图会开始跟踪触摸的手指,若用户拖拽手指到足以滚动的距离,视图会收到touchesCancelled:withEvent:信息,而滚动视图会作为一个滚动事件处理这次触摸。若该属性的值为NO,滚动视图在内容视图开始跟踪时将无视手指移动,不进行滚动。默认值为YES。

29、在触摸事件开始相应前调用

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view{

     return YES;

}// 在UIScrollView的子类中重写该方法,用于返回是否将事件传递给对应的子视图,默认返回YES,如果返回NO,该事件不会传递给对应的子视图

- (BOOL)touchesShouldBegin:(NSSet*)touches withEvent:(UIEvent*)event inContentView:(UIView*)view;//返回yes - 将触摸事件传递给相应的subView; 返回no - 直接滚动scrollView,不传递触摸事件到subView 

30、当设置canCancelContentTouches=YES时,触摸事件响应前会调用该方法

-(BOOL)touchesShouldCancelInContentView:(UIView*)view{

if([view isKindOfClass:[UIButtonclass]]) {

returnYES; 

 }

return[super touchesShouldCancelInContentView:view];

}

- (BOOL)touchesShouldCancelInContentView:(UIView *)view;在UIScrollView的子类中重写该方法,用于返回是否取消已经传递给子视图的事件,默认当子视图是UIControl时返回NO,否则返回YES(注: 该方法被调用的前提是canCancelContentTouches = YES)

参见:iOS实现ScrollView中子控件(Button,自定义View)的触摸事件响应

四、UIScrollView的Zoom属性

1-->设置 最小缩放比例

 scrollView.minimumZoomScale=0.5;

@property(nonatomic) CGFloat minimumZoomScale; // 默认是1.0

2-->设置 最大缩放比例

 scrollView.maximumZoomScale=1.5;//必须大于minimumZoomScale才能正常工作

@property(nonatomic) CGFloat maximumZoomScale; // 默认是1.0

3、设置缩放比例

scrollView.zoomScale =0.8;

@property(nonatomic) CGFloat zoomScale NS_AVAILABLE_IOS(3_0); // 默认是 1.0

4、指定当前缩放因子

[_scrollView setZoomScale:0.8 animated:YES];

- (void)setZoomScale:(CGFloat)scale animated:(BOOL)animated NS_AVAILABLE_IOS(3_0);

//scale

要缩放内容到的新值。

animated

若YES,动画化缩放到时新的缩放大小,NO则立即缩放。

5、设置缩放显示到某个区域,可以带动画效果

[_scrollView zoomToRect:newRect animated:YES];

- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated NS_AVAILABLE_IOS(3_0);//给定矩形的大小进行缩放

6、设置是否允许触底反弹

scrollView.bouncesZoom=NO;

@property(nonatomic) BOOL bouncesZoom; //若该属性的值为YES,在缩放超出最大值或最小值时,滚动视图会临时播放一个稍超出限制范围的动画再返回限制大小。若该属性为NO,缩放会在达到限制大小时立即停止,默认为YES。

  7、获取是否正在缩放模式

BOOL zooming= _scrollView.zooming;

@property(nonatomic,readonly,getter=isZooming) BOOL zooming;//用户发出了一个缩放手指,该值为YES,否则为NO

8、返回是否正在触底反弹

 BOOL zoomBouncing= _scrollView.zoomBouncing;

@property(nonatomic,readonly,getter=isZoomBouncing) BOOL zoomBouncing;//滚动视图缩放超出最大值或最小值时该值为YES;否则值为NO

 9、设置是否点击状态栏滚动到scrollView的最上端

 BOOL scrollsToTop= _scrollView.scrollsToTop;

@property(nonatomic) BOOL scrollsToTop __TVOS_PROHIBITED;// 是否允许点击状态栏让距离状态栏最近的scrollView滑动到顶部,默认为YES(注: 在iPhone中如果有多个将该属性设置为YES的scrollView,则该方法无效;在iPad中则将距离状态栏最近的scrollView滑动到顶部)

8、返回是否正在触底反弹

BOOL zoomBouncing= _scrollView.zoomBouncing;

@property(nonatomic,readonly,getter=isZoomBouncing) BOOL zoomBouncing;//滚动视图缩放超出最大值或最小值时该值为YES;否则值为NO

五、UIScrollView的手势属性

1-->获取当前用于滑动手势的手势识别器(只读)

  UIPanGestureRecognizer *pan=[_scrollView panGestureRecognizer];

@property(nonatomic, readonly) UIPanGestureRecognizer *panGestureRecognizer NS_AVAILABLE_IOS(5_0);

2-->获取当前用于扩张/收缩手势的手势识别器(只读)

 UIPinchGestureRecognizer *pin=[_scrollView pinchGestureRecognizer];

@property(nullable, nonatomic, readonly) UIPinchGestureRecognizer *pinchGestureRecognizer NS_AVAILABLE_IOS(5_0);

3、设置键盘消失的模式

typedefNS_ENUM(NSInteger, UIScrollViewKeyboardDismissMode) {

    UIScrollViewKeyboardDismissModeNone,//不隐藏键盘

    UIScrollViewKeyboardDismissModeOnDrag,      //手指滑动视图键盘就会消失

    UIScrollViewKeyboardDismissModeInteractive, //手指滑动视图后可以与键盘交互,上下滑动键盘会跟随手指上下移动

};

_scrollView.keyboardDismissMode=UIScrollViewKeyboardDismissModeNone;

@property(nonatomic) UIScrollViewKeyboardDismissMode keyboardDismissMode NS_AVAILABLE_IOS(7_0); // 默认是 UIScrollViewKeyboardDismissModeNone

4、设置刷新控件

//ios10新特性 自带刷新控件

self.refresh = [[UIRefreshControl alloc]init];

self.refresh.tintColor = [UIColor blueColor];//控制菊花的颜色

NSAttributedString *string = [[NSAttributedString alloc] initWithString:@"刷刷刷"];

self.refresh.attributedTitle = string;//菊花下面的文字,可利用NSAttributedString设置各种文字属性

[self.refresh addTarget:self action:@selector(start1) forControlEvents:(UIControlEventValueChanged)];//刷新方法

ScrollView.refreshControl = self.refresh;

备注:

1.默认的高度和宽度 

2.原来只适用于UITableViewController

3.当拉动刷新时,UIRefreshControl将在UIControlEventValueChanged事件下被触发

@property (nonatomic, strong, nullable) UIRefreshControl *refreshControl NS_AVAILABLE_IOS(10_0) __TVOS_PROHIBITED;

六、UIScrollView的UIScrollViewDelegate属性

1-->视图已经开始滑动时触发的方法

#pragma mark - scrollView delegate-(void)scrollViewDidScroll:(UIScrollView*)scrollView{

if([scrollView isKindOfClass:[UITableViewclass]]) {

// NSLog(@"------是列表---");

}else{

// NSLog(@"------是滚动试图----");

}

}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView; 

2-->视图已经开始缩放时触发的方法

-(void)scrollViewDidZoom:(UIScrollView*)scrollView{

CGFloat xcenter = scrollView.center.x, ycenter = scrollView.center.y;

}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView NS_AVAILABLE_IOS(3_2); 

3、视图开始拖动时触发的方法

// 当开始滚动视图时,执行该方法。一次有效滑动(开始滑动,滑动一小段距离,只要手指不松开,只算一次滑动),只执行一次。

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{

    NSLog(@"scrollViewWillBeginDragging");

}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;//将要开始拖拽时调用(注: 该方法可能需要先滑动一段时间或距离才会被调用)

4、当用户将要停止拖拽时调用

// 滑动scrollView,并且手指离开时执行。一次有效滑动,只执行一次。

// 当pagingEnabled属性为YES时,不调用,该方法

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{

    NSLog(@"scrollViewWillEndDragging");

}

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset NS_AVAILABLE_IOS(5_0);// 当用户停止拖拽时调用(注: 应用程序可以通过修改targetContentOffset参数的值来调整内容视图content view停止的位置)

5、视图拖动结束时触发的方法

// 滑动视图,当手指离开屏幕那一霎那,调用该方法。一次有效滑动,只执行一次。

// decelerate,指代,当我们手指离开那一瞬后,视图是否还将继续向前滚动(一段距离),经过测试,decelerate=YES

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

    NSLog(@"scrollViewDidEndDragging");

    if (decelerate) {

        NSLog(@"decelerate");

    }else{

        NSLog(@"no decelerate");

    }

    CGPoint point=scrollView.contentOffset;

    NSLog(@"%f,%f",point.x,point.y);

}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;// 当用户停止拖拽时调用(注: 如果内容视图content view在停止拖拽后继续移动,则decelerate参数为YES)

6、视图开始减速时触发的方法

// 滑动减速时调用该方法。

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{

    NSLog(@"scrollViewWillBeginDecelerating");

    // 该方法在scrollViewDidEndDragging方法之后。

}

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView; 

 7、视图减速结束时触发的方法

// 滚动视图减速完成,滚动将停止时,调用该方法。一次有效滑动,只执行一次。

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

    NSLog(@"scrollViewDidEndDecelerating");

    [_scrollView setContentOffset:CGPointMake(0, 500) animated:YES];

}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView; 

8、视图动画结束时触发的方法,使用set方法设置偏移量后回触发

// 当滚动视图动画完成后,调用该方法,如果没有动画,那么该方法将不被调用

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{

    NSLog(@"scrollViewDidEndScrollingAnimation");

    // 有效的动画方法为:

    //    - (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated 方法

    //    - (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated 方法

}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView; 

9、返回进行缩放的视图

// 返回将要缩放的UIView对象。要执行多次

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{

    NSLog(@"viewForZoomingInScrollView");

    return  self.imgView;

}

- (nullable UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView; 

10、将要开始缩放时调用

// 当将要开始缩放时,执行该方法。一次有效缩放,就只执行一次。

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view{

    NSLog(@"scrollViewWillBeginZooming");

}

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view NS_AVAILABLE_IOS(3_2); 

11、视图内容结束缩放时触发的方法

// 当缩放结束后,并且缩放大小回到minimumZoomScale与maximumZoomScale之间后(我们也许会超出缩放范围),调用该方法。

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale{

    NSLog(@"scrollViewDidEndZooming");

}

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view atScale:(CGFloat)scale; 

12、返回yes,开启快捷滚动回顶端,将要滚动时调用

// 指示当用户点击状态栏后,滚动视图是否能够滚动到顶部。需要设置滚动视图的属性:_scrollView.scrollsToTop=YES;

- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView{

    return YES;

}

- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView;

13、当scrollView已经滑动到顶部时调用(仅当点击状态栏让scrollView滑动到顶部才调用)

// 当滚动视图滚动到最顶端后,执行该方法

- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView{

    NSLog(@"scrollViewDidScrollToTop");

}

- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView; 

14、当滚动视图的inset值发生变化时调用

- (void)scrollViewDidChangeAdjustedContentInset:(UIScrollView *)scrollView {

    NSLog(@"scrollViewDidChangeAdjustedContentInset");

}

- (void)scrollViewDidChangeAdjustedContentInset:(UIScrollView *)scrollView API_AVAILABLE(ios(11.0), tvos(11.0));

Tip:判断uiscrollview是向上滚动还是向下滚动

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{

    int currentPostion = scrollView.contentOffset.y; 

    if (currentPostion - _lastPosition > 25) { 

        _lastPosition = currentPostion; 

        NSLog(@"ScrollUp now"); 

    } 

    else if (_lastPosition - currentPostion > 25) 

    { 

        _lastPosition = currentPostion; 

        NSLog(@"ScrollDown now"); 

    } 

}

参考

iOS开发UIScrollView使用详解

iOS控件详解之UIScrollView

iOS 10 UIScrollView详解(scrollview自带刷新UIRefreshControl)

IOS-scrollView详解