Rom*_*use 3 sqlite objective-c tableview ios
我正在进行聊天应用程序并从SQLite数据库中读取消息数据.我想在点击"发送"按钮后用新消息重新加载我的TableView数据.我按钮的事件:
[_sendButton addTarget:self action:@selector(saveMessage:) forControlEvents:UIControlEventTouchUpInside];
Run Code Online (Sandbox Code Playgroud)
我想我需要使用,-(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);}
Run Code Online (Sandbox Code Playgroud)
编辑 这是我向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];}
Run Code Online (Sandbox Code Playgroud)
但是这段代码给了我错误:'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;}
Run Code Online (Sandbox Code Playgroud)
但我仍然有同样的错误.
我们看看吧.我改变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];
}
Run Code Online (Sandbox Code Playgroud)
而且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;
}
Run Code Online (Sandbox Code Playgroud)
但是我收到了一个错误*** 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
}
Run Code Online (Sandbox Code Playgroud)
但是有关'NSRangeException'的错误.
UITableView
动画,您需要:beginUpdates
你的UITableView
endUpdates
你的UITableView
UITableView
调用numberOfRowsInSection:
后跟cellForRowAtIndexPath:
).如果您UITableView
通过添加和删除行和部分来操作a ,那么您应该有一些方法来跟踪当前在哪个部分/行中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;
}
Run Code Online (Sandbox Code Playgroud)
您可以使用几种不同的方式存储有关节/行的信息,包括使用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];
}
Run Code Online (Sandbox Code Playgroud)
如果你还有问题,我会看看你在哪里设置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;
}
Run Code Online (Sandbox Code Playgroud)
此标志控制表中是否存在其他行.出于这个原因,你必须将其与beginUpdates
和endUpdates
这样的:
// 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];
}
Run Code Online (Sandbox Code Playgroud)
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];
Run Code Online (Sandbox Code Playgroud)
要插入数组的末尾,请使用索引appDelegate.messenges.count
(删除+1
).
另外......您是否完全确定您的数据模型和更新UITableView的调用是否一致?NSLog(@"rowsBeforeUpdate: %i", [self numberOfRowsInSection:0]);
在呼叫之后beginUpdates
和呼叫之前尝试调用endUpdates
.此外,NSLog(@"inserting index paths: %@", insertIndexPaths)
在通知UITableView插入操作时调用.我的猜测是self.messenges
准确地反映了表中应该包含的行,但是通过添加+1
when self.tableView.editing
为true,您可以将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];
}
Run Code Online (Sandbox Code Playgroud)
我更改了上面的行索引以排除其中+1
的内容.我将section index更改为0,这应该是正确的,除非这个UITableView确实有多个未提及的部分.确保您的日志有意义.如果你看到numberOfRowsInSection:
在这个过程中增加了两个,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;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3780 次 |
最近记录: |