原理:NSTimer
+UICollectionView
:
-- 动态图.gif -- | -- 静态图 -- |
---|---|
|
![]() |
1:首先熟悉一下NSTimer的常用属性
-(void)fire // 启动
- (void)invalidate; // 停止
这个是唯一一个可以将计时器从runloop中移出的方法。
2:NSTimer为了取消内存以及和循环引用的问题 ,在NSTimer停止的时候(invalidate)要做的处理
[_timerinvalidate];// 停止 从Runlop中移除
_timer = nil; // 放在内存溢出,重置为nil
3、计时器NSTimer
的"启动"
与"停止"
、"暂停"
和"继续"
,
暂停和继续:NSTimer
有一个属性:@property (copy) NSDate *fireDate;
,使用set方法,[self.timer setFireDate:(NSDate * _Nonnull)];
Timer
启动:
_timer = [NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(updateStepWithCusInterval) userInfo:nil repeats:YES];
Timer
停止:
[self.timer invalidate];
但是注意:invalidate
方法会完全释放了Timer
对象,是无法从暂停中再恢复定时,只能重新生成Timer
对象,再开启定时。
怎么可以暂停定时器,用NSDate
的distantFutre
方法
[self.timer setFireDate:[NSDate distantFutre]]; // NSTimer暂停
需要继续的时候调用date
方法
[self.timer setFireDate:[NSDate date]]; // NSTimer继续
4、下面是例子:一个简单的天气预警
Demo
if (self.weatherWarningModels.count > 0) {
self.earlyWarningView.hidden = NO;
self.earlyWarningView.weatherWarningModels = self.weatherWarningModels;
[self.earlyWarningView refreshView];
// 点击,进入天气 预警或异常 详情页:
self.earlyWarningView.clickWarnIngModelBlock = ^(GWHome_WeatherWarningAndAbnormalModel * _Nonnull weatherWarningAndAbnormalModel) {
[LCM_AlertViewFactory showToastWithMessage:weatherWarningAndAbnormalModel.title];
};
} else {
self.earlyWarningView.hidden = YES;
}
.h
#import <UIKit/UIKit.h>
#import "GWHome_WeatherWarningAndAbnormalModel.h" // 【首页】:天气预警 + 异常天气
NS_ASSUME_NONNULL_BEGIN
@interface CWEarlyWarning_WeatherImgView : UIView
// 预警天气 + 异常天气
@property (nonatomic, strong) NSArray<GWHome_WeatherWarningAndAbnormalModel *> *weatherWarningModels;
/** 点击,直接返回该点击预警或天气异常的model */
@property (nonatomic, copy) void (^clickWarnIngModelBlock) (GWHome_WeatherWarningAndAbnormalModel *weatherWarningAndAbnormalModel);
- (void)refreshView;
@end
NS_ASSUME_NONNULL_END
.m
// 预警 ,比如: 大雨红色预警(上下翻页)
#import "CWEarlyWarning_WeatherImgView.h"
#import "CWEarlyWarning_WeatherImgViewCell.h"
@interface CWEarlyWarning_WeatherImgView ()<UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@property (nonatomic, strong) UICollectionViewFlowLayout *layout;
@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, assign) NSInteger itemCell; // cell的索引值
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation CWEarlyWarning_WeatherImgView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = RGBA(181, 66, 62, 1);
[self setupUI];
}
return self;
}
- (void)refreshView {
if (self.weatherWarningModels.count > 1) {
NSMutableArray *alertArr = [NSMutableArray arrayWithCapacity:0];
alertArr = [self.weatherWarningModels mutableCopy];
[alertArr addObject:self.weatherWarningModels[0]]; // 将第一个元素,取出在放到可变数组中,排在末尾啊
self.weatherWarningModels = [alertArr copy];
[self.collectionView reloadData]; // 在循环之前,刷新(更新)一下,将最新的数组数据赋值上。
if (_timer) {
[_timer invalidate];
_timer = nil;
}
self.itemCell = 0;
[self.collectionView setContentOffset:CGPointMake(0,0)animated:NO];
// [self startIconRunLoop]; // 加上这行会闪退
_timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(startIconRunLoop) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
[_timer fire]; // 立即 启动
} else {
if (_timer) {
[_timer invalidate]; // 停止,从Runlop中移除
_timer = nil; // 放在内存溢出,重置为nil
}
}
[self.collectionView reloadData];
}
- (void)startIconRunLoop {
self.itemCell = self.itemCell + 1;
if (self.itemCell <= self.weatherWarningModels.count) {
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:self.itemCell-1 inSection:0] atScrollPosition:(UICollectionViewScrollPositionCenteredVertically) animated:YES];
} else {
[self.collectionView setContentOffset:CGPointMake(0,0)animated:NO];
self.itemCell = 1;
[self startIconRunLoop];
}
}
- (void)dealloc {
[_timer invalidate]; // 停止,从Runlop中移除
_timer = nil; // 放在内存溢出,重置为nil
}
- (void)setupUI {
_layout = [[UICollectionViewFlowLayout alloc] init];
_layout.scrollDirection = UICollectionViewScrollDirectionVertical;
_layout.itemSize = CGSizeMake([UIScreen mainScreen].bounds.size.width/375*118, [UIScreen mainScreen].bounds.size.width/375*22);
_layout.minimumLineSpacing = 10;
_layout.minimumInteritemSpacing = 0;
_layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
_collectionView= [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width/375*118, [UIScreen mainScreen].bounds.size.width/375*22) collectionViewLayout:self.layout];
// UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
_collectionView.backgroundColor = [UIColor clearColor];
_collectionView.delegate = self;
_collectionView.dataSource = self;
_collectionView.showsVerticalScrollIndicator = NO;
_collectionView.scrollEnabled = NO;
[self addSubview:self.collectionView];
[self.collectionView makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self);
}];
[self.collectionView registerClass:[CWEarlyWarning_WeatherImgViewCell class] forCellWithReuseIdentifier:NSStringFromClass([CWEarlyWarning_WeatherImgViewCell class])];
}
#pragma mark -- -- < UICollectionViewDelegate, UICollectionViewDataSource >
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.weatherWarningModels.count;
}
- (nonnull __kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CWEarlyWarning_WeatherImgViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([CWEarlyWarning_WeatherImgViewCell class]) forIndexPath:indexPath];
if (self.weatherWarningModels.count) {
GWHome_WeatherWarningAndAbnormalModel *model = self.weatherWarningModels[indexPath.row];
// 等级: 0金色(异常天气),预警: 1红色,2橙色 ,3 黄色,4 蓝色
if (model.level == 0) {
[cell.warningBut setBackgroundImage:[UIImage imageNamed:@"weather_abNormal_bg_icon"] forState:UIControlStateNormal];
} else if (model.level == 1) {
[cell.warningBut setBackgroundImage:[UIImage imageNamed:@"weather_warning_Red_icon"] forState:UIControlStateNormal];
} else if (model.level == 2) {
[cell.warningBut setBackgroundImage:[UIImage imageNamed:@"weather_warning_Orange_icon"] forState:UIControlStateNormal];
} else if (model.level == 3) {
[cell.warningBut setBackgroundImage:[UIImage imageNamed:@"weather_warning_Yellow_icon"] forState:UIControlStateNormal];
} else if (model.level == 4) {
[cell.warningBut setBackgroundImage:[UIImage imageNamed:@"weather_warning_Blue_icon"] forState:UIControlStateNormal];
}
[cell.warningBut setTitle:[NSString stringWithFormat:@"%@ ", model.title] forState:UIControlStateNormal];
}
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
if (self.clickWarnIngModelBlock) {
self.clickWarnIngModelBlock(self.weatherWarningModels[indexPath.row]);
}
}
@end
网友评论