iOS自定義垂直滾動輪播視圖

最近因為項目需求,需要用到類似淘寶,天貓,京東的文字垂直輪播效果,網上找了不少類似demo之后,決定自己動手造一個,為了增加可擴展性,把滾動的子視圖全部交給使用者來處理,先看下效果圖
advertScroll.gif

調用示例代碼如下:

_labelView = [[LFAdvertScrollView alloc] initWithFrame:CGRectMake(0, 100, ScreenWidth, 40)];
_labelView.totalCount = 4;
_labelView.dataSource = self;
_labelView.delegate = self;
[self.view addSubview:_labelView];

_attbriuteView = [[LFAdvertScrollView alloc] initWithFrame:CGRectMake(0, 160, ScreenWidth, 60)];
_attbriuteView.totalCount = 4;
_attbriuteView.dataSource = self;
_attbriuteView.delegate = self;
[self.view addSubview:_attbriuteView];

_imageView = [[LFAdvertScrollView alloc] initWithFrame:CGRectMake(0, 240, ScreenWidth, 200)];
_imageView.totalCount = 4;
_imageView.dataSource = self;
_imageView.delegate = self;
[self.view addSubview:_imageView];

遵循代理要實現的方法:

   - (Class)customViewClassForAdvertScrollView:(LFAdvertScrollView *)view {
    if (view == _labelView) {
        return [UILabel class];
    } else if (view == _imageView) {
        return [UIImageView class];
    } else {
        return [CustomAdvertView class];
    }
}
- (void)configCustomView:(UIView *)view forIndex:(NSInteger)index advertView:(nonnull LFAdvertScrollView *)advertView {
    if (advertView == _labelView) {
        UILabel *testLabel = (UILabel *)view;
        testLabel.text = @[@"I'm Li Bai",@"I'm Du Fu",@"I'm Bai Ju Yi",@"I'm Wang An Shi"][index];
        testLabel.textAlignment = NSTextAlignmentCenter;
        testLabel.textColor = [UIColor purpleColor];
        testLabel.font = [UIFont boldSystemFontOfSize:16];
        testLabel.backgroundColor = [UIColor cyanColor];
    } else if (advertView == _imageView) {
        UIImageView *imageView = (UIImageView *)view;
        imageView.image = [UIImage imageNamed:@[@"h1.jpg",
                                                @"h2.jpg",
                                                @"h3.jpg",
                                                @"h4.jpg"][index]];
        
    } else {
        CustomAdvertView *customView = (CustomAdvertView *)view;
        customView.leftImage.image = [UIImage imageNamed:@[@"h1.jpg",
                                                           @"h2.jpg",
                                                           @"h3.jpg",
                                                           @"h4.jpg"][index]];
        customView.rightLabel.text = @[@"I'm Li Bai,I'm Li Bai,I'm Li Bai,I'm Li Bai,I'm Li Bai",@"I'm Du Fu",@"I'm Bai Ju Yi",@"I'm Wang An Shi"][index];
    }
 
   
}

重點來了,看了很多都是基于UICollectionView實現的,自動滾動模式下,會返回很多個Item,我這里嘗試用UIScrollview復用三個view來實現自動滾動,核心思路是用戶看到的永遠是中間的那個view,通過控制偏移量來實現自動滾動效果。
LFAdvertScrollView.h文件內容:

@class LFAdvertScrollView;

@protocol LFAdvertScrollViewDataSource <NSObject>


/**
 返回要滾動的視圖類型

 @param view LFAdvertScrollView
 @return  返回要滾動的視圖類型,!!!:必須是繼承于UIView實現的類

 */
- (Class)customViewClassForAdvertScrollView:(LFAdvertScrollView *)view;

@end


@protocol LFAdvertScrollViewDelegate <NSObject>

/**
 給自定義視圖賦值

 @param view 賦值的視圖
 @param index 第幾個視圖
 @param advertView LFAdvertScrollView
 */
- (void)configCustomView:(UIView *)view forIndex:(NSInteger)index advertView:(LFAdvertScrollView *)advertView;

/**
 點擊回調

 @param advertView LFAdvertScrollView
 @param index 第幾個視圖
 */
- (void)advertView:(LFAdvertScrollView *)advertView didSelectViewIndex:(NSInteger )index;

@end

@interface LFAdvertScrollView : UIView

/**
 數據源個數,必傳項
 */
@property (nonatomic, assign) NSInteger totalCount;

/**
 滾動時間間隔
 */
@property (nonatomic, assign) NSTimeInterval autoScrollInterval;

