UIScrollView

1.基本使用

  • 介绍
当展示的内容较多,超出一个屏幕时,用户可通过滚动手势来查看屏幕以外的内容

普通的UIView不具备滚动功能,不适合显示过多的内容

UIScrollView是一个能够滚动的视图控件,可以用来展示大量的内容,并且可以通过滚动查看所有的内容

举例:手机上的“设置”
  • UIScrollView的基本使用
UIScrollView的用法很简单
将需要展示的内容添加到UIScrollView中
设置UIScrollView的contentSize属性,告诉UIScrollView所有内容的尺寸,也就是告诉它滚动的范围(能滚多远,滚到哪里是尽头)

UIScrollView显示内容的小细节
超出UIScrollView边框的内容会被自动隐藏
用户可以用过手势拖动来查看超出边框并被隐藏的内容
  • 设置内容尺寸(contentSize)
  • 不能滚动的原因
如果UIScrollView无法滚动,可能是以下原因:
没有设置contentSize
注意:scrollEnabled = NO 只是不讓scrollView不能滾動
    userInteractionEnabled = NO 是不讓scrollView有任何交互
scrollEnabled = NO
没有接收到触摸事件:userInteractionEnabled = NO
… …

2.常见属性

  • 是否有弹簧效果
  • 是否总是有弹簧效果
    • 作用:下拉刷新,上拉加载
  • 是否显示滚动条
    • 滚动条的样式
  • 滚动条是imageView
    • 注意点:不要通过索引去subViews这个数组中去访问scrollView的子控件
  • UIScrollView的常见属性
@property(nonatomic) CGPoint contentOffset; 
这个属性用来表示UIScrollView滚动的位置
(其实就是内容左上角与scrollView左上角的间距值)

@property(nonatomic) CGSize contentSize; 
这个属性用来表示UIScrollView内容的尺寸,滚动范围(能滚多远)

@property(nonatomic) UIEdgeInsets contentInset; 
这个属性能够在UIScrollView的4周增加额外的滚动区域,一般用来避免scrollView的内容被其他控件挡住
  • UIScrollView的其他属性
@property(nonatomic) BOOL bounces;
设置UIScrollView是否需要弹簧效果

@property(nonatomic,getter=isScrollEnabled) BOOL scrollEnabled; 
设置UIScrollView是否能滚动

@property(nonatomic) BOOL showsHorizontalScrollIndicator;
是否显示水平滚动条

@property(nonatomic) BOOL showsVerticalScrollIndicator;
是否显示垂直滚动条

2.設置scrollView的contentSize
self.scrollView.contentSize = image.size;

3.是否有彈簧效果
self.scrollView.bounces = NO;

4.不管你有没有設置contentSize,总是有彈簧效果(下拉刷新)
self.scrollView.alwaysBounceHorizontal = YES;
self.scrollView.alwaysBounceVertical = YES;

5.設置滾動条(默認是YES)
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.showsVerticalScrollIndicator = NO;

3.偏移量和内边距

  • 偏移量的作用
  • 偏移量的计算方法
    • scrollView左上角和内容左上角的差值
  • 上下左右滚动
  • 设置内边距
2.設置內容的偏移量
 作用1:控制內容滾動的位置
 作用2:得知內容滾動的位置
self.scrollView.contentOffset = CGPointMake(200,100);

點击控制器的View會自動調用這個方法
- (void)touchesBegan:(NSSet<UITouch *>*)touches withEvent:(UIEvent *)event{
 self.scrollView.contentOffset = CGPointMake(-100,-100);
}

3.設罝內邊距
self.scrollView.contentInset = UIEdgeInsetMake(10,20,30,40);

