zoukankan      html  css  js  c++  java
  • iOS UI基础-7.0 UIScrollView

    概述

    移动设备的屏幕大小是极其有限的,因此直接展示在用户眼前的内容也相当有限.当展示的内容较多,超出一个屏幕时,用户可通过滚动手势来查看屏幕以外的内容,普通的UIView不具备滚动功能,不能显示过多的内容。UIScrollView是一个能够滚动的视图控件,可以用来展示大量的内容,并且可以通过滚动查看所有的内容
    • UIScrollView的常见属性
    • UIScrollView的常用代理方法
    • UIScrollView的缩放

    UIScrollView使用

    基本使用

    UIScrollView的用法很简单,将需要展示的内容添加到UIScrollView中

    设置UIScrollView的contentSize属性,告诉UIScrollView所有内容的尺寸,也就是告诉它滚动的范围

    界面设计

    点击滚动,图片往下移。实现代码:

    #import "MJViewController.h"
    
    @interface MJViewController ()
    @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
    @property (weak, nonatomic) IBOutlet UIImageView *minionView;
    - (IBAction)scroll;
    @end
    
    @implementation MJViewController
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        // 设置scrollView内容的尺寸(滚动的范围)
    //    self.scrollView.contentSize = CGSizeMake(892, 480);
    //    self.scrollView.contentSize = self.minionView.image.size;
        self.scrollView.contentSize = self.minionView.frame.size; // 总体内容的范围(滚动范围)
    }
    
    - (IBAction)scroll {
        CGPoint offset = self.scrollView.contentOffset;
        offset.x += 10;
        offset.y += 10;
        [self.scrollView setContentOffset:offset animated:YES];
    }
    @end

    无法滚动的解决办法

    如果UIScrollView无法滚动,可能是以下原因:
    • 没有设置contentSize
    • scrollEnabled = NO
    • 没有接收到触摸事件:userInteractionEnabled = NO
    • 没有取消autolayout功能(要想scrollView滚动,必须取消autolayout)

    常见属性

    @property(nonatomic) CGPoint contentOffset;
    这个属性用来表示UIScrollView滚动的位置
     
    @property(nonatomic) CGSize contentSize;
    这个属性用来表示UIScrollView内容的尺寸,滚动范围(能滚多远)
     
    @property(nonatomic) UIEdgeInsets contentInset;
    这个属性能够在UIScrollView的4周增加额外的滚动区域
     
    @property(nonatomic) BOOL bounces;
    设置UIScrollView是否需要弹簧效果
     
    @property(nonatomic,getter=isScrollEnabled) BOOL scrollEnabled;
    设置UIScrollView是否能滚动
     
    @property(nonatomic) BOOL showsHorizontalScrollIndicator;
    是否显示水平滚动条
     
    @property(nonatomic) BOOL showsVerticalScrollIndicator;
    是否显示垂直滚动条

     

    代理delegate

    很多时候,我们想在UIScrollView正在滚动 或 滚动到某个位置 或者 停止滚动 时做一些特定的操作
    要想完成上述功能,前提条件就是能够监听到UIScrollView的整个滚动过程
    当UIScrollView发生一系列的滚动操作时, 会自动通知它的代理(delegate)对象,给它的代理发送相应的消息,让代理得知它的滚动情况
    也就是说,要想监听UIScrollView的滚动过程,就必须先给UIScrollView设置一个代理对象,然后通过代理得知UIScrollView的滚动过程

    实现代理分三步:

    第一步:就设置UIScrollView所在的控制器 为 UIScrollView的delegate

    通过代码(self就是控制器)
    self.scrollView.delegate = self;
    或者 通过storyboard拖线(右击UIScrollView)
     
     
    第二步:控制器应该遵守UIScrollViewDelegate协议

    第三步:实现协议中定义的相关方法

    常用的代理方法有:

    // 用户开始拖拽时调用
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;
    // 滚动到某个位置时调用
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView;
    // 用户结束拖拽时调用
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;

    内容缩放

    缩放实现步骤

    1. 设置UIScrollView的id<UISCrollViewDelegate> delegate代理对象
    2. 设置minimumZoomScale :缩小的最小比例
    3. 设置maximumZoomScale :放大的最大比例
    4. 让代理对象实现下面的方法,返回需要缩放的视图控件
    - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;
     
    跟缩放相关的其他代理方法
    缩放完毕的时候调用
    - (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
    正在缩放的时候调用
    - (void)scrollViewDidZoom:(UIScrollView *)scrollView

    实例代码

    #import "MJViewController.h"
    
    @interface MJViewController () <UIScrollViewDelegate>
    @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
    @property (weak, nonatomic) IBOutlet UIImageView *minionView;
    @end
    // 代理  委托
    
    @implementation MJViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        // 设置内容尺寸
        self.scrollView.contentSize = self.minionView.frame.size;
        
        // 设置
        self.scrollView.delegate = self;
        
        // 设置最大和最小的缩放比例
        self.scrollView.maximumZoomScale = 2.0;
        self.scrollView.minimumZoomScale = 0.2;
    }
    
    /**
     *  当用户开始拖拽scrollView时就会调用
     */
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        NSLog(@"开始拖拽-----");
    }
    
    /**
     *  只要scrollView正在滚动,就会调用
     */
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        NSLog(@"----正在滚动--%@", NSStringFromCGPoint(scrollView.contentOffset));
    }
    
    /**
     *  当用户使用捏合手势的时候会调用
     *
     *  @return 返回的控件就是需要进行缩放的控件
     */
    - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
    {
        NSLog(@"----开始缩放");
        return self.minionView;
    }
    
    /**
     *  正在缩放的时候会调用
     */
    - (void)scrollViewDidZoom:(UIScrollView *)scrollView
    {
        NSLog(@"----正在缩放");
    }
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end

    效果:

    实践-图片轮播

    UIPageControl分页

    只要将UIScrollView的pageEnabled属性设置为YES,UIScrollView会被分割成多个独立页面,里面的内容就能进行分页展示
     
    一般会配合UIPageControl增强分页效果,UIPageControl常用属性如下:
    一共有多少页
    property(nonatomic) NSInteger numberOfPages;
     
    当前显示的页码
    @property(nonatomic) NSInteger currentPage;
    只有一页时,是否需要隐藏页码指示器
     
    @property(nonatomic) BOOL hidesForSinglePage;
    其他页码指示器的颜色
     
    @property(nonatomic,retain) UIColor *pageIndicatorTintColor;
     
    当前页码指示器的颜色
    @property(nonatomic,retain) UIColor *currentPageIndicatorTintColor;
     

    NSTimer定时器

    NSTimer叫做“定时器”,它的作用如下
    • 在指定的时间执行指定的任务
    • 每隔一段时间执行指定的任务
     
    调用下面的方法就会开启一个定时任务
    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget
    
      selector:(SEL)aSelector
    
      userInfo:(id)userInfo
    
      repeats:(BOOL)yesOrNo;

    每隔ti秒,调用一次aTarget的aSelector方法,yesOrNo决定了是否重复执行这个任务

    通过invalidate方法可以停止定时器的工作,一旦定时器被停止了,就不能再次执行任务。只能再创建一个新的定时器才能执行新的任务
    - (void)invalidate; //时钟停止

    实例代码:

    //
    //  UYViewController.m
    //  图片轮播器
    //
    //  Created by jiangys on 15/5/23.
    //  Copyright (c) 2015年 uxiaoyuan. All rights reserved.
    //
    
    #import "UYViewController.h"
    #define kImageCount 5
    
    @interface UYViewController ()<UIScrollViewDelegate>
    
    @property (nonatomic,strong) UIScrollView *scrollView;
    @property (nonatomic,strong) UIPageControl *pageControl;
    
    @property (nonatomic, strong) NSTimer *timer;
    
    @end
    
    @implementation UYViewController
    
    -(UIScrollView *)scrollView
    {
        if (_scrollView==nil) {
            //如果为空,创建一个
            _scrollView=[[UIScrollView alloc] initWithFrame:CGRectMake(10, 20, 300, 130)];
            _scrollView.backgroundColor=[UIColor redColor];
            
            //取消弹簧效果
            _scrollView.bounces=NO;
            
            // 取消水平滚动条
            _scrollView.showsHorizontalScrollIndicator = NO;
            _scrollView.showsVerticalScrollIndicator = NO;
            
            // 要分页
            _scrollView.pagingEnabled = YES;
            
            // contentSize
            _scrollView.contentSize = CGSizeMake(kImageCount * _scrollView.bounds.size.width, 0);
            
            // 设置代理
            _scrollView.delegate = self;
            
            [self.view addSubview:_scrollView];
                         
        }
        return _scrollView;
    
    }
    
    - (UIPageControl *)pageControl
    {
        if (_pageControl == nil) {
            // 分页控件,本质上和scrollView没有任何关系,是两个独立的控件
            _pageControl = [[UIPageControl alloc] init];
            // 总页数
            _pageControl.numberOfPages = kImageCount;
            // 控件尺寸
            CGSize size = [_pageControl sizeForNumberOfPages:kImageCount];
            
            _pageControl.bounds = CGRectMake(0, 0, size.width, size.height);
            _pageControl.center = CGPointMake(self.view.center.x, 130);
            
            // 设置颜色
            _pageControl.pageIndicatorTintColor = [UIColor redColor];
            _pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
            
            [self.view addSubview:_pageControl];
            
            // 添加监听方法
            /** 在OC中,绝大多数"控件",都可以监听UIControlEventValueChanged事件,button除外" */
            [_pageControl addTarget:self action:@selector(pageChanged:) forControlEvents:UIControlEventValueChanged];
        }
        return _pageControl;
    }
    
    // 分页控件的监听方法
    - (void)pageChanged:(UIPageControl *)page
    {
        // 根据页数,调整滚动视图中的图片位置 contentOffset
        CGFloat x = page.currentPage * self.scrollView.bounds.size.width;
        [self.scrollView setContentOffset:CGPointMake(x, 0) animated:YES];
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        //设置图片
        for (int i=0; i<kImageCount; i++) {
            NSString *imageName=[NSString stringWithFormat:@"img_%02d",i+1];
            UIImage *image=[UIImage imageNamed:imageName];
            
            UIImageView *imageView=[[UIImageView alloc] initWithFrame:self.scrollView.bounds];
            imageView.image=image;
            
            [self.scrollView addSubview:imageView];
        }
        //计算imageView
        [self.scrollView.subviews enumerateObjectsUsingBlock:^(UIImageView *imageView, NSUInteger idx, BOOL *stop) {
            // 调整x => origin => frame
            CGRect frame = imageView.frame;
            frame.origin.x = idx * frame.size.width;
            
            imageView.frame = frame;
        }];
        
        // 分页初始页数为0
        self.pageControl.currentPage = 0;
        
        // 启动时钟
        [self startTimer];
        
    }
    
    - (void)startTimer
    {
        self.timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(updateTimer) userInfo:nil repeats:YES];
        // 添加到运行循环
        [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
    }
    
    - (void)updateTimer
    {
        // 页号发生变化
        // (当前的页数 + 1) % 总页数
        int page = (self.pageControl.currentPage + 1) % kImageCount;
        self.pageControl.currentPage = page;
    
        // 调用监听方法,让滚动视图滚动
        [self pageChanged:self.pageControl];
    }
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.s
        
    }
    
    #pragma mark - ScrollView的代理方法
    // 滚动视图停下来,修改页面控件的小点(页数)
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        // 计算页数
        int page = scrollView.contentOffset.x / scrollView.bounds.size.width;
        
        self.pageControl.currentPage = page;
    }
    
    /**
     修改时钟所在的运行循环的模式后,抓不住图片
     
     解决方法:抓住图片时,停止时钟,松手后,开启时钟
     */
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        // 停止时钟,停止之后就不能再使用,如果要启用时钟,需要重新实例化
        [self.timer invalidate];
    }
    
    /**
     *  停止滚动,开启时钟
     */
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    {
        [self startTimer];
    }
    
    
    @end

    效果:

    源码下载:点击下载

  • 相关阅读:
    zoj 2316 Matrix Multiplication 解题报告
    BestCoder7 1001 Little Pony and Permutation(hdu 4985) 解题报告
    codeforces 463C. Gargari and Bishops 解题报告
    codeforces 463B Caisa and Pylons 解题报告
    codeforces 463A Caisa and Sugar 解题报告
    CSS3新的字体尺寸单位rem
    CSS中文字体对照表
    引用外部CSS的link和import方式的分析与比较
    CSS样式表引用方式
    10个CSS简写/优化技巧
  • 原文地址:https://www.cnblogs.com/jys509/p/4811509.html
Copyright © 2011-2022 走看看