ios uiscrollView 使用理解

1、 scrollview 常用屬性理解

UIScrollVie的常用屬性 :
  contentSize     滾動範圍,比scrollview的size大
  contentInset    內邊距, contentSize和scrollView的邊框的一個距離,和div一樣,內變距會計算到contentSize中
  contentOffset   偏移量,  contentSize+padding  距離邊框的距離
                  彈簧效果
                  滾動指示器
                  是否可以滾動

功能實現: 
ViewController: scrollView常用屬性設置
 1. 拖入scrollview 
 2. 拖imageView設置大小和 圖片大小一致,1024*768
 3. 常用屬性理解



#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIScrollView *myscrollview;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    /**
      1.  設置scrollView 414* 736, 設置子View ImageView和圖片大小一致 1024*768
                scrollView 設置滾動範圍     contentSize
     如果size 爲寬度設置爲0 ,表示橫向不能滾動
       
     */
     self.myscrollview.contentSize= CGSizeMake(1024, 768);
    
    // 2. 設置水平垂直滾動條
    _myscrollview.showsHorizontalScrollIndicator=false;
    _myscrollview.showsVerticalScrollIndicator=false;
    // 3. 彈簧效果,默認Yes
    _myscrollview.bounces=false;
    // 4. 不設置contentSize的時候,彈簧效果開啓,依然看不到效果
    // 如果要看到彈簧效果,設置如下
    _myscrollview.bounces=YES;
    _myscrollview.alwaysBounceHorizontal=YES;
    _myscrollview.alwaysBounceVertical=YES;
    
    // 5.內邊距
    // 設置padding  和div一樣,會加入 content中
    _myscrollview.contentInset= UIEdgeInsetsMake(10, 10, 10, 10);
    
    // 6. content 滾動距離
   // scrollview 滑動  contentoffset.y  累加
    _myscrollview.contentOffset= CGPointMake(10, 10);
    
    /**  7. 不能滾動  原因
     1. contentSize 小於比 scrollView 小
     2.  _myscrollview.userInteractionEnabled=false;
     3. _myscrollview.scrollEnabled=false;
     */
  
}



- (IBAction)scrollTest:(id)sender {
    
     // 1. 取出scrollVie 的 contentSize
    CGPoint offset = _myscrollview.contentOffset;
    
    offset.x= offset.x+10;
    offset.y = offset.y + 10;
    
    // 直接設置沒有動畫
    [_myscrollview setContentOffset:offset];
    
    // 什麼是動畫,動畫就是屬性變化,放入動畫函數中
//    [UIView animateWithDuration:2.0 animations:^{
//         [self.myscrollview setContentOffset:offset];
//    }];
    
    // 使用系統自帶函數
    [self.myscrollview setContentOffset:offset animated:YES];
    
    // 在滾動的時候 contentSize -> 子View contentSize 內容滾動範圍
    // scrollview.frame.size   -> scrollView本身 高度
    NSLog(@"contentSize:%@, frameSize:%@",NSStringFromCGSize(_myscrollview.contentSize),
          NSStringFromCGSize(_myscrollview.frame.size));
}


@end

效果圖:

2. UIscrollView在xib中使用    滾動監聽 

UiScrollView 

垂直滾動
 1、  拖入scrollview 設置約束
 2、  在scrollview中 拖入 contentView中 設置 上下左右約束爲0 
 3、  設置高度  contentSize的高度
 4、  設置水平居中
 5.   然後拖入控件在  contentView中 佈局

水平滾動
 1、  拖入scrollview 設置約束
 2、  在scrollview中 拖入 contentView 設置 上下左右約束爲0 
 3、  設置高度  contentSize的寬度
 4、  設置垂直居中
 5.   然後拖入控件在  contentView中 佈局


#import "ViewController2.h"

@interface ViewController2 ()<UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *myscrollview;

@end

@implementation ViewController2