4.监听scrollView的各种行为

  • 代理的介绍
    • 監聲方法有兩種,一個是用属性名例如scrollView.delegate = self; 另一種是需要控件継承UIControl,継承用addTarget

  • 代码创建scrollView和storyboard创建的区别
    • 代码创建要等到真正要显示的时候才会有滚动条
    • storyboard创建的一开始就有滚动条
  • scrollView监听各种行为的3步骤

    1. 设置代理

    2. 遵守协议

    3. 实现相应的代理方法

  • scrollView的代理方法(监听五个事件)

    1. 滚动
    2. 即将拖拽
    3. 即将停止拖拽
    4. 已经停止拖拽
    5. 减速完毕
  • 如何监听scrollView已经停止滚动

    • 有2种情况
      • 第一种手松开,scrollView就停止滚动
      • 第二种,用户停止拖拽,但scrollView由于惯性继续滚动,并且减速
scrollView监听各种行为的3步骤:
1.遵守协议
    只你聲明UIScrollViewDelegate,就可以實現理面的方法,和調用理面的属性
@interface ViewConteroller ()<UIScrollViewDelegate> //聲明
2.设置代理
scrollView.delegate = self;
3.实现相应的代理方法
    當scrollView正在滾動的時候就自動調用這個方法
    所以如果你需要監聲那個scrollView就實現這個方法
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    NSLog(@"scrollViewDidScroll---");
}


scrollView的代理方法(监听五个事件):
1. 滚动
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    NSLog(@"scrollViewDidScroll---");
}
2. 即将拖拽
//當scrollView正在滾動時候自動調用這個方法
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    NSLog(@"scrollViewDidScroll---");
}

3. 即将停止拖拽
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
    NSLog(@"scrollViewWillEndDragging");
}
4. 已经停止拖拽
//用戶己經停止拖拽scrollView時調用這個方法
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    NSLog(@"scrollViewDidEndDragging");
}
5. 减速完毕
//scrollView减速完毕會調用,停止滾動
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    NSLog(@"scrollViewDidEndDecelerating");
}

5.代理的注意点

  • 任何OC对象都可以作为scrollView的代理,不仅仅是控制器
  • 代理一般都是weak
  • 代理的一般规律

6.常见控件监听事件

  1. UIButton
  2. UISegmentControl
  3. UISlider
  4. UITableView
  5. UITextFlied
1.UIButton 
//1.Button 監聲
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
- (void)btnClick:(UIButton *)btn{
    NSLog(@"123");
}
2.UISegmentControl 
//2.UISegmentedControl 監聲
    UISegmentedControl *segmented = [[UISegmentedControl alloc] initWithItems:@[@"123",@"234",@"345"]];
    //設置默認選第0個
    //segmented.selectedSegmentIndex = 0;
    [segmented addTarget:self action:@selector(segmentedClick:) forControlEvents:UIControlEventValueChanged];

    segmented.center = CGPointMake(self.view.center.x, 200);
    [self.view addSubview:segmented];
- (void)segmentedClick:(UISegmentedControl *)segmented{
    NSLog(@"%ld", segmented.selectedSegmentIndex);
}
3.UISlider 
4.UITableView 
5.UITextFlied(UITextFlied可以用delegate也可以用addTarget)
@interface ViewConteroller ()<UIScrollViewDelegate>
self.textField.delegate = self;
//點击空白結束textField編輯
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self.textField endEditing:YES];
}
//開始編輯
- (void)textFieldDidBeginEditing:(UITextField *)textField{
    NSLog(@"開始編輯");
}
//結束編輯
- (void)textFieldDidEndEditing:(UITextField *)textField{
    NSLog(@"結束編輯");
}
/**
 @param textField textField文字改變會調用這個方法
 @param string 用戶輸入的文字
 @return YES:允許用戶輸入;NO:禁止用戶輸入
 */
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    if ([string isEqualToString:@"1"]) {
        return NO;
    }
    return YES;
}

7.内容的缩放

  • 通过代理告知哪一个控件需要缩放
  • 设置缩放的比例
  • 监听缩放的过程
  • 禁止缩放的弹簧效果

