gpt4 book ai didi

objective-c - 单击按钮后重新加载TableView数据

转载 作者:可可西里 更新时间:2023-11-01 17:10:36 25 4
gpt4 key购买 nike

我正在聊天应用程序,并从SQLite数据库读取消息数据。单击“发送”按钮后,我想用新消息重新加载TableView数据。
我的按钮事件:

    [_sendButton addTarget:self action:@selector(saveMessage:) forControlEvents:UIControlEventTouchUpInside];

我想我需要使用 -(void)viewDidAppear:(BOOL)animated,但是它没有用(或者我做错了)。
[_tableView reloadData];

-(void)viewDidAppear:(BOOL)animated {

sqlite3 *database;

databaseName = @"Messenges.db";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];

messenges = [[NSMutableArray alloc] init];

if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = "select * from messenges";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
NSString *dbMessageText = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];

Message *messege = [[Message alloc] initWithName:dbMessageText];

[messenges addObject:messege];

[messege release];
}
}
sqlite3_finalize(compiledStatement);

}
sqlite3_close(database);}

编辑
这是我向TableView添加新行的方法。单击“发送”按钮后,必须立即添加新行。
-(IBAction)insertRows:(id)sender {
MDAppDelegate *appDelegate = (MDAppDelegate *)[[UIApplication sharedApplication] delegate];
[messenges insertObject:[[NSString alloc] initWithFormat:@"%@", _textField.text] atIndex:appDelegate.messenges.count+1];
NSArray *insertIndexPaths = [NSArray arrayWithObject: [NSIndexPath indexPathForRow:1 inSection:1]];
UITableView *tV = (UITableView *)self.tableView;

[tV beginUpdates];
[tV insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationRight];
[tV endUpdates];}

但是这段代码给我错误: 'Invalid table view update. The application has requested an update to the table view that is inconsistent with the state provided by the data source.'我该如何解决?

编辑2

好。我只有一节。 numberOfSectionsInTableView:不需要更正。
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
MDAppDelegate *appDelegate = (MDAppDelegate *)[[UIApplication sharedApplication] delegate];
NSUInteger numberOfRowsInSection = appDelegate.messenges.count; //add new variable to what rows will be +1
if (self.editing) {
numberOfRowsInSection++;
}
return numberOfRowsInSection;}

但是我仍然有同样的错误。

编辑#3

我们看看吧。我将 insertRows更改为:
-(IBAction)insertRows:(id)sender {
MDAppDelegate *appDelegate = (MDAppDelegate *)[[UIApplication sharedApplication] delegate];
[self.tableView beginUpdates];
self.tableView.editing = YES;
[messenges insertObject:[[NSString alloc] initWithFormat:@"%@", _textField.text] atIndex:appDelegate.messenges.count+1];

NSArray *insertIndexPaths = [NSArray arrayWithObject: [NSIndexPath indexPathForRow:appDelegate.messenges.count+1 inSection:1]];
[self.tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationRight];
[self.tableView endUpdates];
}

numberOfRowsInSection:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
MDAppDelegate *appDelegate = (MDAppDelegate *)[[UIApplication sharedApplication] delegate];
NSUInteger numberOfRowsInSection = appDelegate.messenges.count;
if (self.tableView.editing) {
numberOfRowsInSection++;
}
NSLog(@"%i",numberOfRowsInSection);
return numberOfRowsInSection;
}

但是我收到了一个错误 *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 4 beyond bounds [0 .. 3]'。然后我将 if (self.tableView.editing)更正为:
if (self.tableView.editing) {
MDAppDelegate *someNewDelegate = (MDAppDelegate *)[[UIApplication sharedApplication] delegate];
numberOfRowsInSection = someNewDelegate.messenges.count+1; //or .count
}

但是关于“NSRangeException”也有同样的错误。

最佳答案

