该案例为黑马程序员IOS基础UI视频教程第九天案例
该案例中主要使用UITableView中自带的模板来创建UITableViewCell,这种方式可以无需在创建xib文件,无需再重写initWithStyle方法,略方便一点。案例中也使用了一些其他的小知识点,如:将消息框加入到窗口界面而不是UITableView中、设置文本框的圆角显示等
本案例主要实现的功能有三点:
- 根据plist文件创建UITableView并显示出数据;
- 点击按钮后按钮变为已下载并弹出提示框提示下载过程;
- 点击一次下载后按钮始终显示为已下载并不可点击;
实现的最终效果如下图所示
最终效果.png该案例的实现思路与使用xib文件的实现思路几乎完全相同,只是将原先xib文件换为了tableview的单元格模板。使用单元格模板时直接重用就可以了,无需考虑缓存池中不存在单元格以供重用的情况。
第一步:导入素材、字典转模型、懒加载
第二步:创建界面,创建cell模板,创建对应controller类和cell类并挂接
第三步:在cell类中添加模型属性,实现模型属性的set方法,在方法中为各控件赋值
第四步:实现UITableView的数据源方法,使cell显示出来
第五步:为下载按钮注册单击事件,在事件中实现状态的转换并显示消息提示框
-
实现状态转换:因为单元格被点击一次以后不允许再次被点击,也就是说需要有一个属性来记录单元格是否被点击,保证即使单元格被重用也不会出错。这就需要在模型中添加一个属性来记录
@property(nonatomic , assign) Boolean isDownload
。当点击按钮时,一方面将按钮的enable
设置为NO
,另一方面将isDownload
设置为YES
-
显示消息提示框:因为按钮的单击事件是在cell类中实现的,cell类中无法显示提示框,因此需要通过代理事件来实现,为cell自定义一个delegate方法,cell创建时将其delegate属性指定为控制器本身,使控制器遵守这个代理协议并实现代理方法,在代理方法内部实现消息提示框的动画效果
代理方法:
@class LJAppCell; @protocol LJAppCellDelegate <NSObject> -(void)downloadDidClick:(LJAppCell *)appcell; @end @class LJApp; @interface LJAppCell : UITableViewCell //数据模型 @property(nonatomic , strong) LJApp * app_model; //delegate属性 @property(nonatomic , weak) id<LJAppCellDelegate> delegate; @end
在单击事件中调用代理方法:
if ([self.delegate respondsToSelector:@selector(downloadDidClick:)]) { //调用代理方法 [self.delegate downloadDidClick:self]; }
在控制器中实现代理方法:
-(void)downloadDidClick:(LJAppCell *)appcell { //创建一个label并加入到当前的屏幕中,注意,不要加入到当前的tableView中,否则会随着tableView的滑动而滑动 UILabel * lbl_message = [[UILabel alloc] init]; [[[UIApplication sharedApplication] keyWindow] addSubview:lbl_message]; //设置lable的相关属性 //背景色 lbl_message.backgroundColor = [UIColor grayColor]; //文本颜色与文本内容 lbl_message.textColor = [UIColor redColor]; lbl_message.text = @"正在下载·····"; //文本对齐方式 lbl_message.textAlignment = NSTextAlignmentCenter; //文字大小 lbl_message.font = [UIFont systemFontOfSize:20.0]; //设置文本框的圆角显示效果 lbl_message.layer.cornerRadius = 5; lbl_message.clipsToBounds = YES; //透明度 lbl_message.alpha = 0; //设置frame CGFloat lbl_messageW = 250; CGFloat lbl_messageH = 50; //通过[[UIScreen mainScreen] bounds]来获取当前屏幕的尺寸 CGFloat lbl_messageX = ([[UIScreen mainScreen] bounds].size.width - lbl_messageW)/2; CGFloat lbl_messageY = ([[UIScreen mainScreen] bounds].size.height - lbl_messageH)/2; lbl_message.frame = CGRectMake(lbl_messageX, lbl_messageY, lbl_messageW, lbl_messageH); //动画实现lable的出现和消失,通过改变label的透明度来实现 [UIView animateWithDuration:0.8 animations:^{ lbl_message.alpha = 1; } completion:^(BOOL finished) { if (finished) { [UIView animateWithDuration:0.8 delay:2.0 options:UIViewAnimationOptionCurveLinear animations:^{ lbl_message.alpha = 0; } completion:^(BOOL finished) { [lbl_message removeFromSuperview]; }]; } }]; }
- 避免单元格在重用时出现下载状态的错误显示:由于模型中已有属性记录该模型是否已被下载,因此可以让每个单元格在显示时就进行一次判断,如果已下载则不可点击,如果未下载则可以点击,这段代码可以放在cell模型中对模型数据的set方法重写时执行
//根据模型数据中是否已下载来设置按钮 if (app_model.isDownload) { //使按钮不可点击 self.btn_download.enabled = NO; } else { //使按钮可点击 self.btn_download.enabled = YES; }
由于本人水平有限,不当之处还请批评指正。初学IOS,希望大家一起交流一起进步~
网友评论