@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (nonatomic, weak) UIImageView *imageView;
//做一個圖片的縮放
    UIImage *image = [UIImage imageNamed:@"minion"];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    [self.scrollView addSubview:imageView];

    //設置contentSize
    self.scrollView.contentSize = image.size;
    //這里是為了讓scrollView控件返回字控件所定義的
    self.imageView = imageView;
    //設置縮放的比例
    self.scrollView.maximumZoomScale = 2.5;
    self.scrollView.minimumZoomScale = 0.5;


}
#pragma mark -
#pragma mark - UIScrollViewDelegate
//返回需要縮放的子控件(scrollView的字控件)
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
    return self.imageView;
}

8.分页功能

  • 介绍分页功能
  • 添加图片
  • 开启分页功能
  • 引导页和循环利用的思想(无限滚动)
介绍分页功能
添加图片
开启分页功能 
引导页和循环利用的思想(无限滚动)

 //分頁
    CGFloat scrollViewWith = self.scrollView.frame.size.width;
    CGFloat scrollViewHeight = self.scrollView.frame.size.height;
    int count = 5;
    //1.添加圖片
    for (int i = 0;  i < count; i++) {
        UIImageView *imageView = [[UIImageView alloc] init];
        NSString *name = [NSString stringWithFormat:@"img_0%d",i+1];
        imageView.image = [UIImage imageNamed:name];
        imageView.frame = CGRectMake(i * scrollViewWith, 0, scrollViewWith, scrollViewHeight);
        [self.scrollView addSubview:imageView];
    }
    //2.設置contentSize
    self.scrollView.contentSize = CGSizeMake(count * scrollViewWith, 0);
    //3.設置分頁功能
    self.scrollView.pagingEnabled = YES;

9.显示页码

  • 拖入pageControl控件
  • 设置总页数和当前页
  • 监听scrollView的滚动来改变页码
    • 停止滚动才改变页码
    • 滚动过程中实时改变页码
  • 当只有一页时,隐藏控件
    • 自己判断
    • hidesForSinglePage
  • 禁止与用户交互
  • 修改pageControl显示的图片
#import "ViewController.h"

@interface ViewController () <UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;

@property (weak, nonatomic) IBOutlet UIPageControl *pageConterol;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //分頁
    CGFloat scrollViewWith = self.scrollView.frame.size.width;
    CGFloat scrollViewHeight = self.scrollView.frame.size.height;
    int count = 5;
    //1.添加圖片
    for (int i = 0;  i < count; i++) {
        UIImageView *imageView = [[UIImageView alloc] init];
        NSString *name = [NSString stringWithFormat:@"img_0%d",i+1];
        imageView.image = [UIImage imageNamed:name];
        imageView.frame = CGRectMake(i * scrollViewWith, 0, scrollViewWith, scrollViewHeight);
        [self.scrollView addSubview:imageView];
    }
    //2.設置contentSize
    self.scrollView.contentSize = CGSizeMake(count * scrollViewWith, 0);
    //3.設置分頁功能
    self.scrollView.pagingEnabled = YES;

    self.scrollView.delegate = self;
    //4.設置总頁數
    self.pageConterol.numberOfPages = count;
    //5.設置單頁是否顯示
    /*方法一:
    if (count <= 1 ) {
        self.pageConterol.alpha = 0;
        self.pageConterol.hidden = YES;
    }
     */
    //方法二:
    self.pageConterol.hidesForSinglePage = YES;
    //6.設置page的小點,為圖片的小點
    [self.pageConterol setValue:[UIImage imageNamed:@"current"] forKeyPath:@"_currentPageImage"];
    [self.pageConterol setValue:[UIImage imageNamed:@"other"] forKeyPath:@"_pageImage"];

}
/*
 四舍五入:int(小數 + 0.5)
 0.2 ---> 0  int(0.2 + 0.5) = 0.7 -> 0
 0.3 ---> 0  int(0.3 + 0.5) = 0.8 -> 0
 0.9 ---> 1  int(0.9 + 0.5) = 1.4 -> 1
 1.5 ---> 2  int(1.5 + 0.5) = 2   -> 2
 (int)(scrollView.contentOffset.x / scrollView.frame.size.width + 0.5)
 */
