I am newbie to objective-c and sqlite.I have inserted data in to table using sqlite successfully.My project contains 2 pages
Add Reminder page:Where user enters data and
I understand what your trying to do now.
I would recommend to create a class to hold the data for each reminder, then you can have an array of the reminder data.
So I would add a new Class to your project, call it Reminder, then add a property for each of your fields.
Your reminder class would be as follows:
Reminder.h
#import <Foundation/Foundation.h>
@interface Reminder : NSObject
@property (nonatomic, copy) NSString *reminderId;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *event;
@property (nonatomic, copy) NSString *date;
@end
and your reminder.m file would be:
#import "Reminder.h"
@implementation Reminder
@synthesize reminderId, name, event, date;
-(void)dealloc
{
self.reminderId = nil;
self.name = nil;
self.event = nil;
self.date = nil;
}
@end
So this class will simply hold the data for each of your reminders.
Then in your view controller which shows the list of the reminders you need to add an array property to hold the reminder objects.
So add the following property to your ViewController which shows the list of reminders.
@property (nonatomic, retain) NSMutableArray *reminders;
make sure you also synthesize this in your view controllers .m file, to do this add this line of code under the @implementation line in your view controller .m file:
@synthesize reminders;
Also remember to set the reminders property to nil in your dealloc method to ensure proper memory cleanup:
self.reminders = nil;
We will be using the Reminder class we created in the view controller so you need to also import your class, so in the view controller .m file add an import statement near the top of the file as follows:
#import "Reminder.h"
Now your view controller is setup and ready to use the reminder class we created.
You then need to add a method into your view controller that will be used to load your data from the database and populate the reminder objects and the reminders array.
Add a new method to your view controller, call it something like loadReminders
The implementation for this method will be:
-(void)loadReminders
{
// setup the reminders array
self.reminders = nil;
self.reminders = [[[NSMutableArray alloc] init] autorelease];
//Retrieve the values of database
const char *dbpath = [self.databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &remindersDB) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat:@"SELECT * FROM reminders"];
NSLog(@"Data = %@",querySQL);
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(self.remindersDB ,query_stmt , -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
Reminder *loadedReminder = [[Reminder alloc] init];
loadedReminder.reminderId = [[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)]autorelease];
loadedReminder.name = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)]autorelease];
loadedReminder.event = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)]autorelease];
loadedReminder.date = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 3)]autorelease];
[self.reminders addObject:loadedReminder];
[loadedReminder release];
}
sqlite3_finalize(statement);
}
sqlite3_close(self.remindersDB);
}
}
So what this method is doing is loading the rows from the database, and for each row in the database it is creating a new Reminder object, setting the properties using the data from the row, then adding this reminder object to the reminders array.
notice the change I have made from your original code:
while (sqlite3_step(statement) == SQLITE_ROW)
the while statement will loop round and fetch each row from the database.
You would call this new method (loadReminders) whenever you want to refresh the list of data, so anywhere in your code where you are currently reloading the table, call this method before you reload the table, this will ensure your array of reminders is setup ready for the table to use when reloading. So in your example above, I would replace your viewWillAppear method to be:
-(void)viewWillAppear:(BOOL)animated
{
[self loadReminders];
[self.theTable reloadData];
}
Now all the data is setup and ready to use. And using the reminder object should make the code in your tableView much easier to read.
So to get your data into the table, replace your current tableview methods with the following.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)view
{
return [self.reminders count];
}
This will tell the table to create a section for each reminder in the reminders array.
Now from your description (and link) what you are doing is creating 1 cell in each section. So add the following method to tell the tableView we want 1 row for each section
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
Right now for the cellForRowAtIndexPath, replace your current method with the following:
- (UITableViewCell *)tableView:(UITableView *)view cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Reminder *reminderToDisplay;
reminderToDisplay = [self.reminders objectAtIndex:indexPath.section];
// Now create the cell to display the reminder data:
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil] autorelease];
view.backgroundColor = [UIColor clearColor];
cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"reminderbutton.png"]];
label1 = [[[UILabel alloc]initWithFrame:CGRectMake(26, 3, 30, 40)]autorelease];
label1.backgroundColor = [UIColor clearColor];
label1.textColor = [UIColor whiteColor];
label2 = [[[UILabel alloc]initWithFrame:CGRectMake(45, 3, 100, 40)]autorelease];
label2.backgroundColor = [UIColor clearColor];
label2.textColor = [UIColor whiteColor];
label3 = [[[UILabel alloc]initWithFrame:CGRectMake(119, 3, 100, 40)]autorelease];
label3.backgroundColor = [UIColor clearColor];
label3.textColor = [UIColor whiteColor];
label4 = [[[UILabel alloc]initWithFrame:CGRectMake(198, 3, 120, 40)]autorelease];
label4.backgroundColor = [UIColor clearColor];
label4.textColor = [UIColor whiteColor];
// Now set the labels using our reminder object
label1.text = reminderToDisplay.reminderId;
label2.text = reminderToDisplay.name;
label3.text = reminderToDisplay.event;
label4.text = reminderToDisplay.date;
// now add the labels to the cell
cell.contentView = [[UIView alloc] init] autorelease]
[cell.contentView addSubview:label1];
[cell.contentView addSubview:label2];
[cell.contentView addSubview:label3];
[cell.contentView addSubview:label4];
return cell;
}
So whats happening in this method, is first we are getting the reminder for the current section out of the reminders array:
Reminder *reminderToDisplay;
reminderToDisplay = [self.reminders objectAtIndex:indexPath.section];
The next few lines should be familiar, we are creating the cell, and the labels. Then we are using the reminder object to set the labels text.
The reason your existing solution was not working was because you was using indexPath.Row, and because you are using a section for each reminder the indexPath.Row will always be 0, as you only ever have 1 row in each section.
I know its a long post, but hopefully should help you understand what is happening. Any questions then let me know
You should really create a Custom UITableViewCell.
But for a quick fix answer you could replace the bottom [cell addSubview] lines with the following
cell.contentView = [[UIView alloc] init] autorelease]
[cell.contentView addSubview:label1];
[cell.contentView addSubview:label2];
[cell.contentView addSubview:label3];
[cell.contentView addSubview:label4];