【问题标题】:Saving an array of booleans to UITableView将布尔数组保存到 UITableView
【发布时间】:2015-07-20 19:57:27
【问题描述】:

我想要完成的是构建一个 UITableView,其中每个单元格的右侧都有一个 UISwitch,当用户再次打开应用程序时,这些开关将保持在相应索引路径的开/关位置。

我创建了一个布尔值的 NSArray 并将它们保存到 NSUser 默认值,但是在循环返回它们以使布尔值位于正确的索引以将单元格切换开关设置为打开或关闭时遇到了一些障碍。

创建具有索引路径属性的自定义单元格会更好吗?那么只是有一种方法可以将布尔值保存到索引路径吗?

我对编程比较陌生,所以我想知道一些更高级的人认为最快和最简单的方法是什么。

非常感谢!

这是我的布尔控制器,保存方法是公开的,

#import "BoolController.h"

static NSString *const boolArrayKey = @"boolArrayKey";

@implementation BoolController

+ (BoolController *)sharedInstance {
static BoolController *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    sharedInstance = [BoolController new];
});

return sharedInstance;

}

- (void)saveBool:(BOOL)boolean {

NSArray *arrayOfBooleans = [[NSArray alloc]init];

arrayOfBooleans = [arrayOfBooleans arrayByAddingObject:[NSNumber         numberWithBool:boolean]];

[[NSUserDefaults standardUserDefaults]setObject:arrayOfBooleans     forKey:boolArrayKey];
[[NSUserDefaults standardUserDefaults]synchronize];

}

- (NSArray *)booleans {

   return [[NSUserDefaults standardUserDefaults]objectForKey:boolArrayKey];

}

@end

这是我在索引路径方法中的行单元格

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

UISwitch *toggleSwitch = [[UISwitch alloc]initWithFrame:CGRectMake(50, 10, 50, 30)];
[cell addSubview:toggleSwitch];

if (toggleSwitch.isOn == YES) {

    [[BoolController sharedInstance]saveBool:YES];
}

if (toggleSwitch.isOn == NO) {

    [[BoolController sharedInstance]saveBool:NO];
}

return cell;

}

【问题讨论】:

  • 我更新了代码,索引路径方法的行单元格不完整,因为我一直在玩不同的东西,我只是不知道从哪里开始。

标签: ios objective-c uitableview boolean nsarray


【解决方案1】:

据我了解您的问题,我得出以下结论:

  1. 您绝对应该尊重 MVC 模式 - 这样您就不会将数据存储在 UI 对象 (VIEW) 中。
  2. 您的 saveBool 方法会在每次调用时创建一个新的数组实例,并在您将其同步到用户默认值时覆盖最近的实例。在您的 CONTOLLER 中使用超出函数调用范围的 ivar...

您应该只获取行的索引路径并将 ON/OFF 状态存储在数组的同一索引处。此数组是您的 MVC 设置中的 MODEL...

所以下次创建表格视图时,每一行(索引)都会从数组(索引)中为您的开关获取正确的布尔值!!!

【讨论】:

  • 1.当您说“不要将数据存储在 UI 对象中”时,我猜您指的是开关? 2.我应该做一个if语句来检查是否已经有一个数组吗?我也刚刚意识到这一点。我不是已经存储了 ON/OFF 状态(是或否布尔值)吗?我想过用方法的索引保存布尔值,但这会使事情变得过于复杂。布尔控制器中有一个数组,作为我的 MVC 模型还不够吗?非常感谢!
  • 我认为向单元格或 UISwitch 添加标签实际上可能是解决此问题的最简单方法。
  • 作为新答案跟进,因为需要所有格式选项...
【解决方案2】:
  1. 开关是一个 UI 元素 (VIEW)。你把它放在故事板的单元格中。你看到的只有 UI——表格视图、单元格等。故事板中唯一不是 UI 的是视图控制器(CONTROLLER)。
  2. 对于这么小的应用程序,您的模型不需要独立的类。无论如何,它将存储在您的用户默认值中... -> 所以只需将一个数组 (MODEL) 作为实例变量(或声明的属性)添加到您的视图控制器。因此,只要您的视图存在,它就会一直存在。
  3. 每当您循环遍历行索引时——例如检查开关的状态——使用 for 循环 (i=0 ... i++) 执行此操作,并且您已经使用循环的 i 变量获得索引。所以把它准确地写在你的数组的那个索引处。当然,您首先从数组(数据MODEL)中创建了具有相同索引的表视图 - 所以行和整个表VIEW反映你的 MODEL 数组。这样,您始终保持同步。当用户移动开关(VIEW)时,您会收到通知它在哪一行,瞧 -> 更新您的 MODEL 数组并刷新您的表格 VIEW 与您的模型的新信息。所有更新和同步都应由 CONTROLLER 完成。

模型是真理。始终使用您在 MODEL 中找到的信息创建和刷新 VIEW。如果 VIEW 发生变化 - 让 CONTROLLER 更新 MODEL,反之亦然... - 并且不时更新您的用户默认值您的临时 MODEL 数组的值。因为如果应用程序崩溃或被系统杀死,您需要从用户默认值中读回数组的模型值。如果不是最新的,您将获得上次同步的值...

总之,我建议您阅读更多有关 iOS 编程中的设计模式的内容。这是每个应用程序的脚手架。没有它,你无论如何都会迷路。如果你不是很喜欢阅读(这对于编程极客来说非常糟糕),一定要去'iTunes U' -> 斯坦福大学 / Paul Hagerty

  • 一起编码
  • iOS 应用程序编程

ObjC 2010 - 2014 年的讲座(有时每年两门课程)
2014 年末的 Swift 讲座。

每个季度大约有 18 节视频讲座。它们都涵盖了相同的主题,只是扩展了有关添加到 iOS 的新技术的信息。 全部观看 - 从 2010 年开始 - 表格视图,例如在头几年得到更好的保障......

这真的是一个从绝对新手到(几乎)专业人士的硬核 Corrida ;-) 并且很有趣 - 这个家伙,他的知识和他的演讲方式简直令人惊叹。

所以 - 说够了 - 回去工作吧!

尽情探索 SDK

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-25
    • 2017-04-25
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 1970-01-01
    • 2020-02-25
    • 2014-05-07
    相关资源
    最近更新 更多