//分頁方法二:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    //計算頁碼
    int page =  (scrollView.contentOffset.x / scrollView.frame.size.width + 0.5 );
    self.pageConterol.currentPage = page;
}


//分頁方法一:
//scrollview停止迤拽時做些事情
/*
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    if (decelerate == NO) {
        //計算頁碼
        int page =  scrollView.contentOffset.x / scrollView.frame.size.width;
        self.pageConterol.currentPage = page;
    }
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    //計算頁碼
    int page =  scrollView.contentOffset.x / scrollView.frame.size.width;
    self.pageConterol.currentPage = page;
}
*/

@end

10.定时器的使用

  • 创建定时器
  • 停止定时器
  • 细节
    • 定时器一旦停止工作就不能在使用了
    • 修改timer在runloop中的模式
#import "ViewController.h"

@interface ViewController () <UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;

@property (weak, nonatomic) IBOutlet UIPageControl *pageConterol;

@property (nonatomic, assign) int count;

@property (nonatomic, weak) NSTimer *timer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //分頁
    CGFloat scrollViewWith = self.scrollView.frame.size.width;
    CGFloat scrollViewHeight = self.scrollView.frame.size.height;
    self.count = 5;
    //1.添加圖片
    for (int i = 0;  i < self.count; i++) {
        UIImageView *imageView = [[UIImageView alloc] init];
        NSString *name = [NSString stringWithFormat:@"img_0%d",i+1];
        imageView.image = [UIImage imageNamed:name];
        imageView.frame = CGRectMake(i * scrollViewWith, 0, scrollViewWith, scrollViewHeight);
        [self.scrollView addSubview:imageView];
    }
    //2.設置contentSize
    self.scrollView.contentSize = CGSizeMake(self.count * scrollViewWith, 0);
    //3.設置分頁功能
    self.scrollView.pagingEnabled = YES;

    self.scrollView.delegate = self;
    //4.設置总頁數
    self.pageConterol.numberOfPages = self.count;
    //5.設置單頁是否顯示
    /*方法一:
    if (count <= 1 ) {
        self.pageConterol.alpha = 0;
        self.pageConterol.hidden = YES;
    }
     */
    //方法二:
    self.pageConterol.hidesForSinglePage = YES;
    //6.設置page的小點,為圖片的小點
    [self.pageConterol setValue:[UIImage imageNamed:@"current"] forKeyPath:@"_currentPageImage"];
    [self.pageConterol setValue:[UIImage imageNamed:@"other"] forKeyPath:@"_pageImage"];

    //7.開始定時器
    [self startTimer];

}
//定時器的方法
- (void)nextPage{
    //計算當前頁
    NSInteger page = self.pageConterol.currentPage + 1;
    if (page == self.count) {
        page = 0;
    }
    //滾動到下一頁
    [self.scrollView setContentOffset:CGPointMake(page * self.scrollView.frame.size.width, 0) animated:YES];
}
#pragma mark -
#pragma mark - 定時器的相關代碼
- (void)startTimer{
     self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(nextPage) userInfo:nil repeats:YES];
}
- (void)stopTimer{
    [self.timer invalidate];
    self.timer = nil;
}

/*
 四舍五入:int(小數 + 0.5)
 0.2 ---> 0  int(0.2 + 0.5) = 0.7 -> 0
 0.3 ---> 0  int(0.3 + 0.5) = 0.8 -> 0
 0.9 ---> 1  int(0.9 + 0.5) = 1.4 -> 1
 1.5 ---> 2  int(1.5 + 0.5) = 2   -> 2
 (int)(scrollView.contentOffset.x / scrollView.frame.size.width + 0.5)
 */
//分頁方法二:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    //計算頁碼
    int page =  (scrollView.contentOffset.x / scrollView.frame.size.width + 0.5 );
    self.pageConterol.currentPage = page;
}

//用戶拖拽,停止定時器
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    [self stopTimer];
}
//用戶己經停止拖拽,開始定時器
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    [self startTimer];
}

11.单独view的封装

results matching ""

    No results matching ""