要使用动画更新 UITableView ,您需要:

  • 在您的 beginUpdates 上调用 UITableView
  • 更新数据模型
  • 插入/删除行和节
  • 在您的 endUpdates 上调用 UITableView

  • 注意事项:
  • 如果要删除某个节,则也不应从该节中删除行(不必要,甚至可能导致错误)
  • 如果要插入一个节,则也不应在该节中插入行(如果该单元格可见, UITableView 将调用 numberOfRowsInSection: ,然后再调用 cellForRowAtIndexPath: )。

  • 您是什么意思,更新我的数据模型?

    如果要通过添加和删除行和节来操作 UITableView ,则应该有某种方式可以随时跟踪 UITableView 中当前有哪些节/行。

    例如,您应该有一个类似于以下内容的 numberOfRowsInSection: 方法:
    - (NSInteger)numberOfRowsInSection:(NSInteger)section
    {
    // You should have a way to get section data with an index (section)
    // The below example assumes an NSArray named self.mySectionCollection
    // exists for this purpose
    NSArray *sectionList = self.mySectionCollection;
    // You should have data associated with a section. Below its assumed
    // this data is wrapped in an NSDictionary. Data that might be in here
    // could include a height, a name, number of rows, etc...
    NSDictionary *sectionData = [sectionList objectAtIndex:section];

    NSInteger rowCount = 0;
    // SectionData should NEVER be nil at this point. You could raise an
    // exception here, have a debug assert, or just return 0.
    if (sectionData)
    {
    rowCount = [[sectionData objectForKey:@"rowCount"] intValue];
    }
    return rowCount;
    }

    您可以通过几种不同的方式(包括使用CoreData)存储有关节/行的信息。关键是,通过在 beginUpdates endUpdates 之间修改此集合,您可以告诉 UITableView 如何更新自身(它将根据需要查询 numberOfRowsInSection: numberOfSections cellForRowAtIndexPath: )。

    编辑

    我相信,如果您同时修改 insertRows:方法以修改数据源( messenges),则通知 UITableView已发生更新,一切将开始为您正常工作。

    尝试使用以下代码:
    -(IBAction)insertRows:(id)sender 
    {
    MDAppDelegate *appDelegate = (MDAppDelegate *)[[UIApplication sharedApplication] delegate];
    UITableView *tV = (UITableView *)self.tableView;

    [tV beginUpdates];

    // UPDATE DATA MODEL IN BETWEEN beginUpdates and endUpdates
    int rowIndex = appDelegate.messenges.count + 1;
    [messenges insertObject:[[NSString alloc] initWithFormat:@"%@", _textField.text]
    atIndex:rowIndex];

    // Notify UITableView that updates have occurred
    NSArray *insertIndexPaths = [NSArray arrayWithObject:
    [NSIndexPath indexPathForRow:rowIndex inSection:1]];
    [tV insertRowsAtIndexPaths:insertIndexPaths
    withRowAnimation:UITableViewRowAnimationRight];

    [tV endUpdates];
    }

    编辑#2

    如果您仍然遇到问题,请查看设置 self.editing标志的位置。
    - (NSInteger)tableView:(UITableView *)tableView 
    numberOfRowsInSection:(NSInteger)section
    {
    MDAppDelegate *appDelegate = (MDAppDelegate *)[[UIApplication sharedApplication] delegate];
    //add new variable to what rows will be +1
    NSUInteger numberOfRowsInSection = appDelegate.messenges.count;
    if (self.editing)
    {
    numberOfRowsInSection++;
    }
    return numberOfRowsInSection;
    }

    该标志控制表中是否存在其他行。因此,您必须像下面这样在 beginUpdatesendUpdates之间进行设置:
    // assuming the editing flag is set from some IBAction
    -addNewRow:(id)sender
    {
    int row = ???; // not sure where you want this new row

    [self.tableView beginUpdates]
    self.editing = YES;
    NSArray *insertIndexPaths = [NSArray arrayWithObject:
    [NSIndexPath indexPathForRow:row inSection:1]];
    [self.tableView insertRowsAtIndexPaths:insertIndexPaths
    withRowAnimation:UITableViewRowAnimationRight];
    [self.tableView endUpdates];
    }

    如果删除要添加的行,如果用户停止编辑,请记住类似地调用 deleteRowsAtIndexPaths:withRowAnimation:。我认为,如果编辑成为永久性,则无需采取任何措施,但是您需要设置 self.editing = NO,同时还要在 self.messenges的适当位置添加新行。

    也是,在 insertRows:方法中,您告诉 UITableView您正在索引1处插入一行,而实际上您总是在 messenges集合的末尾插入。我已经修改了 insertRows方法的版本,使其具有 rowIndex变量,目的是确保在更新数据模型并通知 UITableView更改时使用相同的索引。

    最后,当您遇到问题时,请包含尽可能多的调试信息。通常,当您以尝试的方式更新 UITableView时出现问题时,它会告诉您存在不一致错误。自从我看到它已经有一段时间了,但是有一点影响,就是在更新表之前有5行,而在有7行之后只添加1行。我希望看到此消息,如果它显示在您的控制台中。

    编辑#3

    这是对您看到的错误的响应:

    *由于未捕获的异常“NSRangeException”而终止应用程序,原因:“* -[__ NSArrayM objectAtIndex:]:索引4超出范围[0 ..
    3]

    您的错误与插入UITableView没有关系。这与以下事实有关:您试图插入数组的边界之外。我的猜测是令人反感的行是:
    [messenges insertObject:[[NSString alloc] initWithFormat:@"%@", 
    _textField.text]
    atIndex:appDelegate.messenges.count+1];

    要在数组的末尾插入,请使用 appDelegate.messenges.count的索引(已删除 +1)。

    另外...您绝对确定您的数据模型和更新UITableView的调用是否同意?尝试在调用 NSLog(@"rowsBeforeUpdate: %i", [self numberOfRowsInSection:0]);之后和调用 beginUpdates之前调用 endUpdates。另外,在通知UITableView插入操作时,请调用 NSLog(@"inserting index paths: %@", insertIndexPaths)。我的猜测是 self.messenges准确地反映了应该在表中的行,但是当 +1为true时,通过添加 self.tableView.editing,可以将 numberOfRowsInSection:推到对 insertRowsAtIndexPaths:withRowAnimation:的调用中所报告的内容之上。

    试试这个:
    -(IBAction)insertRows:(id)sender {
    MDAppDelegate *appDelegate = (MDAppDelegate *)[[UIApplication sharedApplication] delegate];
    [self.tableView beginUpdates];
    NSLog(@"rows before update: %i", [self numberOfRowsInSection:0]);

    self.tableView.editing = YES;
    NSLog(@"rows with editing flag set: %i", [self numberOfRowsInSection:0]);

    int rowIndex = appDelegate.messenges.count; // don't need +1 at end
    int sectionIndex = 0; // should it be 0 or 1? I would guess 0
    [messenges insertObject:[[NSString alloc] initWithFormat:@"%@", _textField.text]
    atIndex:rowIndex];

    NSArray *insertIndexPaths = [NSArray arrayWithObject:
    [NSIndexPath indexPathForRow:rowIndex
    inSection:sectionIndex]];
    [self.tableView insertRowsAtIndexPaths:insertIndexPaths
    withRowAnimation:UITableViewRowAnimationRight];
    NSLog(@"inserting index paths: %@", insertIndexPaths);

    [self.tableView endUpdates];
    }

    我更改了上面的行索引,以排除其中的 +1。我将节索引更改为0,这应该是正确的,除非此UITableView实际上有多个未提及的节。确保您的日志有意义。如果您在 numberOfRowsInSection:的过程中看到 insertRows:增加了2,那么最好也看到 insertRowsAtIndexPaths: 反映了。我很困惑,为什么需要编辑标记才能在 numberOfRowsInSection:方法中添加另一行。这部分(如果设置了 self.editing,则在其中添加另一行)似乎工作不正常。也许只是尝试省略此部分以使其某些功能正常工作,然后在某些功能正常运行时将其重新添加。在某些事情开始起作用之前,也许将 numberOfRowsInSection:更改为以下内容:
    - (NSInteger)tableView:(UITableView *)tableView 
    numberOfRowsInSection:(NSInteger)section
    {
    MDAppDelegate *appDelegate = (MDAppDelegate *)[[UIApplication sharedApplication] delegate];
    NSUInteger numberOfRowsInSection = appDelegate.messenges.count;
    NSLog(@"numberOfRowsInSection %i: %u", section, numberOfRowsInSection);
    return numberOfRowsInSection;
    }

    关于objective-c - 单击按钮后重新加载TableView数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9826345/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com