检索插入到 sqlite 数据库中的所有行,并在包含标签的表视图单元格中显示为具有不同部分的子视图

2024-04-05

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

添加提醒页面:用户输入数据并单击“保存”,这是右侧导航栏

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

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

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

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

}

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

按顺序使用 sqlite 数据库中的表行填充表视图部分 https://stackoverflow.com/questions/8475446/populate-the-table-view-sections-with-rows-of-table-in-sqlite-database-in-an-ord

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

-(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)-cell 中,我采用了 4 个标签并将它们添加为子视图,并将 [array objectAtIndex:indexPath.row] 分配给 label.text,即:

 - (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 的新手,如果有人能提出详细的解释和解决方案,我将非常高兴。抱歉这个问题如果这听起来很愚蠢

预先感谢大家:)


我明白你现在想做什么。

我建议创建一个类来保存每个提醒的数据,然后您可以拥有一个提醒数据数组。

因此,我会向您的项目添加一个新类,将其命名为“提醒”,然后为每个字段添加一个属性。

您的提醒类别如下:

提醒.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

你的reminder.m 文件将是:

#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

因此,此类将仅保存每个提醒的数据。

然后在显示提醒列表的视图控制器中,您需要添加一个数组属性来保存提醒对象。

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

@property (nonatomic, retain) NSMutableArray *reminders;

确保您还在视图控制器 .m 文件中综合了这一点,为此,请在视图控制器 .m 文件中的 @implementation 行下添加此代码行:

@synthesize reminders;

还要记住在 dealloc 方法中将提醒属性设置为 nil 以确保正确的内存清理:

self.reminders = nil;

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

#import "Reminder.h"

现在您的视图控制器已设置完毕并准备好使用我们创建的提醒类。

然后,您需要在视图控制器中添加一个方法,该方法将用于从数据库加载数据并填充提醒对象和提醒数组。

向视图控制器添加一个新方法,将其命名为 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 对象,使用该行中的数据设置属性,然后将此提醒对象添加到提醒数组中。

请注意我对您的原始代码所做的更改:

while (sqlite3_step(statement) == SQLITE_ROW)

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

每当您想要刷新数据列表时,您都会调用这个新方法(loadReminders),因此在您当前重新加载表格的代码中的任何位置,请在重新加载表格之前调用此方法,这将确保您的提醒数组已设置准备好在重新加载时使用表。因此,在上面的示例中,我会将您的 viewWillAppear 方法替换为:

-(void)viewWillAppear:(BOOL)animated
{
    [self loadReminders];
    [self.theTable reloadData];
}

现在所有数据均已设置并可供使用。使用提醒对象应该会使 tableView 中的代码更易于阅读。

因此,要将数据放入表中,请将当前的表视图方法替换为以下方法。

-(NSInteger)numberOfSectionsInTableView:(UITableView *)view
{
     return [self.reminders count];
}

这将告诉表为提醒数组中的每个提醒创建一个部分。

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

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

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

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

}

那么这个方法中发生的事情是,首先我们从提醒数组中获取当前部分的提醒:

Reminder *reminderToDisplay;
reminderToDisplay = [self.reminders objectAtIndex:indexPath.section];

接下来的几行应该很熟悉,我们正在创建单元格和标签。然后我们使用提醒对象来设置标签文本。

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

我知道这是一篇很长的文章,但希望可以帮助您了解正在发生的事情。有任何问题请告诉我

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

检索插入到 sqlite 数据库中的所有行,并在包含标签的表视图单元格中显示为具有不同部分的子视图 的相关文章

随机推荐