欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Objective-C实现无限循环轮播器

程序员文章站 2023-12-04 09:38:04
先看看效果图: 具体实现代码: 1. 控制器     // // appdelegate.m // 无限...

先看看效果图:

Objective-C实现无限循环轮播器

具体实现代码:

1. 控制器    

//
// appdelegate.m
// 无限轮播器
//
// created by zhangmi on 16/5/16.
// copyright © 2016年 paramount pictures. all rights reserved.
//
#import "viewcontroller.h"
#import "sninfinitescrollview.h"
 
@interface viewcontroller ()
 
@end
 
@implementation viewcontroller
 
- (void)viewdidload {
 [super viewdidload];
 // do any additional setup after loading the view, typically from a nib.
  
 nsmutablearray * images = [nsmutablearray array];
 for (int i = 0; i < 5; i++) {
  nsstring * imagename = [nsstring stringwithformat:@"ad_%02d", i]; //img01
  uiimage * image = [uiimage imagenamed:imagename];
  [images addobject:image];
 }
 uiview * scrollview = [sninfinitescrollview scrollviewwithframe:cgrectmake(0, 20, 414, 200) superview:self.view images:images scrolldirection:scrolldirectionhorizontal pageindicatortintcolor:[uicolor lightgraycolor] currentpageindicatortintcolor:[uicolor orangecolor] imageviewcontentmode:uiviewcontentmodescaleaspectfit];
  
 [self.view addsubview:scrollview];
}
 
@end

2. 显示内容界面设置

//
// appdelegate.m
// 无限轮播器
//
// created by zhangmi on 16/5/16.
// copyright © 2016年 paramount pictures. all rights reserved.
//
 
#import "sninfinitescrollview.h"
 
static int const imageviewcount = 3;
#define scrollviewwidth self.scrollview.frame.size.width
#define scrollviewheight self.scrollview.frame.size.height
 
@interface sninfinitescrollview () <uiscrollviewdelegate>
 
@property(weak, nonatomic) uiscrollview * scrollview;
@property(weak, nonatomic) nstimer * timer;
/** pageindex */
@property(nonatomic, assign) nsinteger pageindex;
 
@end
 
@implementation sninfinitescrollview
 
- (void)setimages:(nsarray<uiimage *> *)images {
  
 _images = images;
  
 // 设置页码
 self.pageindex = 0;
  
 // 设置内容
 [self updatecontent];
  
 // 开始定时器
 [self starttimer];
}
 
/** 代码创建的时候调用. */
- (instancetype)initwithframe:(cgrect)frame {
 if (self = [super initwithframe:frame]) {
  // 滚动视图
  uiscrollview * scrollview = [[uiscrollview alloc] init];
   
  self.scrollview = scrollview;
  scrollview.delegate = self;
  // scroller属性
  scrollview.showshorizontalscrollindicator = no;
  scrollview.showsverticalscrollindicator = no;
  scrollview.pagingenabled = yes;
  scrollview.bounces = no;
  // 添加scrollview
  [self addsubview:scrollview];
   
  // 图片控件
  for (int i = 0; i < imageviewcount; i++) {
   uiimageview * imageview = [[uiimageview alloc] init];
   // 图片不变形处理.
   imageview.contentmode = self.imageviewcontentmode;
   [scrollview addsubview:imageview];
  }
 }
 return self;
}
/** 布局 子控件, 只执行一次 */
- (void)layoutsubviews {
 [super layoutsubviews];
  
 self.scrollview.frame = self.bounds;
 if (self.scrolldirection == scrolldirectionvertical) {
  self.scrollview.contentsize = cgsizemake(0, imageviewcount * self.bounds.size.height);
 } else {
  self.scrollview.contentsize = cgsizemake(imageviewcount * self.bounds.size.width, 0);
 }
  
 for (int i = 0; i < imageviewcount; i++) {
  uiimageview * imageview = self.scrollview.subviews[i];
   
  if (self.scrolldirection == scrolldirectionvertical) {
   imageview.frame = cgrectmake(0, i * self.scrollview.frame.size.height, self.scrollview.frame.size.width, self.scrollview.frame.size.height);
  } else {
   imageview.frame = cgrectmake(i * self.scrollview.frame.size.width, 0, self.scrollview.frame.size.width, self.scrollview.frame.size.height);
  }
 }
 // 设置内容
 [self updatecontent];
}
#pragma mark - 内容更新
- (void)updatecontent {
 // 设置图片
 for (int i = 0; i < self.scrollview.subviews.count; i++) {
   
  nsinteger pageindex = self.pageindex;
  // 遍历每一个imageview
  uiimageview * imageview = self.scrollview.subviews[i];
   
  if (i == 0) {
   pageindex--;
  } else if (i == 2) {
   pageindex++;
  }
   
  if (pageindex < 0) {
   pageindex = self.images.count - 1;
  } else if (pageindex >= self.images.count) {
   pageindex = 0;
  }
  // 图片角标 赋值给 imageview的tag
  imageview.tag = pageindex;
  imageview.image = self.images[imageview.tag];
 }
  
 // 设置偏移量在中间 // 不能使用带动画 contentoffset
 if (self.scrolldirection == scrolldirectionvertical) {
  self.scrollview.contentoffset = cgpointmake(0, scrollviewheight);
 } else {
  self.scrollview.contentoffset = cgpointmake(scrollviewwidth, 0);
 }
}
#pragma mark - <uiscrollviewdelegate>
- (void)scrollviewdidscroll:(uiscrollview *)scrollview {
 // 找出最中间的那个图片控件
 nsinteger page = self.pageindex;
 cgpoint point = cgpointzero;
 for (int i = 0; i < self.scrollview.subviews.count; i++) {
  uiimageview * imageview = self.scrollview.subviews[i];
  point = [scrollview convertpoint:imageview.frame.origin toview:self.superview];
  //=****** other way ****************** stone ***
  if (self.scrolldirection == scrolldirectionvertical) {
   if (abs(point.y - self.frame.origin.y) < 1.0) {
    page = imageview.tag;
   }
  } else {
   if (abs(point.x - self.frame.origin.x) < 1.0) {
    page = imageview.tag;
   }
  }
 }
 self.pageindex = page;
 self.pagecontrol.currentpage = page;
  
 //拖动结束会调用 [self updatecontent];
 //#warning mark - 没有动画正常 , 有动画不动, 一直是原点
 // [self updatecontent]; // 没有动画正常 , 有动画不动, 一直是原点
}
/** 开始拖拽 */
- (void)scrollviewwillbegindragging:(uiscrollview *)scrollview {
 // 停止定时器
 [self stoptimer];
}
/** 结束拖拽 */
- (void)scrollviewdidenddragging:(uiscrollview *)scrollview willdecelerate:(bool)decelerate {
 // 开启定时器
 [self starttimer];
}
/** 减速完毕 */
- (void)scrollviewdidenddecelerating:(uiscrollview *)scrollview {
 // 更新内容 , 如果contentoffset 不带动画的话 不走这个方法
 [self updatecontent];
}
/** 结束滚动动画 */ // 这是保险的做法吧... 如果contentoffset 不带动画的话 不走这个方法
- (void)scrollviewdidendscrollinganimation:(uiscrollview *)scrollview {
 // 更新内容
 [self updatecontent];
}
 
