UITableView在插入时复制行 MyStackViewScrollableViewController.mMyTableViewController.m

问题描述

我有一个表视图控制器,它通过使用带有嵌入转场的 UIContainerView 显示在垂直堆栈视图中。所有这些工作正常。问题是,如果我尝试插入一行,我希望它为新行设置动画并更新堆栈视图中容器视图的高度,但问题是当它这样做时,它似乎重复了底行。

这是一个动画,展示了正在发生的事情。在动画中的“项目 1”和“项目 2”之间插入了一个新项目。该动画效果很好,但是如果您查看表格底部,“项目 3”似乎被简单地重复了。这就是我正在尝试的修复。

animated image showing the table animation behavior

这是显示视图结构的文档大纲。基本上有一个滚动视图,里面有一个堆栈视图。堆栈视图然后管理不同的视图,例如表视图。现在,大多数视图只是彩色的 UIViews,但最终我希望它们都是加载外部视图控制器的 UIViewContainers,类似于现在使用表视图控制器所做的。目标是让我可以在他们自己的视图控制器中实现每个部分,并将它们“插入”到堆栈视图或表视图或其他任何东西中。

document outline

但我真正需要支持的一件事是让子视图控制器能够垂直调整大小,并且在父视图控制器或 UIContainerView 中将调整大小设置为动画。这就是我遇到的问题,我无法弄清楚为什么会暂时复制这一行。

这是视图控制器的类,其中包含滚动视图和堆栈视图。然后,堆栈视图包含 UIContainerView,它具有到表视图控制器(在代码中称为 MyTableViewController)的嵌入 segue。

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

有谁知道我可能做错了什么或如何在动画期间修复重复的底行?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...