Сохраните состояние UISwitch в базе данных sqlite и получите доступ к нему для отображения - PullRequest
0 голосов
/ 06 марта 2012

У меня есть форма, содержащая текстовые поля, textView и 2 переключателя. Теперь я использую базу данных sqlite для сохранения данных в базе данных. Все хорошо с текстовыми полями, сохранением текстового представления, извлечением и даже отображением сохраненных. Как мы знаем, что у нас нет никакой функции, называемой флажком, нам нужно использовать переключатель, который ведет себя / действует как функциональность переключателя. Теперь, сохраняя состояние переключателя в базе данных. Я сохраняю его как строку / только текстовый формат, т.е. проверьте состояние переключателя, присвойте значение как «1» для включения и «0» для выключения целому числу. Теперь вы можете немного запутаться, как я могу сохранить целое число в строковом формате, да, вы правы! Я преобразовываю int значение в число и, наконец, число в строку. Затем я сформировал запрос и вставил значения в таблицу базы данных sqlite. Вот фрагмент кода для ясного понимания:

int smsValue = 0;

    if ([smsSwitch isOn])
    {
        smsValue = 1;
    }

    else
    {
        smsValue = 0;
    }

    NSNumber *smsNum = [NSNumber numberWithInt:smsValue];
    NSString *selectedVal = [smsNum stringValue];

selectedVal - это то, что мы собираемся передать как строку при формировании запроса, я также обнаружил, что состояние сохраняется должным образом, т.е. значение верное.

Теперь у меня есть требование, в моей форме у меня есть переключатель для смс. Первоначально состояние этого переключателя выключено, в состоянии «выключено» последние 2 поля, т.е. textField и textView, скрыты. Если пользователь выбирает его (т.е. состояние ON), тогда оба поля считаются открытыми для ввода значений.

Всего я сохранил 3 напоминания, из которых я сохранил 2 без смс и 1 с смс и оба поля (последние) заполнены. Теперь для передачи данных или для отслеживания записи, сохраненной после заполнения формы Я использовал класс модели, см. Следующий фрагмент для ясного понимания ... как я передал значения для других полей (textFields):

-(void)viewDidLoad
{
    textField.text = reminderInstance.Name;
    textField1.text = reminderInstance.Event;
    textField2.text = reminderInstance.Date;
    textField3.text = reminderInstance.numDays;
    textField4.text = reminderInstance.remGroup;

    [super viewDidLoad];
}

Здесь remderInstance - это объект класса модели, содержащий значения, такие как имя, событие, дата и т. Д. Теперь последние 2 поля, т. Е. TextField5 и textView, связаны или связаны с состоянием переключателя смс. Если этот параметр выбран, нам нужно рассмотреть оба значения полей и передать их пользователю для редактирования / внесения изменений. Если нет, нам не нужно беспокоиться о последних 2 полях.

Вот действие для переключателя:

-(IBAction)toggleEnabledForswitch:(id)sender
{
    if(smsSwitch.on)
    {
        textField5.hidden = NO;
        textView.hidden = NO;
    }

    else 
    {
        textField5.hidden = YES;
        textView.hidden = YES;
    }
}

Теперь в действии сохранения, я проверяю состояние переключателя и сохраняю значения соответственно, следующий фрагмент кода покажет четкую картинку:

-(IBAction)save:(id)sender
{
int smsValue = 0;

    if ([smsSwitch isOn])
    {
        smsValue = 1;
    }

    else
    {
        smsValue = 0;
    }

    NSNumber *smsNum = [NSNumber numberWithInt:smsValue];
    NSString *selectedVal = [smsNum stringValue];

    reminderInstance.smsString = selectedVal;
sqlite3_stmt *statement = nil;
    const char *dbpath = [databasePath UTF8String];

    if (sqlite3_open(dbpath, &remindersDB) == SQLITE_OK && textField.text != nil)
    {
      if (self.navigationItem.rightBarButtonItem.title == @"Save" && [textField.text length] !=0 && [textField1.text length] !=0 && [textField2.text length] !=0 && [textField3.text length] !=0 && [textField4.text length] !=0)
       {
            NSLog(@"am in the save loop");

            if (smsValue == 0)
            {
                NSString *insertSQL = [NSString stringWithFormat:@"INSERT INTO reminders(name,event,date,bfr,grp,val,sms) VALUES (\"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\")", textField.text, textField1.text,textField2.text,textField3.text,textField4.text,isSelected,selectedVal]; 
                const char *insert_stmt = [insertSQL UTF8String];
                sqlite3_prepare_v2(remindersDB, insert_stmt, -1, &statement, NULL);
            }

            else if (smsValue == 1)
            {
                NSString *insertSQL = [NSString stringWithFormat:@"INSERT INTO reminders(name,event,date,bfr,grp,val,sms,num,bod) VALUES (\"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\")", textField.text, textField1.text,textField2.text,textField3.text,textField4.text,isSelected,selectedVal,textField5.text,textView.text]; 
                textField5.text = reminderInstance.number;
                textView.text = reminderInstance.msgBody;
                const char *insert_stmt = [insertSQL UTF8String];
                sqlite3_prepare_v2(remindersDB, insert_stmt, -1, &statement, NULL);
            }

            if (sqlite3_step(statement) == SQLITE_DONE)
            {
                UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"\nReminder Saved" message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:nil,nil];
                [alert show];
                [alert dismissWithClickedButtonIndex:0 animated:YES];
                [alert release];
            }

            else 
            {
                UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Alert" message:@"Reminder not saved" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
                [alert show];
                [alert release];
            }

        }
    }
 }

