不更新tableviewcell和height中的重用约束

时间:2016-05-27 04:48:44

标签: ios uitableview autolayout

我有像这样的表视图单元格。

enter image description here

下载图像后,我更新图像视图的高度,使宽高比正确(宽度固定)。

[self.imgMain removeConstraint:self.aspectConstraint];
self.aspectConstraint = [NSLayoutConstraint constraintWithItem:self.imgMain
                                                     attribute:NSLayoutAttributeWidth
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self.imgMain
                                                     attribute:NSLayoutAttributeHeight
                                                    multiplier:aspectRatioMult
                                                      constant:0];
self.aspectConstraint.priority = 999;//the reason is that if it is 1000, it violate with my label height constraints and it broke label constraint.So I set to 999
[self.imgMain addConstraint:self.aspectConstraint];
[self setNeedsUpdateConstraints];
[self updateConstraints];

问题在于,虽然我更新了约束,但tableviewcell从未改变,并且它首次在每3个单元格中重复使用单元格。如果我向上和向下滚动,高度会更新。如何成功更新我的约束?

修改

我像这样设置单元格数据。

- (void)setData:(NSDictionary *)dict
{
    if (!dict)
        return;

    self.cellData = [NSDictionary dictionaryWithDictionary:dict];
    [self.imgMain setImageWithURL:[NSURL URLWithString:self.cellData[SERVER_IMG]] placeholderImage:[UIImage new] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL){

        if (image) {
            [self putImage:image];
            return ;
        }
        [self putImage:[UIImage imageNamed:@"placeholder.png"]];


    } usingActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

    NSString *name = [NSString stringWithFormat:@"%@%@",SERVER_NAME, [LocalizationHelper getExtForLocale]];

    if([self.cellData[SERVER_INTEGRATION_ID]intValue]==SERVER_ISHOPCHANGI_ID) {

        [self.lblShopName setText:self.cellData[SERVER_DESCRIPTION]];
        [self.btnMap setHidden:YES];
        self.imgWidthMapBtnConstraint.constant = 0;
    } else {
        [self.lblShopName setText:self.cellData[SERVER_LOCATIONS][0][SERVER_SHOP]];
        [self.btnMap setHidden:[Helper isPointZero:dict[SERVER_LOCATIONS][0]]];
        self.imgWidthMapBtnConstraint.constant = 33;
    }
    [self.lblOfferTitle setText:self.cellData[name]];
}

3 个答案:

答案 0 :(得分:2)

让事情变得清晰的小概述:

在使用Autolayout时,为了计算单元格的高度,iOS仅计算第一次为indexPath加载单元格时的高度并缓存它,并在下次重用它时,单元格再次可见。

解决 - >

使用,

tableView.beginUpdates()
tableView.endUpdates()

OR

tableView.reloadRowsAtIndexPath

参考链接

回答您的问题

你可以在set Data中使用tableView.beginUpdates()/ endUpdates()

以下不会导致不确定的循环

-(void)setData{
  /*YOUR CODE UPDATING THE CONSTRAINTS*/
  tableView.beginUpdates()
  tableView.endUpdates()
}

<强> OR

使用reloadRows CHECK如果CONSTRAINTS已经设置,打破循环,如果是,则不要调用reloadRows *

    -(void)setData{
       CGFloat requiredValue = 0;

if([self.cellData[SERVER_INTEGRATION_ID]intValue]==SERVER_ISHOPCHANGI_ID) {

requiredValue  = 0;

        } else {

       requiredValue  = 33;

      }
          /*CHECK IF CONSTRAINT ALREADY SET*/
         if(self.imgWidthMapBtnConstraint.constant != requiredValue){

          self.imgWidthMapBtnConstraint.constant = requiredValue;
           /**RELOAD ROW*/
        }
        }

答案 1 :(得分:0)

<强>夫特

是的,更改约束将不会执行任何操作,因为调用heightForRowAtIndexPath时已经计算了高度,并且仅在重新加载tableView或重新加载cell时调用此高度。

您可以调用tableView.reloadData(),但如果只在一个单元格中进行更改,则效率不高。

如果您知道更改的单元格的indexPath,则只需调用tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)

答案 2 :(得分:0)

想象UITableViewCell只有一个标签,它的高度是AutomaticDimension, 有时候我想保证金取决于数据

起初,我设置了这样的约束

[_label mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.equalTo(@(0));
    make.right.equalTo(@(0));
    make.top.equalTo(@(self.margin));
    make.height.equalTo(@30)
    make.bottom.equalTo(@(-self.margin));
}];

我想在单元格数据更改时更改边距

- (void)setMargin:(CGFloat)margin {
        _margin = margin;
        [self.label mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(@(self.margin));
            make.bottom.equalTo(@(-self.margin));
        }];
}

滚动UITableview,当我更改此单元格的边距(重复使用)时出现xcode警告

Probably at least one of the constraints in the following list is one you don't want. 
Try this: 
    (1) look at each constraint and try to figure out which you don't expect; 
    (2) find the code that added the unwanted constraint or constraints and fix it. 
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
"<MASLayoutConstraint:0x1c42b9e60 UILabel:0x13fec3bb0.top == UITableViewCellContentView:0x13fe9ef60.top + 10>",
"<MASLayoutConstraint:0x1c42b9d40 UILabel:0x13fec3bb0.height == 30>",
"<MASLayoutConstraint:0x1c42b9e00 UILabel:0x13fec3bb0.bottom == UITableViewCellContentView:0x13fe9ef60.bottom - 10>",
"<NSAutoresizingMaskLayoutConstraint:0x1c0291710 UITableViewCellContentView:0x13fe9ef60.height == 80>"
)

Will attempt to recover by breaking constraint 
<MASLayoutConstraint:0x1c42b9d40 UILabel:0x13fec3bb0.height == 30>
  

为避免将此警告设置为优先级:

[_label mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.equalTo(@(0));
    make.right.equalTo(@(0));
    make.top.equalTo(@(self.margin));
    make.height.equalTo(@30).priority(MASLayoutPriorityDefaultMedium);
    make.bottom.equalTo(@(-self.margin));
}];