[英]Reload TableView data after click button
我正在進行聊天應用程序並從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.'
'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.'
我該如何解決?
EDIT2
好。 我只有一節。 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;}
但我仍然有同樣的錯誤。
我們看看吧。 我將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
,您需要: UITableView
上調用beginUpdates
UITableView
上調用endUpdates
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];
}
如果您仍然遇到問題,我會查看您在哪里設置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;
}
此標志控制表中是否存在其他行。 因此,您必須在beginUpdates
和endUpdates
之間進行beginUpdates
,例如:
// 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行。 如果它出現在您的控制台中,我希望看到此消息。
這是對您所看到的錯誤的回應:
*由於未捕獲的異常'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
准確地反映了表中應該包含的行,但是當self.tableView.editing
為true時,通過添加+1
,你將numberOfRowsInSection:
推送到你在insertRowsAtIndexPaths:withRowAnimation:
調用中報告的內容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
。 我將section index更改為0,這應該是正確的,除非這個UITableView確實有多個未提及的部分。 確保您的日志有意義。 如果你看到numberOfRowsInSection:
在insertRows:
過程中增加2 insertRows:
那么你最好還是看看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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.