tableView 使用注意事项:一个tableView展示不同的cell时复用,以及数据更新

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近在工作之中使用到3种不同的cell类 来展示3种不同的 数据形式:</span>

记录总结一下:

先前在 一个类中定义了 3种不同的cell初始化方法,来进行不同的cell类的初始化:

本来是在View上添加三个不同的tableView来展示不同的cell 这样导致内存开销相对较大,不过也有代码可以解决一些内存问题

比如:在切换tableView 的时候将tableView的数据源给置为nil,不过这样做的话就会导致一些低水准的代码出来(本人也是菜,只不过在追求大神的过程中)


代码如下:

-(void)setinifWithJP:(NSDictionary *)dict;

-(void)setinfWithGP:(NSDictionary *)dict;

-(void)setinifConstWithJS:(NSDictionary *)dict;

虽然方法是集中到一起了,调用起来比较方便,但是有点缺点是代码太集中了,导致.m文件中代码很长,阅读起来就相对比较费事,但是能很好地避免冗余的代码。

后来采用 分开的cell类 继承自父类,拥有共同的功能或者属性,但是本人的属性比较复杂,就直接个性化到所在的类中了,没有抽出来。

这样每个cell都有专门的方法初始化,(本来就有)

附代码:

#pragma mark 初始化界面
-(void)otherInitJP{
    if (self.labelNameJP ) {
        return ;
   // 避免重复创建直接使用,不过觉得在cell初始化的时候就应该换
   //把这些子控件创建好,然后直接赋值显示就行了,以后再说吧
    }
    //项目名字
    self.labelNameJP = [[UILabelalloc]initWithFrame:CGRectMake(self.swipeContentView.width*0.35,self.contentView.height*0.8,self.contentView.frame.size.width*0.3,20)];
    //    self.labelName.backgroundColor=[UIColor yellowColor];
    self.labelNameJP.font = [UIFontsystemFontOfSize:16];
    [self.swipeContentViewaddSubview:self.labelNameJP];
    
    //进度条
    self.progressViewJP = [[UAProgressViewalloc]initWithFrame:CGRectMake(self.swipeContentView.frame.size.width*0.1,self.contentView.frame.size.height*0.4,40, 40)];
    [selfprogressV];
    [self.swipeContentViewaddSubview:self.progressViewJP];
    
    
    //项目价格
    self.labelPriceJP = [[UILabelalloc]init];
    self.labelPriceJP.font = [UIFontsystemFontOfSize:16];
    self.labelPriceJP.textColor = [UIColororangeColor];
    //    self.labelTime.backgroundColor=[UIColor redColor];
    self.labelPriceJP.textAlignment =NSTextAlignmentRight;
    self.labelPriceJP.translatesAutoresizingMaskIntoConstraints=NO;
    [self.swipeContentViewaddSubview:self.labelPriceJP];
    
    [self.labelPriceJPmas_makeConstraints:^(MASConstraintMaker *make) {
        make.size.mas_equalTo(CGSizeMake(100,25));
        make.right.mas_equalTo(-10);
        make.top.mas_equalTo(10);
    }];
    
    //项目倒计时
    self.labelTimeJP = [[UILabelalloc]init];
    self.labelTimeJP.font=[UIFontsystemFontOfSize:14];
    self.labelTimeJP.alpha =0.9;
    
    self.labelTimeJP.textColor = [UIColorgrayColor];
    self.labelTimeJP.textAlignment =NSTextAlignmentRight;
    self.labelTimeJP.translatesAutoresizingMaskIntoConstraints=NO;
    [self.swipeContentViewaddSubview:self.labelTimeJP];
    [self.labelTimeJPmas_makeConstraints:^(MASConstraintMaker *make) {
        make.size.mas_equalTo(CGSizeMake(100,25));
        make.right.mas_equalTo(self.labelPriceJP.mas_right);
        make.top.mas_equalTo(self.labelPriceJP.mas_bottom);
    }];
    
}