- (void)viewDidLoad {
    [super viewDidLoad];
    //實際開發中如何確定scrollView contentSize
    //  獲取 最後一個控件的  的Y 值
  //  CGFloat lastImageY = CGRectGetMaxY(_lastImage.frame);
  //   _myscrollview.contentSize= CGSizeMake(0, lastImageY);
      // 設置內邊距以後,contextSize區域還是在屏幕頂端,padding在屏幕上
      _myscrollview.contentInset= UIEdgeInsetsMake(60, 0, 40 , 0);
    // 向下偏移 -60
      _myscrollview.contentOffset= CGPointMake(0, -60);
      _myscrollview.delegate =self;
}

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    NSLog(@"scrollView滾動時候一直調用:%@",NSStringFromCGPoint(scrollView.contentOffset));
}
// Drag: 拖拽,開始拖拽的時候調用
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    NSLog(@"開始拖拽時候調用,只會調用一次");
}
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    
    NSLog(@"停止拖拽時候調用,只會調用一次");
}

@end

效果圖: 

3.  ScrollView 設置圖片縮放

按照如下設置即可: 
     //1. 實際開發中把這裏設置爲1
       _scrollView.minimumZoomScale = 0.3;
       _scrollView.maximumZoomScale = 3;
//2.  返回的view將被拉伸(縮放),告訴ScrollView 要縮放哪一個View
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return _imageView;//返回值爲需要縮放的對象
}



#import "ScrollViewController.h"

#define kImageCount 5

@interface ScrollViewController ()<UIScrollViewDelegate>


@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end

@implementation ScrollViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
        /**
         minimumZoomScale;   -->圖片最小的縮小倍數
          maximumZoomScale;  --> 圖片最大的放大倍數
        */
       //1. 實際開發中把這裏設置爲1
       _scrollView.minimumZoomScale = 0.3;
       _scrollView.maximumZoomScale = 3;
       
       // 設置控制器成爲scrollView的代理
       _scrollView.delegate = self;
}

//2.  返回的view將被拉伸(縮放),告訴ScrollView 要縮放哪一個View

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return _imageView;//返回值爲需要縮放的對象
}

// 只要圖片在放大/縮小的過程中都會一直調用
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
    NSLog(@"scrollViewDidZoom");
}

// 開始縮放的時候調用
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {
    NSLog(@"scrollViewWillBeginZooming");
}

// 結束的時候調用
// withView: 進行縮放的view
// atScale: 縮放的倍數
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {
    NSLog(@"scrollViewDidEndZooming");
}



@end

4.   圖片輪播實現

4.1. 設置scrollView 圖片顯示 
 _scrollView.contentSize = CGSizeMake(kImageCount * kScrollViewSize.width, 0);

4.2.  設置指示器
  _pageControl.currentPage = 0;

4.3. 實現拖動頁面切換 _pageControl.currentPage
 scrollViewDidEndDecelerating:  當scrollView停止減速的時候調用,表示頁面已經切換,切換指示器_pageControl.currentPage

4.4.  模仿: 實現點擊按鈕滾動頁面自動
      _pageControl.currentPage = currentPage;
     [_scrollView setContentOffset:offset animated:YES];
     
4.5. 通過定時實現自動輪播
    [self initImageTimer];
scrollViewWillBeginDragging: 當拖拽的時候停止定時器
scrollViewDidEndDragging:  當停止拖拽的時候恢復定時器

//
//  BannerController.m
//  scrollViewDemo
//
//  Created by 鄧安置 on 2020/6/11.
//  Copyright © 2020 鄧安置. All rights reserved.
//

#import "BannerController.h"

#define kScrollViewSize (_scrollView.frame.size)

#define kImageCount 5

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

@property (nonatomic, strong) NSTimer *timer;
@end

@implementation BannerController

- (void)viewDidLoad {
    [super viewDidLoad];
// 下面代碼寫完,那麼就可以滾動了
    //  1. 設置scrollView 圖片顯示
    // 設置控制器成爲scrollView的代理
    _scrollView.delegate = self;
    
      for (int i = 0; i < kImageCount; i++) {
            // 計算imageView的x值
            CGFloat imageViewX = i * kScrollViewSize.width;
            
            UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(imageViewX, 0, kScrollViewSize.width, kScrollViewSize.height)];
            
            // 設置圖片
    //        imageView.image =[UIImage imageNamed:@"img_01"];
            // 拼接圖片的名稱
            NSString *imageName = [NSString stringWithFormat:@"img_%02d",i + 1];
            
            imageView.image = [UIImage imageNamed:imageName];
            
            
            // 添加到scrollView
            [_scrollView addSubview:imageView];
        }
    
    // 設置 scrollView的contentSize
    _scrollView.contentSize = CGSizeMake(kImageCount * kScrollViewSize.width, 0);
    // 隱藏滾動指示器
    _scrollView.showsHorizontalScrollIndicator = NO;
    // scrollView的分頁效果 (根據scrollView的寬度進行分頁的)
    _scrollView.pagingEnabled = YES;
    
    
    // 2. 設置指示器
    // 設置總共有幾個點
       _pageControl.numberOfPages = kImageCount;
       // 設置指示器的顏色
       // 非當前的指示器
       _pageControl.pageIndicatorTintColor = [UIColor grayColor];
       // 設置當前指示器的顏色
       _pageControl.currentPageIndicatorTintColor = [UIColor redColor];
       // 設置當前在第幾個點 , 取值範圍是 0 .. numberOfPages - 1
       // 設置的currentPage如果超出最大的範圍, 就在最後一個顯示
       // 設置的currentPage如果超出最小的範圍 就在第一個顯示
       // 動態 滾動的時候不斷改變這點點即可
       _pageControl.currentPage = 0;
    
    
   // 5. 創建計時器
     [self initImageTimer];
}

