table 单元格中的动画约束更改
Animate constraint change in table cell
我的 table 单元格中有一个滑块,当用户滑动它时,我将重新加载该特定单元格以在我的单元格中显示更新后的滑块值。
当用户将滑块移动到最大值时,我想用一些动画更改单元格中元素的宽度约束。
一切正常,但我看不到动画。
-(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
,并在 self.tableView
上调用 layoutIfNeeded
而不是 cell
。但没有任何效果。我究竟做错了什么 ?
如何使用 [UIView animateWithDuration:animations:completion:],并在你的 "sliderValueChanged" 方法中接受一个完成块作为参数,然后你可以在块中重新加载 tableView,你可以删除对表格视图。
您的示例中的问题是您在与动画块相同的循环中调用 reloadRowsAtIndexPaths
。通常,您需要做的就是删除该调用,动画应该可以正常工作。
从评论看来,如果不调用它,甚至单元格中的文本也不会更改,这会导致您在从滑块操作方法请求单元格时可能无法获得正确的单元格。
我建议您始终使用 table 视图单元格子类中单元格的所有出口。通过这种方式,您始终可以确保无需调用 getIndexPathForView
、cellForRowAtIndexPath
即可访问正确的子视图,并且在某些情况下,然后从数据源数组中获取 object 以及该索引路径,例如 myObject = self.array[indexPath.row]
。这样做唯一的缺点是将通知从单元格返回给 table 视图所有者(通常是视图控制器)。对于这种情况,您通常使用自定义委托,其中单元格对委托(视图控制器)有弱引用,并在需要的任何操作上调用委托。举一个这样的例子 table 视图单元格:
Header:
@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];
如果您需要在单元格滑块发生变化时在视图控制器内进行通知,您只需实现委托方法即可。
我的 table 单元格中有一个滑块,当用户滑动它时,我将重新加载该特定单元格以在我的单元格中显示更新后的滑块值。
当用户将滑块移动到最大值时,我想用一些动画更改单元格中元素的宽度约束。
一切正常,但我看不到动画。
-(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
,并在 self.tableView
上调用 layoutIfNeeded
而不是 cell
。但没有任何效果。我究竟做错了什么 ?
如何使用 [UIView animateWithDuration:animations:completion:],并在你的 "sliderValueChanged" 方法中接受一个完成块作为参数,然后你可以在块中重新加载 tableView,你可以删除对表格视图。
您的示例中的问题是您在与动画块相同的循环中调用 reloadRowsAtIndexPaths
。通常,您需要做的就是删除该调用,动画应该可以正常工作。
从评论看来,如果不调用它,甚至单元格中的文本也不会更改,这会导致您在从滑块操作方法请求单元格时可能无法获得正确的单元格。
我建议您始终使用 table 视图单元格子类中单元格的所有出口。通过这种方式,您始终可以确保无需调用 getIndexPathForView
、cellForRowAtIndexPath
即可访问正确的子视图,并且在某些情况下,然后从数据源数组中获取 object 以及该索引路径,例如 myObject = self.array[indexPath.row]
。这样做唯一的缺点是将通知从单元格返回给 table 视图所有者(通常是视图控制器)。对于这种情况,您通常使用自定义委托,其中单元格对委托(视图控制器)有弱引用,并在需要的任何操作上调用委托。举一个这样的例子 table 视图单元格:
Header:
@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];
如果您需要在单元格滑块发生变化时在视图控制器内进行通知,您只需实现委托方法即可。