检索在sqlite数据库中插入的所有行,并在包含标签的表视图单元格中显示为带有不同部分的子视图 [英] Retrieve all rows inserted in sqlite database and display in table view cells containing labels as subviews with different sections

查看:39
本文介绍了检索在sqlite数据库中插入的所有行,并在包含标签的表视图单元格中显示为带有不同部分的子视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Objective-c和sqlite的新手.我已成功使用sqlite将数据插入表中.我的项目包含2页

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 clicks save which is the right navigation bar

查看提醒"页面:这是用户在表格视图的单元格中查看保存的提醒的地方,

View Reminder page:This is where the user views the saved reminder in cells of table view,

即第一个单元格上的第一个提醒,第二个单元格上的第二个提醒,依此类推...

i.e. 1st reminder on 1st cell,2nd reminder on 2nd cell and so on...

使用以下代码使我的任务更容易指定节数,这意味着保存的提醒数等于视图提醒表中的节数

I have made my task much easier to specify the number of sections using the following code,means the number of saved reminders is equal to number of sections in view reminder table

-(NSInteger)numberOfSectionsInTableView:(UITableView *)view
{    
    numTableRecords = -1;
    sqlite3_stmt *statement;
    if (sqlite3_open([self.databasePath UTF8String], &remindersDB) == SQLITE_OK) 
    {
        NSString *sqlStatement = [NSString stringWithFormat: @"select count(*) from reminders"];
        const char *sql = [sqlStatement cStringUsingEncoding:NSUTF8StringEncoding];
        if(sqlite3_prepare_v2(remindersDB, sql, -1, &statement, NULL) == SQLITE_OK) 
        {          
            while(sqlite3_step(statement) == SQLITE_ROW) 
            {
                numTableRecords = sqlite3_column_int(statement, 0);
            }
        }
        else 
        {
            printf("could not prepare statement: %s\n", sqlite3_errmsg(remindersDB));
        }
    }

    else 
    {
        NSLog(@"Error in Opening Database File");
    }
    sqlite3_close(remindersDB);
    NSLog(@"Number of records = %d",numTableRecords);
    return numTableRecords; 

}

基于以下链接中给出的建议,与我的要求非常相似:

Based on suggestion given in the following link,pretty much similar to my requirement:

按顺序在sqlite数据库中的表格行中填充表格视图部分

我获取了一个数组,并将检索到的数据作为对象插入到数组中,如下所示:

I took an array and inserted the retrieved data as objects to the array as shown in the following:

-(void)viewWillAppear:(BOOL)animated
{

    //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)
        {
            if (sqlite3_step(statement) == SQLITE_ROW)
            {
                ID = [[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)]autorelease];

                nameField = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)]autorelease];                    

                eventField = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)]autorelease];

                dateField = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 3)]autorelease];
            } 

            sqlite3_finalize(statement);
        }
        sqlite3_close(self.remindersDB);
    }
    [array addObject:ID];
    [array addObject:nameField];
    [array addObject:eventField];
    [array addObject:dateField];
    [self.theTable reloadData];
    [super viewWillAppear:YES];
}

现在在(UITableViewCell)单元格中索引路径的行中,我获取了4个标签并将它们添加为子视图,并将[array objectAtIndex:indexPath.row]分配给label.text,即:

Now in (UITableViewCell)-cell for row at index path I took 4 labels and added them as subviews and assigned the [array objectAtIndex:indexPath.row] to label.text,i.e.:

 - (UITableViewCell *)tableView:(UITableView *)view cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    //NSString *CellId = [NSString stringWithFormat:@"S%1dR%1d",indexPath.section,indexPath.row];

    UITableViewCell *cell = (UITableViewCell *)[view dequeueReusableCellWithIdentifier:nil];

    if (cell == nil)
    {
        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];

    }
 label1.text = [array objectAtIndex:indexPath.row];
    label2.text = [array objectAtIndex:indexPath.row];
    label3.text = [array objectAtIndex:indexPath.row];
    label4.text = [array objectAtIndex:indexPath.row];

    [cell addSubview:label1];
    [cell addSubview:label2];
    [cell addSubview:label3];
    [cell addSubview:label4];

    return cell;
}

在单元格上什么都没有显示,请帮助我解决此问题.为此,工作非常不好,因为我是Objective-C的新手,如果有人提出详细的说明和解决方案,我将非常高兴.这个问题听起来是否愚蠢

Nothing is getting displayed on cells,please help me to fix this issue.Struggling very bad for this,as I am new to objective-c,I would be very happy if any one comes up with detailed explanation and solution.Sorry for the question if it sounds stupid

首先感谢所有:)

推荐答案

我了解您现在要做什么.

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.

您的提醒类别如下:

Reminder.h

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

,您的hinter.m文件为:

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.

因此,将以下属性添加到显示提醒列表的ViewController中.

So add the following property to your ViewController which shows the list of reminders.

@property (nonatomic, retain) NSMutableArray *reminders;

确保您还在视图控制器.m文件中对此进行了合成,为此,请在视图控制器.m文件中的@implementation行下添加以下代码行:

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;

还请记住在您的dealloc方法中将hinters属性设置为nil,以确保正确进行内存清理:

Also remember to set the reminders property to nil in your dealloc method to ensure proper memory cleanup:

self.reminders = nil;

我们将使用在视图控制器中创建的Reminder类,因此您还需要导入您的类,因此在视图控制器.m文件中,在文件顶部附近添加一个导入语句,如下所示:

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.

在视图控制器中添加一个新方法,将其命名为loadReminders

Add a new method to your view controller, call it something like loadReminders

此方法的实现为:

-(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);
    }


}

因此,此方法正在从数据库中加载行,并针对数据库中的每一行创建一个新的Reminder对象,使用行中的数据设置属性,然后将该提醒对象添加到提醒中数组.

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)

while语句将循环并从数据库中获取每一行.

the while statement will loop round and fetch each row from the database.

每当您要刷新数据列表时,都将调用此新方法(loadReminders),因此,在代码中当前正在重新加载表的任何地方,请在重新加载表之前调用此方法,这将确保您的数组提醒已准备就绪,可供表重新加载时使用.因此,在上面的示例中,我将您的viewWillAppear方法替换为:

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];
}

现在所有数据都已设置并可以使用.并且使用提醒对象应该使tableView中的代码更易于阅读.

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.

因此,要将数据放入表中,请使用以下内容替换当前的tableview方法.

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.

现在,根据您的描述(和链接),您正在做的是在每个部分中创建1个单元格.因此,添加以下方法来告诉tableView我们希望每个节有1行

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;
}

现在,对于cellForRowAtIndexPath,将您的当前方法替换为以下内容:

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;

}

因此,此方法中发生的事情是,首先,我们从hinters数组中获取了当前部分的提醒:

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.

现有解决方案不起作用的原因是因为您使用的是indexPath.Row,并且因为每个提醒都使用了一个部分,所以indexPath.Row始终为0,因为每个部分中只有1行.

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

这篇关于检索在sqlite数据库中插入的所有行,并在包含标签的表视图单元格中显示为带有不同部分的子视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