#pragma mark -
#pragma mark -  當scrollView停止減速的時候調用
// 3. Decelerating 減速
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    // currentPage = scrollView.contentOffset.x / kScrollViewSize.width
    // 通過 currentPage++不行,如果通過currentPage++那麼要判斷向左滑動還是向右
    // 這裏有一個小算法: 判斷當前的頁,當前座標除以第一頁的座標
    _pageControl.currentPage = scrollView.contentOffset.x / kScrollViewSize.width;
}


 //4.  模仿: 實現點擊按鈕滾動
 - (IBAction)didClickButton:(id)sender {
     /**
      1. 取出scrollView的contentOffset
      2. 取出 pagecontroll 的 currentPage
      3. 進行修改
      4. 賦值回去
      */
     
     // 1. 取出 contentOffset
     CGPoint offset = _scrollView.contentOffset;
     
     // 2. currentPage
     NSInteger currentPage = _pageControl.currentPage;
     
     // 3. 進行修改
     
     if (currentPage == 4) {
         // 到了最後一張, 再次點擊的時候, 到第一張圖片的位置
         // currentPage 修改爲0
         currentPage = 0;
         
         // 修改 scrollView的contentOffset
         offset = CGPointZero;
         
     } else {
         
         currentPage += 1;
         
         offset.x += kScrollViewSize.width;
     }
     
     // 4. 賦值回去
     _pageControl.currentPage = currentPage;
     [_scrollView setContentOffset:offset animated:YES];
     
 }



/**
 在開始拖拽的時候, 把計時器停止
 
 invalidate 無效的意思
 */
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    // 讓計時器無效
    [_timer invalidate];
}

/**
 當停止拖拽的時候, 讓計時器開始工作
 手指離開scrollView的時候
 */
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
   [_timer fire];
    
    [self initImageTimer];
}

#pragma mark -
#pragma mark -  創建計時器
- (void)initImageTimer {
    /**
     scheduled 計劃,安排
     interval : 間隔
     target :  一般指控制器
     selector: 方法
     userInfo : 用戶自定義的參數
     repeats: 重複
     
     每隔1秒鐘 調用 控制器的  didClickButton: 方法, 傳遞的參數爲nil
     
     一旦創建就會立即生效
     
     在使用timer的時候, 如果調用了 invalidate方法, 那麼這個計時器就不會再次生效
     重新創建新的timer
     */
    _timer = [NSTimer scheduledTimerWithTimeInterval:2
                                              target:self
                                            selector:@selector(didClickButton:)
                                            userInfo:nil
                                             repeats:YES];
    
   // [_timer fire];  調用fire , 這個計時器會立即執行, 不會等待 interval 設置的時間
    /*** 問題: 如果界面有兩個scrollview的時候,當滑動另外一個
     *    scrollview當前scrollview可能不會自動滾動,用戶交互的scrollview
    *    優先級更高,通過下面設置,把優先級設置成一樣高了
    **/
    NSRunLoop *mainLoop = [NSRunLoop mainRunLoop];
    
    
    [mainLoop addTimer:_timer forMode:NSRunLoopCommonModes];
    
}

@end

效果圖:

源碼目錄:

ViewController: scrollView常用屬性設置
ViewController2:  scrollView 滾動監聽
ScrollViewController: 實現圖片縮放
BannerController: 圖片輪播實現 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章