将UISwitch状态保存到sqlite数据库中,并访问该数据库进行显示



我有一个包含文本字段、textView和2个开关的表单。现在我使用sqlite数据库将数据保存到数据库中。文本字段、文本视图保存、检索甚至显示保存的内容都很好。正如我们所知,我们没有任何称为复选框的功能,我们需要使用与复选框功能相同的开关。现在将交换机状态保存到数据库中。我只将其保存为字符串/文本格式,即检查开关的状态,将值指定为"1"表示ON,将值分配为"0"表示OFF为整数。现在你可能会有点困惑,我如何将整数保存为字符串格式,是的,你是对的!我正在将中的int值转换为数字,最后将数字转换为字符串。然后,我形成了查询,并将值插入到sqlite数据库表中。以下是它的代码片段,以便于清晰理解:

int smsValue = 0;
    if ([smsSwitch isOn])
    {
        smsValue = 1;
    }
    else
    {
        smsValue = 0;
    }
    NSNumber *smsNum = [NSNumber numberWithInt:smsValue];
    NSString *selectedVal = [smsNum stringValue];

selectedVal是我们在形成查询时将作为字符串传递的值,我还发现状态保存正确,即值是正确的。

现在我有一个要求,在我的表单中,我有短信开关,最初开关的状态是关闭,在关闭状态下,最后两个字段,即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];
}

这里的reminderInstance是模型类的对象,包含名称、事件、日期等值。现在,最后两个字段,即textField5和textView被绑定或链接到sms开关的状态。如果选择了它,我们需要考虑这两个字段的值,并将它们传递给用户进行编辑/更改。如果没有,我们就不必为最后两个字段而烦恼。

以下是交换机的操作:

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

现在发生的事情是,因为我在显示控制器中有一个表视图,其中有两个包含字段,除了链接到短信状态的字段,还有一个包含所有字段。当我选择视图控制器时,它在"loadedReminder.number"行崩溃:

*由于未捕获的异常"NSInvalidArgumentException"而终止应用程序,原因:"*-[NSPlaceholderString initWithUTF8String:]:NULL cString"

当我删除loadedReminder.numberloadedReminder.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的问题。因为它保存得很好,但开关总是处于关闭状态,所以在填写表单和保存表单时(如果用户选择它并填写最后两个字段),状态设置为默认状态以保存表单(记录)。

很抱歉有这么多的描述,我只是想详细说明一下,这样任何人都能理解我的问题是什么,我已经搜索了好几次了。但无法完成任务。

有谁能告诉我一种方法,如何在数据库中保存切换状态,然后在从数据库sqlite加载记录时填充相同的状态吗。

提前感谢每一个人:)

我找到了它的解决方案,即使用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];
    }
}

就是这样,我们现在已经通过正确访问为所有连续提醒保存的值来正确设置切换状态。

希望能有所帮助。非常感谢。

最新更新