e...其实这个是扫盲贴,也是基础,又有人会发现本帖是个脑残贴...
问题1.是当我们UIViewController的self.view上有很多乱起八糟的View啊 自定义控件的时候,由于数据是异步回来或者哪个事件响应后才请求网络数据
问题2.有人想有没有tableview的类似的方法比如reloadData之后就刷新了tableview
问题3.又有人想,能不能调用[self.view setNeedDisplay]; 进行刷新view
固定的控件
比如我的self.view上有个jobLabel用来显示职位名称,请求回来的数据中有个对应的字段job,那么所谓的刷新就是直接找到jobLabel的引用,直接赋值text了
如果连接了IBOutlet输出口或者是代码创建的,如下
self.jobLabel.text = [responeObject objectForKey:@"job"]
动态添加的控件
因为某种动态添加的控件又没有存引用,但是确实存在在superView中
还想进行赋值刷新,那么使用viewWithTag 和事先设置好的tag来进行
UILabel *jobLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, 100, 30)]; jobLabel.tag = 11111; [self.view addSubview:jobLabel];
UILabel *jobLabel = [self.view viewWithTag:11111]; jobLabel.text = [responeObject objectForKey:@"job"]
或者根据想要获取控件的特征,遍历superview,获取到 想干什么干什么...
for (UIView *v in self.view.subviews) {
if ([v isKindOfClass:[UILabel class]]) {
//....balabala
}
}
这种情况在老式的cell复用中经常遇见,比如
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *kCellID = @"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID];
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
UILabel *jobLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, 100, 30)];
jobLabel.tag = 11111;
[cell addSubview:jobLabel];
}
UILabel *jobLabel = [cell viewWithTag:11111];
jobLabel.text = [self.dataArray objectAtIndex:indexPath.row];
return cell;
}
多个固定数量控件
比如我有100个UILabel在self.view上,请求回来的数据对应有100条(由于网络请求可能会有多次,创建多个UILabel在请求前后已经不是问题的重点了)
创建时候
for(int i=0;i<=100;i++){
UILabel *jobLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, 100, 30)];
jobLabel.tag = 1000+i;
[self.view addSubview:jobLabel];
}
赋值
for (int i=0;i<=100;i++) {
UILabel *jobLabel = [self.view viewWithTag:1000+i];
jobLabel.text = [responeObject objectForKey:[NSString stringWithFormat:@"job_%zd"],1000+i];
}
上面是使用viewWithTag来获取指定tag的UILable,创建的时候可以把所有UILable放在一个数组或字典中,赋值时候直接获取,赋值就行了
for (int i=0;i<=100;i++) {
UILabel *jobLabel = [_subLables objectForKey:@(1000+i)];
jobLabel.text = [@{} objectForKey:[NSString stringWithFormat:@"job_%zd"],1000+i];
}
多个动态添加的控件
如果我的UILabel个数完全是根据请求回来的数据量创建多个,并且有很多变量,比如位置,内容,颜色等等
那么使用之前创建好的UILabel就满足不了需求啦,解决方案很简单,那就是自己实现一个类似UITableView的reloadData方法,每次网络请求回来,都会先移除所有之前创建的控件,然后在动态添加
移除数组中所有子数据
[self.view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
或者基本的方法,for遍历移除,顺便判断是不是要移除的类型
for(UIView *v in self.view.subviews){
if([v isKindOfClass:[UILabel class]]){
[v removeFromSuperview];
}
}
动态添加
for(int i=0;i<=[responeModelObject count];i++){
Model * m = [responeModelObject objectAtIndex:i];
UILabel *jobLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, 100, 30)];
jobLabel.tag = 1000+i;
jobLabel.text = m.job;
[self.view addSubview:jobLabel];
}
小小示例(自定义控件)
-(void)reloadData{
[_scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
for(int i=0;i<=[self.items count];i++){
Model * m = [self.items objectAtIndex:i];
UILabel *jobLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, 100, 30)];
jobLabel.tag = 1000+i;
jobLabel.text = m.job;
jobLabel.backgroundColor = self.itemColor;
[_scrollView addSubview:jobLabel];
}
//......
}
//重写控件属性items的set方法,当设置数据源的时候reloadData
-(void)setItems:(NSArray *)items{
_items = items;
_currentPageIndex = 0;
[self reloadData];
}
//重写控件属性itemColor的set方法,设置控颜色件属性后,reloadData
-(void)setItemColor:(UIColor*)itemColor{
_itemColor = itemColor;
[self reloadData];
}
写在最后
所谓的"刷新"其实就行想把数据绑定到控件上而已,动态的数据动态的控件才叫真正的刷新
本文不仅仅适用于UIViewController,任何View,封装的控件其实都是适用的