之前的一篇文章大概讲述了一下UITableView的使用,UITableView在iOS的地位和ListView在Android中的地位基本上算是不相上下,关于ListView的优化网上的也有很多文章。UITableView苹果公司本身就已经优化了其中的功能,不管你有多少数据,每次加载的时候只是加载当前页面的数据,以免造成不必要的内存占用。一个非常常见的优化就是使用Identifier,也就是唯一标示,将页面中不用的对象放在缓存池中,如果有新的对象出现从缓存池中取出。
页面布局
页面布局还是跟上篇文章一样,一个TableView:
不过需要额外的工作的时本次暂时的是服装信息,通过弹框修改服装的价格,需要新建一个服装类,实现UIAlertViewDelegate协议,头文件中的声明:
@interface ViewController : UIViewController <UITableViewDataSource,UITableViewDelegate,UIAlertViewDelegate> @property (weak, nonatomic) IBOutlet UITableView *tableView; @end
服装类的定义:
@interface Dress : NSObject @property (strong,nonatomic) NSString *dressName; @property (strong,nonatomic) NSString *dressDetial; @property (strong,nonatomic) NSString *dressImage; @end
优化与实现
优化之前先实现一些必要的功能,以及一些方法的使用,上篇文章只是涉及了其中的一部分,为了更好的理解,可以先看下实现的效果:
定义存储数据的数组:
@interface ViewController () { NSArray *imageArr; NSArray *dressArr; NSMutableArray *dressList; } @end
初始化数据:
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. imageArr=[[NSArray alloc]initWithObjects:@"dress1.jpeg",@"dress2.jpg",@"dress3.jpg",nil]; dressArr=[[NSArray alloc]initWithObjects:@"七匹狼",@"森马",@"杰克琼斯",@"美特斯邦威",@"以纯",@"真维斯",@"海南之家",nil]; dressList=[NSMutableArray arrayWithCapacity:30]; for (NSInteger i=0; i<30; i++) { Dress *dress=[[Dress alloc]init]; NSInteger imageRandom=arc4random_uniform(3); NSInteger dressRandom=arc4random_uniform(7); NSInteger price=arc4random_uniform(1000)+100; dress.dressImage=imageArr[imageRandom]; dress.dressName=dressArr[dressRandom]; dress.dressDetial=[NSString stringWithFormat:@"促销价:%ld",(long)price]; [dressList addObject:dress]; } }
设置行数:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return [dressList count]; }
设置分组:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; }
设置单元格内容,通过reuseIdentifier设置重用的单元格,dequeueReusableCellWithIdentifier取出可以重用的单元格:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *flag=@"cacheCell"; //生成唯一的标记 UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:flag]; if (cell==nil) { //设置需要显示详情的样式 cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:flag]; } Dress *dress=dressList[indexPath.row]; UIImage *image=[UIImage imageNamed:dress.dressImage]; [cell.imageView setImage:image]; [cell.imageView setFrame:CGRectMake(0, 0, 80, 50)]; [cell.textLabel setText:dress.dressName]; //设置展示小箭头 [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; //设置Tag // [cell setTag:indexPath.row]; [cell.detailTextLabel setText:dress.dressDetial]; NSLog(@"获取更新之后的行:%ld",indexPath.row); return cell; }
选中行之后的弹框设置:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ UIAlertView *alterView=[[UIAlertView alloc] initWithTitle:@"服装价格:" message:nil delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"修改", nil]; [alterView setAlertViewStyle:UIAlertViewStylePlainTextInput]; //选中的Cell UITableViewCell *cell=[tableView cellForRowAtIndexPath:indexPath]; UITextField *textField=[alterView textFieldAtIndex:0]; //设置修改的服装信息 [textField setText:cell.detailTextLabel.text]; [textField setTag:indexPath.row]; [alterView show]; }
UIAlterView中的点击事件:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ if (buttonIndex==1) { UITextField *textField=[alertView textFieldAtIndex:0]; NSArray *selectedRow=[self.tableView indexPathsForSelectedRows]; NSIndexPath *indexPath=selectedRow[0]; Dress *dress=dressList[indexPath.row]; dress.dressDetial=textField.text; NSLog(@"%@---%ld",textField.text,(long)indexPath.row); [self.tableView reloadRowsAtIndexPaths:selectedRow withRowAnimation:UITableViewRowAnimationRight]; } }
设置行高:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 50; }
关于UITable的优化:
1.最常用的就是不重复生成单元格,很常见,很实用;
2.使用不透明的视图可以提高渲染速度,xCode中默认TableCell的背景就是不透明的;
3.如果有必要减少视图中的条目,本文中设置textLabel,detialTextLabel,imageView,accessoryType;
4.更新条目的时候不要整体更新,更新选中的即可,建议reloadRowsAtIndexPaths,而不是使用reloadData;