-(void)setinfoWithJP:(Project *)project
{
    [selfotherInitJP];
    
    BOOL Selected =NO;
    if (project.hasliked !=0){
        Selected = YES;
    }

    [[self.rightButtonsobjectAtIndex:0]setSelected:Selected];
    
    //项目名字
    self.labelNameJP.text = project.name;
    
    //设置百分比
    NSString * str=[NSStringstringWithFormat:@"%@",project.score];
    float floatString=[strfloatValue];
    self.progressViewJP.progress = floatString*0.01;
    
    //项目价格
    NSString * str1=[NSStringstringWithFormat:@"%@元/㎡",project.all_price];
    self.labelPriceJP.text=str1;
    
    NSString * str2=[NSStringstringWithFormat:@"倒计时%@天",project.dtime];
    self.labelTimeJP.text=str2;
    
}
#pragma mark 进度条
-(void)progressV{
    self.pausedJP =YES;
    
    self.progressViewJP.tintColor = [UIColororangeColor];
    self.progressViewJP.borderWidth =1.0;
    self.progressViewJP.lineWidth =4.0;
    self.progressViewJP.fillOnTouch =YES;
    
    UILabel *textLabel = [[UILabelalloc] initWithFrame:CGRectMake(0,0, 40.0,22.0)];
    textLabel.font = [UIFontfontWithName:@"HelveticaNeue-UltraLight"size:18];
    textLabel.textAlignment =NSTextAlignmentCenter;
    textLabel.textColor =self.progressViewJP.tintColor;
    textLabel.backgroundColor = [UIColorclearColor];
    self.progressViewJP.centralView = textLabel;
    
    self.progressViewJP.progressChangedBlock = ^(UAProgressView *progressView, CGFloat progress)
    {
        [(UILabel *)progressView.centralViewsetText:[NSStringstringWithFormat:@"%2.0f%%", progress *100]];
    };
}
@end

之后又对tableView动手脚,狠心把很多代码斩掉,使用 一个tableView展示3种不同的cell:

1. 做好标记
2.切换数据源
3. 刷新数据
4. 网络请求时的注意事项
1. 做好标记
- (void)headerBtnClick:(ProjectButton *)button
{
    NSInteger index = button.tag;
// 切换数据源:模型数组  切换 cellID刷新表示图中在根据cellID 来进行cell的创建循环
    switch (index) {
        case0:
            self.cellIdentifier =cellIDBiddingCell;
            break;
        case1:
            self.cellIdentifier =cellIDListCell;
            break;
        case2:
            self.cellIdentifier =CellIDConstructionViewCell;
            break;
        default:
            break;
    }
}
2.切换数据源 通过重写set方法实现
- (void)setCellIdentifier:(NSString *)cellIdentifier
{
    _cellIdentifier = cellIdentifier;
    if ([cellIdentifierisEqualToString:cellIDBiddingCell]) {
        
        self.projectArr =self.projectArrJP ;

    }elseif ([cellIdentifier isEqualToString:cellIDListCell]){
    
        self.projectArr =self.projectArrGP ;
    }else{
        self.projectArr =self.projectArrJS ;
    }

//3. 刷新数据 每次都要刷新数据
    [self.tableViewreloadData];
}
重点来了


4. 网络请求时的注意事项

本人的 cell 是与用户进行交互的cell,点击其中的按钮进行收藏的切换图标,当时恼火啊,没见过切换cell左滑动,出现带有icon的button,更恼火的是居然button还要切换图标(收藏与取消收藏展示不同的图标),后来找到了一个框架给他扩展了一下,搞定这一功能 。

MGSwipeButton

我真是直接啊,强行扩展

+(instancetype) buttonWithTitle:(NSString *) title backgroundColor:(UIColor *) color;

+(instancetype) buttonWithTitle:(NSString *) title backgroundColor:(UIColor *) color padding:(NSInteger) padding;

+(instancetype) buttonWithTitle:(NSString *) title backgroundColor:(UIColor *) color insets:(UIEdgeInsets) insets;

+(instancetype) buttonWithTitle:(NSString *) title backgroundColor:(UIColor *) color callback:(MGSwipeButtonCallback) callback;

+(instancetype) buttonWithTitle:(NSString *) title backgroundColor:(UIColor *) color padding:(NSInteger) padding callback:(MGSwipeButtonCallback) callback;

+(instancetype) buttonWithTitle:(NSString *) title backgroundColor:(UIColor *) color insets:(UIEdgeInsets) insets callback:(MGSwipeButtonCallback) callback;

+(instancetype) buttonWithTitle:(NSString *) title icon:(UIImage*) icon iconSelected:(UIImage*) iconSelected backgroundColor:(UIColor *) color;

+(instancetype) buttonWithTitle:(NSString *) title icon:(UIImage*) icon iconSelected:(UIImage*) iconSelected backgroundColor:(UIColor *) color padding:(NSInteger) padding;

