Сохраните состояние UISwitch в базе данных sqlite и получите к нему доступ для отображения.

У меня есть форма, содержащая текстовые поля, 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, скрыты. Если пользователь выбирает его (т.е. состояние включено) , то оба поля считаются открытыми для ввода значений.

Всего я сохранил 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];
}

Здесь напоминаниеInstance является объектом класса модели, содержащего такие значения, как имя, событие, дата и т. д. Теперь последние 2 поля, т.е. textField5 и textView, привязаны или связаны с состоянием переключателя sms. Если он выбран, нам нужно рассмотреть оба поля значения и передать их пользователю для редактирования/внесения изменений. Если нет, нам не нужно беспокоиться о последних 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);
    }

}

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

* Завершение работы приложения из-за необработанного исключения "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";
}

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

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

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

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


person Eshwar Chaitanya    schedule 06.03.2012    source источник
comment
На ум приходит столько вопросов, что я даже не знаю, с чего начать! Вы понимаете, что базы данных могут хранить другие типы, кроме строк, не так ли?   -  person Nick Bull    schedule 06.03.2012
comment
@NickBull Да, но раньше я сделал кнопку флажком, т.е. Я установил обычную кнопку в качестве изображения без выбора, а при выборе изображения кнопки с галочкой я сохранил его только как строковый формат ... и более того, ранее он использовался для просмотра таблицы, поэтому я передал значения значениям этот класс напоминания содержится в методе cellForRowAtIndexPath:! Я тоже добился успеха, точно так же я думал, что смогу добиться того же с помощью UISwitch. Если мое решение неверно, я искренне сожалею о том же.   -  person Eshwar Chaitanya    schedule 06.03.2012
comment
уменьшите длину своего вопроса, иначе никто не заинтересуется лихорадочной работой по пониманию этого вопроса.   -  person Mobile Developer iOS Android    schedule 06.03.2012
comment
@iOSDeveloper Спасибо за вопрос, но если я уменьшу вопрос, у меня будет много вопросов, описание bcoz будет звучать запутанно. Поэтому я ясно дал понять с помощью фрагментов кода. Я согласен с вашим пунктом в любом случае :)   -  person Eshwar Chaitanya    schedule 06.03.2012
comment
попробуйте сохранить int в базе данных как; NSString *selectedVal = [NSString stringWithFormat:@%i, smsValue]; а также поместите проверку на нулевую строку при извлечении данных из БД.   -  person Mobile Developer iOS Android    schedule 06.03.2012
comment
@iOSDeveloper О, большое спасибо, но после сохранения, как передать значения последних 2 полей, мне следует написать, если (smsSwitch isOn) textField5.text = напоминаниеInstance.number и textView.text = напоминаниеInstance.msgBody; в viewDidLoad, так же, как я делал это с другими полями в форме   -  person Eshwar Chaitanya    schedule 06.03.2012
comment
@EshwarChaitanaya, вам нужно прочитать И ПОНЯТЬ о контроллере представления модели, а также о типах данных. Это сильно поможет вам   -  person Nick Bull    schedule 06.03.2012
comment
@NickBull Да, я понял о шаблоне Modal View Controller после изучения нескольких руководств, а также типов данных на сайте www.sqlite.org, я просто хотел заставить его работать с помощью NSString, не могли бы вы предложить мне способ сделать это   -  person Eshwar Chaitanya    schedule 06.03.2012
comment
@EshwarChaitanya Как это сделать? Примените концепции MVC к своему дизайну, и все должно получиться легко и приятно. Если нет, то вам нужно переработать свой дизайн. Я бы посоветовал вам повторить некоторые уроки, если вы боретесь с этим.   -  person Nick Bull    schedule 06.03.2012


Ответы (1)


Я нашел решение для него, т.е. используйте 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];
    }
}

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

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

person Eshwar Chaitanya    schedule 19.03.2012