UIPickerView不会从显示NSUserDefaults的加载的数据 - 应用程序的同时加载数

2019-10-21 16:39发布

我做了第一次尝试在一个应用程序来使用与NSUserDefaults的UIPickerViews。 不过,虽然测试/数据没有在PickerView显示的应用程序崩溃。 我还是尽量自己解决,但一些帮助将是巨大的。

ViewController3: 凡用户应保存数据到NSUserDefault。 因此,有来记东西的文本字段和“Savebutton”

class ViewController3: UIViewController, UITextFieldDelegate {

@IBOutlet weak var textField: UITextField!

...

 @IBAction func tappedAddButton(sender: AnyObject) {

    var userDefaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()

    var exercisesList:NSMutableArray? = userDefaults.objectForKey("exercisesList") as? NSMutableArray

    var dataSet:NSMutableDictionary = NSMutableDictionary()
    dataSet.setObject(textField.text, forKey: "exercises")

    if ((exercisesList) != nil){
        var newMutableList:NSMutableArray = NSMutableArray();

        for dict:AnyObject in exercisesList!{
            newMutableList.addObject(dict as NSDictionary)
        }

        userDefaults.removeObjectForKey("exercisesList")
        newMutableList.addObject(dataSet)
        userDefaults.setObject(newMutableList, forKey: "exercisesList")

    }else{
        userDefaults.removeObjectForKey("exercisesList")
        exercisesList = NSMutableArray()
        exercisesList!.addObject(dataSet)
        userDefaults.setObject(exercisesList, forKey: "exercisesList")
    }

    userDefaults.synchronize()

    self.view.endEditing(true)
    textField.text = ""

}

视图控制器1: 凡保存的数据应该被NSUserDefaults的加载和显示pickerView1

class ViewController: UIViewController,UIPickerViewDelegate {

@IBOutlet weak var pickerView1: UIPickerView!
@IBOutlet weak var pickerView2: UIPickerView!
@IBOutlet weak var pickerView3: UIPickerView!

var reps = [["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25"],["x"]]

var weight = [["0","1","2","3","4","5"],["0","1","2","3","4","5","6","7","8","9"],["0","1","2","3","4","5","6","7","8","9"],[","],["0","25","5","75"],["kg","lbs"]]

var exercises:NSMutableArray = NSMutableArray();

override func viewDidLoad() {
    super.viewDidLoad()

    var userDefaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()

    var exercisesListFromUserDefaults:NSMutableArray? = userDefaults.objectForKey("exercisesList") as? NSMutableArray

    if ((exercisesListFromUserDefaults) != nil){
        exercises = exercisesListFromUserDefaults!
    }
    self.pickerView1.reloadAllComponents()
}

func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {

    switch pickerView {
    case pickerView1:
        return 1
    case pickerView2:
        return reps.count
    case pickerView3:
        return weight.count
    default:
        assertionFailure("Unknown pickerView")
    }
}

func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    switch pickerView {
    case pickerView1:
        return exercises.count
    case pickerView2:
        return reps[component].count
    case pickerView3:
        return weight[component].count
    default:
        assertionFailure("Unknown pickerView")
    }
}

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
    switch pickerView {
    case pickerView1:
        return exercises[row] as String
    case pickerView2:
        return reps[component][row]
    case pickerView3:
        return weight[component][row]
    default:
        assertionFailure("Unknown pickerView")
    }
}

}

Answer 1:

因为你没有有线它们备份到viewController1作为数据源和代表的原因,你的pickerViews是空的可能性最大 。 您可以在故事板或代码做到这一点:

override  func viewDidLoad() {
    super.viewDidLoad()
    let pickers = [pickerView1,pickerView2,pickerView3]
    for i in 0...2 {
        let pickerView : UIPickerView = pickers[i]
        pickerView.dataSource = self
        pickerView.delegate = self
    }
}

更新 ( 第3部分 )

exercisesList是字典的阵列。 这里有个例子,你正在添加新项exercisesList:

 newMutableList.addObject(dataSet)

其中数据集创建/定义如下:

 var dataSet:NSMutableDictionary = NSMutableDictionary()
 dataSet.setObject(textField.text, forKey: "exercises")

所以你有一个单一的项目字典,用钥匙“演习”。

然后,在viewController1你拆包数组,并假设它填充了字符串 ,而不是字典:

return exercises[row] as String

在这里,你是铸造字典为一个字符串,这是崩溃了。

线索是在堆栈跟踪线swift dynamic cast failed ,并在这些行

 (ObjectiveC.UIPickerView, titleForRow : Swift.Int, forComponent:     
 Swift.Int) => Swift.ImplicitlyUnwrappedOptional<Swift.String>

它会工作,如果你正确地提取字符串作为从字典键“练习”的值:

        return exercises[row]["exercises"] as String

另外,您可以填充的字符串,而不是字典的数组(因为你只需要进入每一个条目)。

希望你可以不崩溃,现在运行这个!



Answer 2:

首先,确保datasourcedelegate为您的pickerViews设置。 您可以设定他们通过选择pickerView和数据源,并委托给你的viewController拖动故事板:

或者你可以设置他们viewDidLoad是这样的:

self.pickerView1.dataSource = self
self.pickerView2.delegate = self

更新

您正在崩溃的titleForRow方法。 我猜你的练习阵列没有任何数据时,该方法火灾。 覆盖viewDidLoad和移动你的代码viewDidAppear到该方法。 你需要拥有的数据在你的锻炼阵列机械臂试图显示它之前。

我在你发现另一件事viewDidAppear方法时,必须考虑覆盖要做的第一件事是调用超喜欢super.viewDidAppear(animated)你自己的代码之前。 同样,你必须先调用super.viewDidLoad()viewDidLoad

更新2

在你的switch语句,使pickerView3默认情况下,摆脱那些assertionFailure线。 该pickerView委托方法期待的返回值,所以这可能是扔东西了为好。



文章来源: UIPickerView won't display the data loaded from NSUserDefaults - App is crashing while loading data