iOS UIScrollView分頁滑動寬度自定義實現

SHAREHONEY 7年前發布 | 12K 次閱讀 iOS開發 移動開發 UIScrollView

前言

App中最常用 輪播圖 , 關于它的實現有很多方法 如 : Anination, UIScrollView, UICollectionView . 動畫是另一種思路, UICollectionView 繼承于 UIScrollView. 作者今天就用 UIScrollView 講一下 , 分頁效果下 滑動寬度小于屏幕寬度 露出上下頁內容, 或 滑動視圖之間 間隙問題 . 如圖 :

分頁效果下 滑動寬度小于屏幕寬度 露出上下頁內容

滑動視圖之間 間隙

一 思路整理

有些文章寫過 實現方法, 是把 pagingEnabled 設為 NO , 自己寫出 分頁效果. 這么寫也可以. 作者更喜歡使用 系統的方法. 實現該效果, 有以下核心代碼 :

1) pagingEnabled 設為 YES , 用系統方法實現.

2) clipsToBounds 設為 NO , 為了顯現上下頁內容

3) 分頁滑動寬度 系統默認為 UIScrollViewwidth .

4) 算法公式 : (2 i+ 1) b + i * a => 說明 : b : 圖片間距一半, a : 圖片寬

二 封裝控件 RollView .h

#import <UIKit/UIKit.h>

/* 設置代理 / @protocol RollViewDelegate <NSObject>

-(void)didSelectPicWithIndexPath:(NSInteger)index; @end

@interface RollView : UIView

@property (nonatomic, assign) id<RollViewDelegate> delegate;

/** 初始化

@param frame 設置View大小 @param distance 設置Scroll距離View兩側距離 @param gap 設置Scroll內部 圖片間距 @return 初始化返回值 */

  • (instancetype)initWithFrame:(CGRect)frame withDistanceForScroll:(float)distance withGap:(float)gap;

/* 滾動視圖數據 / -(void)rollView:(NSArray *)dataArr;

@end</code></pre>

三 封裝控件 RollView .m

#import "RollView.h"

@interface RollView ()<UIScrollViewDelegate>

@property (nonatomic, strong) UIScrollView *scrollView;

@property (nonatomic, strong) NSArray *rollDataArr; // 圖片數據

@property (nonatomic, assign) float halfGap; // 圖片間距的一半

@end</code></pre>

@implementation RollView

  • (instancetype)initWithFrame:(CGRect)frame withDistanceForScroll:(float)distance withGap:(float)gap {

    self = [super initWithFrame:frame]; if (self) {

      self.halfGap = gap / 2;
    
      /** 設置 UIScrollView */
      self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(distance, 0, self.frame.size.width - 2 * distance, self.frame.size.height)];
      [self addSubview:self.scrollView];
      self.scrollView.pagingEnabled = YES;
      self.scrollView.delegate = self;
    
      self.scrollView.clipsToBounds = NO;
    
      /** 添加手勢 */
      UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
      tap.numberOfTapsRequired = 1;
      tap.numberOfTouchesRequired = 1;
      [self.scrollView addGestureRecognizer:tap];
      self.scrollView.showsHorizontalScrollIndicator = NO;
    
      /** 數據初始化 */
      self.rollDataArr = [NSArray array];
    
    

    }

return self;

}

pragma mark - 視圖數據

-(void)rollView:(NSArray *)dataArr{

self.rollDataArr = dataArr;


//循環創建添加輪播圖片, 前后各添加一張
for (int i = 0; i < self.rollDataArr.count + 2; i++) {

    for (UIView *underView in self.scrollView.subviews) {

        if (underView.tag == 400 + i) {
            [underView removeFromSuperview];
        }
    }

    UIImageView *picImageView = [[UIImageView alloc] init];
    picImageView.userInteractionEnabled = YES;
    picImageView.tag = 400 + i ;

    /**  說明
     *   1. 設置完 ScrollView的width, 那么分頁的寬也為 width.
     *   2. 圖片寬為a 間距為 gap, 那么 圖片應該在ScrollView上居中, 距離ScrollView左右間距為halfGap.
     *   與 ScrollView的width關系為 width = halfGap + a + halfGap.
     *   3. distance : Scroll距離 底層視圖View兩側距離.  
     *   假設 要露出上下頁內容大小為 m ,   distance = m + halfGap
     *
     *  圖片位置對應關系 :
     *  0 ->  2 * halfGap ;
     *  1 ->  3 * halfGap + a ;
     *  2 ->  5 * halfGap + 2 * a ;
          .
          .
     *  i   -> (2 * i +1) *  halfGap + 2 *(width - 2 * halfGap )
     */


    picImageView.frame = CGRectMake((2 * i + 1) * self.halfGap + i * (self.scrollView.frame.size.width - 2 * self.halfGap), 0, (self.scrollView.frame.size.width - 2 * self.halfGap), self.frame.size.height);

    //設置圖片
    if (i == 0) {

        picImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@", self.rollDataArr[self.rollDataArr.count - 1]]];

    }else if (i == self.rollDataArr.count+1) {

        picImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@", self.rollDataArr[0]]];
    }else {

        picImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@", self.rollDataArr[i - 1]]];
    }

    [self.scrollView addSubview:picImageView];
}
//設置輪播圖當前的顯示區域
self.scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width, 0);
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * (self.rollDataArr.count + 2), 0);

}

pragma mark - UIScrollViewDelegate 方法

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

NSInteger curIndex = scrollView.contentOffset.x  / self.scrollView.frame.size.width;

if (curIndex == self.rollDataArr.count + 1) {

    scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width, 0);
}else if (curIndex == 0){

    scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width * self.rollDataArr.count, 0);
}

}

pragma mark - 輕拍手勢的方法

-(void)tapAction:(UITapGestureRecognizer *)tap{

if ([self.rollDataArr isKindOfClass:[NSArray class]] && (self.rollDataArr.count > 0)) {

    [_delegate didSelectPicWithIndexPath:(self.scrollView.contentOffset.x / self.scrollView.frame.size.width)];
}else{

    [_delegate didSelectPicWithIndexPath:-1];
}

}</code></pre>

四 調用

#import "ViewController.h"

import "RollView.h"

@interface ViewController ()<RollViewDelegate>

@property (nonatomic, strong) RollView *rollView;

@end</code></pre>

-(void)creatPicRollView{

self.rollView = [[RollView alloc] initWithFrame:CGRectMake(0, 50, self.view.frame.size.width, 150) withDistanceForScroll:12.0f withGap:8.0f];

/**全屏寬滑動 視圖之間間隙,  將 Distance 設置為 -12.0f*/

// self.rollView = [[RollView alloc] initWithFrame:CGRectMake(0, 50, self.view.frame.size.width, 150) withDistanceForScroll: -12.0f withGap:8.0f]; // self.rollView.backgroundColor = [UIColor blackColor];

self.rollView.delegate = self;

[self.view addSubview:self.rollView];


NSArray *arr = @[@"1.jpg",
                 @"2.jpg",
                 @"3.jpg"];

[self.rollView rollView:arr];

}

pragma mark - 滾動視圖協議

-(void)didSelectPicWithIndexPath:(NSInteger)index{

if (index != -1) {

    NSLog(@"%ld", (long)index);
}

}</code></pre>

五 效果

分頁效果下 滑動寬度小于屏幕寬度 露出上下頁內容

滑動視圖之間有間隙

 

來自:http://www.jianshu.com/p/9c1be359fd1b

 

 本文由用戶 SHAREHONEY 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!