iOS UITableViewCell 局部更新

       iOS新手,最近做一个物流相关的项目,tableView展示,cell中有一个“距离”标签需要计算后展示(百度地图SDK计算后代理回调结果),数据没有办法第一时间获得。

iOS UITableViewCell 局部更新_第1张图片
image.png

       目前想到有两个方法解决以上问题:
1.得到model数组 -> 获取当前位置 -> 调用百度地图路算方法 -> 每个model得到结果 -> talbeView reloadData

2.得到model数组┬> tableView reloadData └> 获取当前位置 -> 调用地图路算方法 -> 每个model得到结果 -> 跟新cell对应label
       明显,方法1的耗时会比方法2长,影响用户体验。方法2的思路关键在于,得到回调结果后发送通知,让cell更改label,上代码

Request.m

- (void)addDistanceWithModelData:(id)data myLocation:(CLLocationCoordinate2D)coordinate {
    //创建队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
//data 有两种 根据类型 转换,可以不用理解
        NSArray *array = [data isKindOfClass:[TJMOrderData class]] ? ((TJMOrderData *)data).content : ((TJMMyOrderData *)data).data;
//遍历得到的数组(中有model),逐个请求获得路程
        [array enumerateObjectsUsingBlock:^(TJMOrderModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            CLLocationCoordinate2D endCoordinate = CLLocationCoordinate2DMake(obj.consignerLat.doubleValue, obj.consignerLng.doubleValue);
//骑行距离计算,直接从百度地图copy来的
            [[TJMLocationService sharedLocationService] calculateRidingDistanceWithDelegate:obj startPoint:coordinate endPoint:endCoordinate];
        }];
    });
}
Model.m

//代理方法回调  
#pragma mark 返回驾乘搜索结果
- (void)onGetRidingRouteResult:(BMKRouteSearch *)searcher result:(BMKRidingRouteResult *)result errorCode:(BMKSearchErrorCode)error {
    if (error == BMK_SEARCH_NO_ERROR) {
        BMKRidingRouteLine *plan = (BMKRidingRouteLine *)[result.routes firstObject];
        // 计算路线方案中的路段数目
        self.getDistance = @(plan.distance / 1000.0);
//发送通知,通知的名字就是model的内存地址(唯一性);
        NSString *notiKey = [NSString stringWithFormat:@"%p",self];
        [[NSNotificationCenter defaultCenter] postNotificationName:notiKey object:nil userInfo:@{@"model":self}];
    }
}
Cell.m

- (void)setViewWithModel:(TJMOrderModel *)model {
    if (!model) return;
    self.currentModel
    //根据model状态 设置 按钮 title
    /*
    //...省略设置其他view的代码
    */
    //我到取货点位置
    //先置为零
    self.myToGetDistanceLabel.text = @"约0.0KM";
    if (model.getDistance) {
        //如果有就更新label
        self.myToGetDistanceLabel.text = [NSString stringWithFormat:@"约%.2fKM",[model.getDistance doubleValue]];
    } else {
        //如果没有,就添加通知
        NSString *notiKey = [NSString stringWithFormat:@"%p",_currentModel];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(modelDistanceDidGet:) name:notiKey object:nil];
    }
    //种类 尺寸
    self.typeNameLabel.text = model.item.itemName;
    self.remarkLabel.text = [NSString stringWithFormat:@"%@kg",model.objectWeight];
}

#pragma  mark - 通知
- (void)modelDistanceDidGet:(NSNotification *)notification {
    TJMOrderModel *model = notification.userInfo[@"model"];
    if ([model isEqual:self.currentModel]) {
        self.myToGetDistanceLabel.text =  [NSString stringWithFormat:@"约%.2fKM",[model.getDistance doubleValue]];
//移除通知
        NSString *notiKey = [NSString stringWithFormat:@"%p",model];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:notiKey object:nil];
    }
}

       距离结果的回调在主线程中,cell中的代码 对 model.getDistance 判断, 如果不为空,则直接赋值,不添加通知,如果为空,则说明回调还没调用,添加通知,等待回调后,发送通知,接收通知后更改结果,并删除通知!所以并不会造成多余的通知!(但是在本文编写过程中想到,这样其实是违反MVC原则的,MVC框架 View 和 Model 不能直接通讯,感觉目前项目到更好的改进办法,希望大神指点)
       第一次写文章,虽然可能并不实用,但也算是提供了一种思路吧。

你可能感兴趣的:(iOS UITableViewCell 局部更新)