Я взял другой контроллер представления с табличным представлением, где я заполнил табличное представление, чтобы просмотреть все сохраняемые записи, и после выбора мы переместим его / ее на страницу контроллера, которая содержит форму, то есть заполненную всеми значениями. пока я успешно прошел все значения, используя:

1. Следующий код на странице контроллера формы:

-(id) initWithReminder:(ReminderClass *)aReminder 
{
    if ( (self=[super init]) ) 
    {
        self.reminderInstance = aReminder;
    }

    return self;
}

2. Следующие части кода в контроллере дисплея:

-(void)loadReminders
{

    // setup the reminders array
    self.array = [[NSMutableArray alloc] init];

    //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"];

        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)
            {
                ReminderClass *loadedReminder = [[ReminderClass alloc] init];

                loadedReminder.reminderID = sqlite3_column_int(statement, 0);

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

                loadedReminder.numDays = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 4)]autorelease];

                loadedReminder.remGroup = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 5)]autorelease];

                loadedReminder.selString = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 6)]autorelease];

                loadedReminder.smsString = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 7)]autorelease];

                NSLog(@"selected value = %@",loadedReminder.smsString);


                 loadedReminder.number = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 8)]autorelease];

                 loadedReminder.msgBody = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 9)]autorelease];


                NSDateFormatter *dateFormat = [[[NSDateFormatter alloc]init]autorelease]; 
                [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 
                NSDate *theDate = [dateFormat dateFromString:loadedReminder.Date];
                NSString *stringDate = [dateFormat stringFromDate:theDate];
                loadedReminder.Date = stringDate; 

                NSLog(@"Date = %@",loadedReminder.Date);

                [self.array addObject:loadedReminder];
                [loadedReminder release];
            } 

            sqlite3_finalize(statement);
        }
        sqlite3_close(self.remindersDB);
    }

}

Теперь, что происходит, так как у меня есть табличное представление в контроллере дисплея с 2 полями, содержащими поля, за исключением тех, которые связаны с состоянием смс, и одно со всеми заполненными полями. Когда я выбираю контроллер представления, он падает на линии " loadedReminder.number":

* Завершение работы приложения из-за необработанного исключения «NSInvalidArgumentException», причина: «* - [NSPlaceholderString initWithUTF8String:]: NULL cString '

когда я удаляю loadedReminder.number и loadedReminder.msgBody , мы можем просматривать таблицу (страницу контроллера) без сбоев, что происходит ... После выбора ячейки представления таблицы Я делаю следующее:

-(void)tableView:(UITableView *)atableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    ReminderClass *rem = [self.array objectAtIndex:indexPath.section];

    // Instantiate your detail/editor view controller,
    // and pass in the ReminderClass object to be edited.
    ERAddReminderViewController *rdvc = [[[ERAddReminderViewController alloc]initWithReminder:rem]autorelease];

    [self.navigationController pushViewController:rdvc animated:YES];
    rdvc.navigationItem.rightBarButtonItem.title = @"Edit";
}

Теперь я могу видеть все значения, правильно заполненные в полях, кроме проблемы с switch. Потому что он правильно сохраняет, но переключатель всегда находится в выключенном состоянии, состояние установлено по умолчанию, как я уже говорил при заполнении формы. и сохранение его (если пользователь выбирает его и также заполняет последние 2 поля), чтобы сохранить его (запись).

Извините за это огромное описание , просто хотел сделать его подробным, чтобы любой мог понять, в чем моя проблема, я сделал несколько поисков . Но не смог достичь задача.

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

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

1 Ответ

0 голосов
/ 19 марта 2012

Я нашел решение для этого, т.е. используйте NSString и присвойте строковое значение, то есть извлеченные значения состояния, которые были добавлены в массив. Позвольте мне объяснить это подробно:

На странице Добавить напоминание возьмитескажем, NSString currentState, теперь вернитесь туда, где просматриваются сохраненные напоминания, возьмите массив с именем «stateValues» и добавьте значения состояния в этот массив, например:

loadedReminder.smsState = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 7)]autorelease];

[stateValues addObject:loadedReminder.smsState];

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

-(void)tableView:(UITableView *)atableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    ReminderClass *rem = [self.array objectAtIndex:indexPath.section];
    NSLog(@" switch state in did : %@",[stateValues objectAtIndex:indexPath.section]);
 ERAddReminderViewController *rdvc = [[[ERAddReminderViewController alloc]initWithReminder:rem]autorelease];
    rdvc.currentState = [stateValues objectAtIndex:indexPath.section];
}

Мы успешно установили значения в текущее состояние, теперь вернемся, чтобы добавить страницу напоминания вустановить состояние переключателя, т.е. в методе viewDidLoad выполните следующие действия:

-(void)viewDidLoad
{

    if ([currentState isEqualToString:@"0"]) 
    {
        [smsSwitch setOn:NO animated:NO];
    }
    else if([currentState isEqualToString:@"1"])
    {
        [smsSwitch setOn:YES animated:YES];
    }
}

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

Надеюсь, это поможет. Спасибо!

...