@property (nonatomic, weak)   id<LFAdvertScrollViewDelegate>delegate;

@property (nonatomic, weak)   id<LFAdvertScrollViewDataSource>dataSource;

@end

實現方式很簡單,就是復用三個view實現無限輪播,點擊事件只添加到中間的view上面,然后點擊回調出當前頁碼
這是主要實現部分:

///設置事件代理
- (void)setDelegate:(id<LFAdvertScrollViewDelegate>)delegate {
    _delegate = delegate;
    if ([_delegate respondsToSelector:@selector(configCustomView:forIndex:advertView:)]) {
        [self.delegate configCustomView:self.topView forIndex:self.totalCount - 1 advertView:self];
        [self.delegate configCustomView:self.middleView forIndex:0 advertView:self];
        [self.delegate configCustomView:self.bottomView forIndex:1 advertView:self];
    }
}
///設置視圖類型代理
- (void)setDataSource:(id<LFAdvertScrollViewDataSource>)dataSource {
    _dataSource = dataSource;
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(customViewClassForAdvertScrollView:)]) {
        ///拿到用戶自定義的視圖類名
        Class CustomClass = [self.dataSource customViewClassForAdvertScrollView:self];
        
        self.topView = [[CustomClass alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
        
        self.middleView = [[CustomClass alloc] initWithFrame:CGRectMake(0, self.frame.size.height * 1, self.frame.size.width, self.frame.size.height)];
        
        ///用戶看到的只有中間視圖,所以為了簡單起見,只需要添加中間視圖的點擊響應
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(customViewTap)];
        [self.middleView addGestureRecognizer:tap];
        
        self.bottomView = [[CustomClass alloc] initWithFrame:CGRectMake(0, self.frame.size.height * 2, self.frame.size.width, self.frame.size.height)];
        
        [self.contentView addSubview:self.topView];
        [self.contentView addSubview:self.middleView];
        [self.contentView addSubview:self.bottomView];
    }
}

#pragma mark - timer執行的方法
- (void)automaticScroll
{
    self.currentPage++;
    if (self.currentPage  == self.totalCount) {
        self.currentPage = 0;
    }
    [UIView animateWithDuration:1 animations:^{
        ///動畫發生的滑動
        self.middleView.userInteractionEnabled =NO;
        self.contentView.contentOffset =CGPointMake(0, CGRectGetHeight(self.contentView.frame) * 2);
    } completion:^(BOOL finished) {
        ///滑動完成后,把當前現實的imageview重現移動回中間位置,此處不能使用動畫,用戶感覺不到
        ///移動前,先把中間imageview的image設置成當前現實的iamge
        self.middleView.userInteractionEnabled = YES;
        if (self.delegate && [self.delegate respondsToSelector:@selector(configCustomView:forIndex:advertView:)]) {
            [self.delegate configCustomView:self.topView forIndex:self.currentPage == 0 ?self.totalCount - 1 : self.currentPage - 1 advertView:self];
            [self.delegate configCustomView:self.middleView forIndex:self.currentPage advertView:self];
            [self.delegate configCustomView:self.bottomView forIndex:self.currentPage == self.totalCount - 1 ? 0 : self.currentPage + 1 advertView:self];
        }
        self.contentView.contentOffset =CGPointMake(0, CGRectGetHeight(self.contentView.frame) * 1);
    }];

}

#pragma mark - 用戶點擊

-(void)customViewTap{
    if (self.delegate && [self.delegate respondsToSelector:@selector(advertView:didSelectViewIndex:)]) {
        [self.delegate advertView:self didSelectViewIndex:self.currentPage];
    }
}

代碼基本就這些了, 寫這篇純屬算是個人筆記,不喜勿噴,有更好的想法或者意見的歡迎大家指出。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容

  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,151評論 4 61
  • 今晚,看見音樂,聽見舞蹈。驚喜于音樂舞蹈全新的演繹方式外,緊抓我心弦的,是同一個故事,看到不同版本的我們自己,投射...
    房頂一彎弦月閱讀 398評論 0 0
  • 生日快樂 對我來說有點特別滴小于。 今天終于做出點東西了 我加油了 棒?,F在是八點二十九剛走出工廠 遇上晚自修放學...
    福進進閱讀 89評論 0 0
  • 昨天早睡了,今天補上。 昨天我拉著一張茶桌,和明澤一起返程。因為后座沒地方坐,不得已坐在了副駕駛位置??汕?,走到界...
    觀心不語閱讀 149評論 0 0