Извлечь все строки, вставленные в базу данных sqlite, и отобразить в ячейках табличного представления, содержащих метки, как подпредставления с различными разделами. - PullRequest
1 голос
/ 20 декабря 2011

Я новичок в Objective-C и sqlite. Я успешно вставил данные в таблицу, используя sqlite. Мой проект содержит 2 страницы

Страница напоминания о добавлении: где пользователь вводит данные и нажимает сохранить, что является правильнымпанель навигации

Просмотр страницы напоминания: здесь пользователь просматривает сохраненное напоминание в ячейках табличного представления,

, то есть 1-е напоминание в 1-й ячейке, 2-е напоминание во 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 в порядке

Iвзял массив и вставил извлеченные данные в качестве объектов в массив, как показано ниже:

-(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 для строки по индексу paЯ взял 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, я был бы очень рад, если кто-нибудь придет с подробным объяснением и решением. Извините за вопрос, если это звучит глупо

Спасибо всем взаранее:)

Ответы [ 2 ]

7 голосов
/ 20 декабря 2011

Я понимаю, что вы пытаетесь сделать сейчас.

Я бы порекомендовал создать класс для хранения данных для каждого напоминания, тогда у вас может быть массив данных напоминания.

Поэтому я бы добавил новый класс в ваш проект, назвал его «Напоминание», а затем добавил свойство для каждого из ваших полей.

Ваш класс напоминания будет выглядеть следующим образом:

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

, а ваш файл Remder.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 вашего контроллера представления:

@synthesize reminders;

Также не забудьте установить для свойства напоминаний значение nil в вашем методе dealloc для обеспечения надлежащей очистки памяти:

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.

Таким образом, чтобы получить ваши данные в таблицу, замените текущие методы 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 строка.

Я знаю, что это длинный пост, но, надеюсь, должен помочь вам понять, что происходит.Любые вопросы, то дайте мне знать

1 голос
/ 20 декабря 2011

Вы действительно должны создать Custom UITableViewCell.

Но для быстрого исправления вы можете заменить нижние строки [cell addSubview] следующими

cell.contentView = [[UIView alloc] init] autorelease]
[cell.contentView addSubview:label1];
[cell.contentView addSubview:label2];
[cell.contentView addSubview:label3];
[cell.contentView addSubview:label4];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...