ios - UITableView在插入时重复行
问题描述
我有一个表格视图控制器,它通过使用带有嵌入 segue 的 UIContainerView 显示在垂直堆栈视图中。这一切都很好。问题是,如果我尝试插入一行,我希望它为新行设置动画并更新堆栈视图中容器视图的高度,但问题是当它这样做时,它似乎重复了底行。
这是一个动画,显示正在发生的事情。在动画中的“项目 1”和项目 2 之间插入了一个新项目。该动画效果很好,但是如果您查看表格的底部,“项目 3”似乎被简单地复制了。这就是我正在尝试的修理。
这是显示视图结构的文档大纲。基本上有一个滚动视图,里面有一个堆栈视图。然后堆栈视图管理不同的视图,例如表格视图。现在,大多数视图只是彩色的 UIViews,但最终我希望它们都是加载外部视图控制器的 UIViewContainers,类似于现在对表视图控制器所做的事情。目标是让我可以在他们自己的视图控制器中实现每个部分,并将它们“插入”到堆栈视图或表格视图或其他任何东西中。
但我真正需要能够支持的一件事是让子视图控制器能够垂直调整大小,并在父视图控制器或 UIContainerView 中重新调整大小。这就是我遇到的问题,我无法弄清楚为什么会暂时复制这一行。
这是包含滚动视图和堆栈视图的视图控制器类。然后,堆栈视图包含 UIContainerView,该 UIContainerView 具有到表视图控制器的嵌入 segue(在代码中称为 MyTableViewController)。
MyStackViewScrollableViewController.m
#import "MyStackViewScrollableViewController.h"
#import "MyTableViewController.h"
@interface MyStackViewScrollableViewController ()
@property (weak, nonatomic) MyTableViewController *myTableViewController;
@end
@implementation MyStackViewScrollableViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)addARow:(id)sender {
[self.myTableViewController insertRow];
}
- (void)preferredContentSizeDidChangeForChildContentContainer:(id<UIContentContainer>)container {
[super preferredContentSizeDidChangeForChildContentContainer:container];
if ([container isKindOfClass:[MyTableViewController class]]) {
MyTableViewController *viewController = (MyTableViewController *)container;
[UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionCurveEaseOut animations:^{
self.myTableViewControllerSectionHeightConstraint.constant = viewController.preferredContentSize.height;
[self.view layoutIfNeeded];
} completion:nil];
}
}
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"myTableViewControllerEmbedSegue"]) {
self.myTableViewController = segue.destinationViewController;
}
}
@end
这是表视图控制器类。这是由父视图(前一个类)通过来自 UIContainerView 的故事板嵌入 segue 加载的(我只是将容器视图拖到堆栈视图中,然后控制拖动到表视图控制器并为 segue 选择嵌入)。
MyTableViewController.m
#import "MyTableViewController.h"
@interface MyTableViewController ()
@property (strong, nonatomic) NSMutableArray<NSString *> *items;
@end
@implementation MyTableViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
CGRect frame = self.tableView.frame;
frame.size.height = [self.tableView sizeThatFits:CGSizeMake(frame.size.width, CGFLOAT_MAX)].height;
self.preferredContentSize = frame.size;
}
- (void)insertRow {
NSUInteger rowIndex = self.items.count == 0 ? 0 : 1;
[self.items insertObject:[NSString stringWithFormat:@"New item %lu", self.items.count + 1] atIndex:rowIndex];
[UIView beginAnimations:@"twisterTableAnimationId" context:nil];
[UIView setAnimationDuration:1.0f];
[CATransaction begin];
[CATransaction setCompletionBlock:^{
NSLog(@"animation complete");
}];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:rowIndex inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
[CATransaction commit];
[UIView commitAnimations];
CGRect frame = self.tableView.frame;
frame.size.height = [self.tableView sizeThatFits:CGSizeMake(frame.size.width, CGFLOAT_MAX)].height;
self.preferredContentSize = frame.size;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.items = [NSMutableArray arrayWithArray:@[@"Item 1", @"Item 2", @"Item 3"]];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.items.count;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
CGSize preferredContentSize = self.preferredContentSize;
self.preferredContentSize = CGSizeMake(preferredContentSize.width, preferredContentSize.height + 50);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"StringCell" forIndexPath:indexPath];
cell.textLabel.text = self.items[indexPath.row];
return cell;
}
@end
有谁知道我可能做错了什么或如何在动画期间修复重复的底行?
解决方案
推荐阅读
- r - 在过滤器中使用 tidyeval 引用另一列
- java - 输入不保存在文本文件中
- algorithm - Brent-Pollard 分解:Brent 的循环查找算法中正确的龟兔指数是什么?
- c# - 如何从外部 API 读取 jwt 令牌以验证用户并将用户名和电子邮件 ID 插入数据库
- emacs - yasnippets 不起作用:yas--table-get-create: Symbol 的函数定义为 void:record
- delphi - 如何使用 TShellExecuteInfo 发送命令行开关和参数字符串
- kotlin - 如何获取在片段的自定义对话框中输入的信息?
- javascript - 无法使用带有 socket.io 的媒体源从媒体记录器跳转到流
- python - 制作有效的递归幂函数
- r - 遍历一列并找到总和