#pragma mark - 定时器处理
- (void)starttimer {
  
 nstimer * timer = [nstimer scheduledtimerwithtimeinterval:1.0 target:self selector:@selector(next:) userinfo:nil repeats:yes];
 // [[nsrunloop mainrunloop] addtimer:timer formode:nsrunloopcommonmodes];
 [[nsrunloop currentrunloop] addtimer:timer formode:nsrunloopcommonmodes];
 self.timer = timer;
}
 
- (void)stoptimer {
 [self.timer invalidate];
 self.timer = nil;
}
 
- (void)next:(nstimer *)timer {
 if (self.scrolldirection == scrolldirectionvertical) {
  [self.scrollview setcontentoffset:cgpointmake(0, 2 * self.scrollview.frame.size.height) animated:yes];
 } else {
  [self.scrollview setcontentoffset:cgpointmake(2 * self.scrollview.frame.size.width, 0) animated:yes];
 }
}
//=****** 简单调用 ****************** stone ***
+ (instancetype)scrollviewwithframe:(cgrect)frame superview:(uiview *)superview images:(nsarray<uiimage *> *)images scrolldirection:(scrolldirection)scrolldirection pageindicatortintcolor:(uicolor *)pageindicatortintcolor currentpageindicatortintcolor:(uicolor *)currentpageindicatortintcolor imageviewcontentmode:(uiviewcontentmode)imageviewcontentmode {
  
 //=****** 添加自定义scrollview ****************** stone ***
 sninfinitescrollview * scrollview = [[sninfinitescrollview alloc] init];
 scrollview.frame = frame;
 scrollview.imageviewcontentmode = imageviewcontentmode;
 scrollview.scrolldirection = scrolldirection;
 //=****** 添加image ****************** stone ***
 scrollview.images = images;
 //=****** 添加pagecontrol ****************** stone ***
 uipagecontrol * pagecontrol = [[uipagecontrol alloc] init];
 scrollview.pagecontrol = pagecontrol;
 pagecontrol.enabled = no;
 pagecontrol.currentpageindicatortintcolor = currentpageindicatortintcolor;
 pagecontrol.pageindicatortintcolor = pageindicatortintcolor;
 pagecontrol.numberofpages = scrollview.images.count;
 pagecontrol.bounds = cgrectmake(0, 0, scrollview.bounds.size.width, 44);
 pagecontrol.center = cgpointmake(scrollview.bounds.size.width * 0.5, scrollview.bounds.size.height * 0.9);
 [scrollview addsubview:pagecontrol];
 [superview addsubview:scrollview];
 //=************************ stone ***
 return scrollview;
}
 
@end

以上就是本文的全部内容,希望对大家的学习有所帮助。