+(instancetype) buttonWithTitle:(NSString *) title icon:(UIImage*) icon iconSelected:(UIImage*) iconSelected backgroundColor:(UIColor *) color insets:(UIEdgeInsets) insets;

+(instancetype) buttonWithTitle:(NSString *) title icon:(UIImage*) icon iconSelected:(UIImage*) iconSelected backgroundColor:(UIColor *) color callback:(MGSwipeButtonCallback) callback;

+(instancetype) buttonWithTitle:(NSString *) title icon:(UIImage*) icon iconSelected:(UIImage*) iconSelected backgroundColor:(UIColor *) color padding:(NSInteger) padding callback:(MGSwipeButtonCallback) callback;

+(instancetype) buttonWithTitle:(NSString *) title icon:(UIImage*) icon iconSelected:(UIImage*) iconSelected backgroundColor:(UIColor *) color insets:(UIEdgeInsets) insets callback:(MGSwipeButtonCallback) callback;


扩展完了之后就是网络数据与本地对接了,问题来了,就是网络与本地不同步,就是网络请求完了之后,我没有进行网络请求刷新本地的模型数组,bug啊,当时没注意直接改的是本地数据但是肯定会出现问题的,改变cell显示的应该是本定的模型,所以啊只能进行本地的模型数组的更新。

这里之贴出部分代码 :网络请求之后的 处理                       
  if (MGbutton.selected ==NO)
                    {
//#warning  不仅仅要网络请求 而且要更新本地模型数据,而不是只改变当前cell的数据
                        //1.更新网络数据
                        [NetWorkingreturnDataWithDictionary:dict urlStr:@"liked/addinfo"completion:^(id result)
                        {
                            if ([ result[@"info"]isEqualToString:@"关注成功"])
                            {
                                [selfshowMessage:@"您已收藏"];
                        //2.更新本地数据
                                project.hasliked =YES;
//                                MGbutton.selected = YES;

                                [selfreplaceObjectInProjectArrAtIndex:indexwithObject:project];

                             }else{
                                [selfshowMessage:@"未知错误"];
                             }

                        }];
                    }

//更新本地的 模型数组

- (void)replaceObjectInProjectArrAtIndex:(NSUInteger)index withObject:(id)object
{
    if ([_cellIdentifierisEqualToString:cellIDBiddingCell])
    {
        [self.projectArrJPreplaceObjectAtIndex:index withObject:object];
        
//        self.projectArr = self.projectArrJP ;
        
    }elseif ([_cellIdentifierisEqualToString:cellIDListCell])
    {
        [self.projectArrGPreplaceObjectAtIndex:index withObject:object];
        
//        self.projectArr = self.projectArrGP ;
    }else{
        [self.projectArrJSreplaceObjectAtIndex:index withObject:object];
        
//        self.projectArr = self.projectArrJS ;
    }
    [self.tableViewreloadData];
}


OK ,重点还是网络请求之后网络数据与本地的模型的同步!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Qt C++中,你可以使用QSqlRelationalTableModel和QSqlTableModel来在同一个tableView中显示不同数据表。 QSqlTableModel用于显示单个数据表的数据。你可以使用setTable()方法设置要显示的数据表,然后使用select()方法从数据库中检索数据。例如: ```cpp QSqlTableModel *model = new QSqlTableModel(this); model->setTable("my_table"); model->select(); ui->tableView->setModel(model); ``` 要在同一个tableView中显示多个数据表,你可以使用QSqlRelationalTableModel。QSqlRelationalTableModel可以显示多个相关联的数据表的数据。你可以使用setTable()方法设置要显示的主数据表,然后使用setRelation()方法将其他数据表与主数据表相关联。例如: ```cpp QSqlRelationalTableModel *model = new QSqlRelationalTableModel(this); model->setTable("orders"); model->setRelation(1, QSqlRelation("customers", "id", "name")); model->setRelation(2, QSqlRelation("products", "id", "name")); model->select(); ui->tableView->setModel(model); ``` 在此示例中,orders表是主数据表,而customers和products表是相关联的数据表。setRelation()方法将customers表与orders表的customer_id列相关联,将products表与orders表的product_id列相关联。这样,tableView将显示orders表中的数据,并且将customer_id和product_id列中的值替换为相关联的表中的数据。 请注意,使用QSqlRelationalTableModel,你需要在数据库中设置外键约束来确保正确的关联。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值