表格单元格中的动画约束更改

时间:2017-01-18 15:23:48

标签: ios objective-c uitableview uiviewanimation nslayoutconstraint

我的表格单元格中有一个滑块,当用户滑动它时,我正在重新加载该特定单元格以在我的单元格中显示更新的滑块值。

当用户将滑块移动到最大值时,我想用一些动画更改单元格中元素的宽度约束。

一切正常,但我看不到动画。

a[0]

我也尝试过a[i][j] = some number;,并在-(void)sliderValueChanged:(id)sender{ sliderValueChanged = YES; UISlider *slider = (UISlider *)sender; int sliderValue; sliderValue = roundf(slider.value); [slider setValue:sliderValue animated:YES]; NSIndexPath *indexPath = [self getIndexPathForView:slider]; MySliderCell *sliderCell = (MySliderCell *)[self tableView:self.tableView cellForRowAtIndexPath:indexPath]; sliderCell.sliderValueLabel.text = [NSString stringWithFormat:@"%d",sliderValue]; if(sliderValue == 7){ [sliderCell layoutIfNeeded]; sliderCell.radioButonWidth.constant = 40; [UIView animateWithDuration:2.0 animations:^{ [sliderCell layoutIfNeeded]; }]; }else{ [sliderCell layoutIfNeeded]; sliderCell.radioButonWidth.constant = 0; [UIView animateWithDuration:2.0 animations:^{ [sliderCell layoutIfNeeded]; }]; } [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; DLog(@"slider value :%d change method called, indexpath is %@",sliderValue,indexPath); } 而不是setNeedsUpdateConstraints上调用layoutIfNeeded。但没有任何效果。我究竟做错了什么 ?

2 个答案:

答案 0 :(得分:1)

您的示例中的问题是您在与动画块相同的循环中调用reloadRowsAtIndexPaths。通常,您需要做的就是删除该调用,动画应该可以正常工作。

从评论中可以看出,如果没有调用它,即使文本在单元格中被更改也会导致问题,即从滑块操作方法请求时,您可能无法获得正确的单元格。

我建议你始终在表格单元格的子类中使用单元格的所有出口。通过这种方式,您始终可以确保无需调用getIndexPathForViewcellForRowAtIndexPath即可访问正确的子视图,在某些情况下,您可以使用myObject = self.array[indexPath.row]之类的索引路径从数据源数组中获取对象。通过这样做,唯一的缺点是从单元格返回到表视图所有者(通常是视图控制器)的通知。对于这种情况,您通常使用自定义委托,其中单元格将具有对委托(视图控制器)的弱引用,并在所需的任何操作上调用委托。举一个这样的表视图单元格的例子:

标题

@class MyTableViewCell;

@protocol MyTableViewCellDelegate <NSObject>

- (void)myTableViewCell:(MyTableViewCell *)sender changedSliderValue:(CGFloat)newValue;

@end

@interface MyTableViewCell : UITableViewCell

@property (nonatomic, weak) id<MyTableViewCellDelegate> delegate;
@property (nonatomic, strong) MyCustomObject *myObject; // The object this cell is designed to represent


@end

<强>来源:

@interface MyTableViewCell ()

@property (nonatomic, weak) IBOutlet UISlider *slider;

@end

@implementation MyTableViewCell

- (void)setMyObject:(MyCustomObject *)myObject {
    _myObject = myObject;

    // Set any UI properties needed
    self.slider.value = myObject.magnitude;
}

- (void)sliderValueChanged:(UISlider *)sender {

    self.myObject.magnitude = sender.value;
    [self.delegate myTableViewCell:self changedSliderValue:sender.value];

    // Your animation code goes here as well

}

@end

因此,当您将单元格出列时,您将执行以下操作:

MyTableViewCell *cell = ...
cell.delegate = self;
cell.myObject = self.myArray[indexPath.row];

如果在单元格滑块发生变化时需要在视图控制器中进行通知,则只需实现委托方法。

答案 1 :(得分:0)

如何使用[UIView animateWithDuration:animations:completion:],并在“sliderValueChanged”方法中接受一个完成块作为参数,然后你可以在块中重新加载tableView,你可以删除tableView的引用。