网上有很多跑马灯的demo,但是都是没有带图片的,所以只能自己写一个了
我的思路就是直接用scrollView,上面放view,让他一直滚
(可以把scrollView换成tableView的)
主要用到了setContentOffset这个方法
但是使用
[self.scrollView setContentOffset:CGPointMake(0,0) animated:YES];
返回到最初时却出现了一个bug,就是视图往回滚了
所以我就想要不多写一个视图,让他代替CGPointMake(0,0) 的动画,到时关掉动画效果就行了,说干就干
#import "HorseRaceLampView.h"
#import "UIView+Extionsiton.h"
#import "HorseRaceLampCell.h"
@interface HorseRaceLampView ()<UIScrollViewDelegate>
/**
定时器
*/
@property (nonatomic, strong) NSTimer *timer;
/**
滚动视图
*/
@property (nonatomic, strong) UIScrollView *scrollView;
/**
记录已经加载的视图
*/
@property (nonatomic, strong) NSMutableArray *viewList;
/**
当前滑动第几个界面 1开始
*/
@property (nonatomic, assign) NSInteger currentIndex;
/**
处理的数组,因为要避免回退动画,就是最后一个回到第一个
*/
@property (nonatomic, strong) NSMutableArray *tempArr;
@end
@implementationHorseRaceLampView
-(instancetype)initWithFrame:(CGRect)frame{
if(self= [superinitWithFrame:frame]) {
[selfinitialize];
[selfcreateUI];
}
return self;
}
#pragma mark - 生命周期
-(void)dealloc{
[self.timer invalidate];
self.timer=nil;
}
#pragma mark - 初始化
-(void)initialize{
self.currentIndex = 1;
}
#pragma mark - 创建UI
-(void)createUI{
self.scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
self.scrollView.backgroundColor = UIColor.grayColor;
self.scrollView.scrollEnabled = NO;
self.scrollView.showsVerticalScrollIndicator = NO;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.delegate = self;
[self addSubview:self.scrollView];
}
#pragma mark - 私用方法
#pragma mark - 公共方法
- (void)startAnimation {
if (!self.timer.isValid) {
[self.timerfire];
}
}
-(void) stopAnimation{ //结束动画
if (self.timer.isValid) {
[self.timer invalidate];
self.timer=nil;
}
}
#pragma mark - 通知方法
#pragma mark - 监听代理
-(void)refreshProgress{
CGFloat y = self.currentIndex * self.scrollView.height;
self.currentIndex++;
[self.scrollView setContentOffset:CGPointMake(0,y) animated:YES];
}
#pragma mark - 点击事件
#pragma mark - 代理协议
// 当滚动视图动画完成后,调用该方法,如果没有动画,那么该方法将不被调用
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView*)scrollView{
if (self.currentIndex == self.tempArr.count) {
self.currentIndex=1;
[self.scrollView setContentOffset:CGPointMake(0,0) animated:NO];
}
}
#pragma mark - 网络请求
#pragma mark - 懒加载
- (NSMutableArray*)viewList{
if(!_viewList) {
_viewList = [[NSMutableArray alloc] init];
}
return _viewList;
}
-(NSTimer*)timer{
if(!_timer) {
_timer = [NSTimer timerWithTimeInterval: 1.0f target:self selector:@selector(refreshProgress) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
}
return _timer;
}
-(NSMutableArray *)tempArr{
if(!_tempArr) {
_tempArr= [[NSMutableArrayalloc]init];
}
return _tempArr;
}
#pragma mark - getset方法
-(void)setModels:(NSArray*)models{
_models= models;
//移除动画
[self.scrollView.layer removeAllAnimations];
//先移除之前的item
for(UIView*vinself.scrollView.subviews) {
if([visKindOfClass:[HorseRaceLampCellclass]]) {
[vremoveFromSuperview];
}
}
[self.viewList removeAllObjects];
// 为了解决闪一下,所以要加多加一个view用来替代动画
self.tempArr = [NSMutableArray arrayWithArray:models];
// 数据要加第一个
[self.tempArr addObject:models.firstObject];
for(inti =0; i
NSDictionary*dic =self.tempArr[i];
HorseRaceLampCell *nb = [HorseRaceLampCell initView];
nb.backgroundColor = [UIColor purpleColor];
nb.frame = CGRectMake(0, (i*self.scrollView.height), self.scrollView.width, self.scrollView.height);
nb.tag= i;
nb.titleLB.text= dic[@"title"];
nb.iconImgV.image= [UIImageimageNamed:dic[@"icon"]];
[self.scrollView addSubview:nb];
[self.viewList addObject:nb];
}
self.scrollView.contentSize = CGSizeMake(0, self.tempArr.count * self.scrollView.height);
self.clipsToBounds = YES;
}
HorseRaceLampView *marqueeView = [[HorseRaceLampView alloc] initWithFrame:CGRectMake(0,100,self.view.bounds.size.width,44)];
[self.view addSubview:marqueeView];
[marqueeView setModels:@[@{@"title":@"你好吗",@"icon":@"login-password"},@{@"title":@"我很好",@"icon":@"login-phone"}]];
//开始动画
[marqueeView startAnimation];
当然也有很多可以优化的地方
以上就是全部代码了,HorseRaceLampCell这个自定义替换成需求样式就好了
代码是在http://www.cnblogs.com/qqcc1388/p/8664280.html的基础上改的
转载:http://www.cnblogs.com/qqcc1388/p/8664280.html
在分享一个swift版的,也是自定义视图的
用collectionView做的 复制一下代码就可以直接用
import UIKit
enum Roll {
case ver /// 垂直
case hor /// 水平
}
class HorseRunningLightsView: UIView {
deinit {
if timer.isValid {
timer.invalidate()
}
}
/// 定时器
private lazy var timer : Timer = {
let timer = Timer(timeInterval: 2.0, target: self, selector: #selector(startToMove), userInfo: nil, repeats: true)
RunLoop.current.add(timer, forMode: .common)
return timer
}()
/// 创建布局对象
let flowLayout = UICollectionViewFlowLayout()
/// collectionView
private lazy var collectionView : UICollectionView = {
let collectionView = UICollectionView(frame: self.bounds, collectionViewLayout: flowLayout)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
return collectionView
}()
/// 滚动方向
private var rollType : Roll?
/// 当前滑动第几个cell
private var currentIndex : Int?
/// 处理的数组,因为要避免回退动画,就是最后一个回到第一个
private var tempList : Array<Any>?
/// 数据源
var models : Array<Any>? {
didSet {
guard models != nil && (models?.count)! > 0 else {
return
}
tempList = Array(models!)
/// 添加多一个数据源用来作过渡
tempList?.append(models?.first as Any)
/// 延迟2秒
timer.fireDate = Date(timeIntervalSinceNow: 2)
}
}
override init(frame: CGRect) {
super.init(frame: frame)
initialize()
createUI()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
/// 出现构造方法
convenience init(frame: CGRect,type: Roll) {
self.init(frame: frame)
rollType = type
if type == Roll.ver {
flowLayout.scrollDirection = .vertical
}else{
flowLayout.scrollDirection = .horizontal
}
}
}
extension HorseRunningLightsView: UICollectionViewDelegate,UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return tempList?.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
if indexPath.row == 0 {
cell.backgroundColor = UIColor.red
}else if indexPath.row == 1 {
cell.backgroundColor = UIColor.yellow
}else if indexPath.row == 2 {
cell.backgroundColor = UIColor.green
}else if indexPath.row == 3 {
cell.backgroundColor = UIColor.blue
}else if indexPath.row == 4 {
cell.backgroundColor = UIColor.purple
}
return cell
}
}
extension HorseRunningLightsView: UICollectionViewDelegateFlowLayout {
/// cell尺寸
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: self.collectionView.width, height: self.collectionView.height)
}
/// 这个是两行cell之间的间距(上下行cell的间距)
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
/// 定义每个Section的四边间距
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
}
extension HorseRunningLightsView: UIScrollViewDelegate {
/// scrollView的动画结束后会进入此方法
/// 当滚动到最后一个的处理
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
if self.currentIndex == self.tempList?.count {
self.currentIndex = 1
self.collectionView.setContentOffset(CGPoint(x: 0, y: 0), animated: false)
}
}
}
extension HorseRunningLightsView {
func initialize() {
currentIndex = 1
}
func createUI() {
addSubview(collectionView)
}
}
extension HorseRunningLightsView {
@objc private func startToMove(){
if rollType == Roll.ver {
let y = CGFloat(self.currentIndex!) * self.collectionView.height
self.currentIndex = self.currentIndex! + 1
self.collectionView.setContentOffset(CGPoint(x: 0, y: y), animated: true)
}else{
let x = CGFloat(self.currentIndex!) * self.collectionView.width
self.currentIndex = self.currentIndex! + 1
self.collectionView.setContentOffset(CGPoint(x: x, y: 0), animated: true)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let v = HorseRunningLightsView(frame: CGRect(x: 0, y: 100, width: self.view.width, height: 44), type: Roll.hor)
v.models = ["你好吗","呵呵呵","你还好意思问我","我这不是在关心你嘛"]
view.addSubview(v)
}
网友评论