我首次尝试在UIPickerViews的App中使用NSUserDefaults。但是,在测试时,应用程序崩溃/数据未在PickerView中显示。我仍然试着自己解决这个问题,但是一些帮助会很棒。
ViewController3: 用户应将数据保存到NSUserDefault。因此,有一个textField写下一些东西和一个“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 = ""
}
ViewController 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")
}
}
}
答案 0 :(得分:1)
首先,确保datasource
&为pickerViews设置了delegate
。您可以通过选择pickerView并从dataSource拖动并委托给您的viewController来在故事板中设置它们:
或者您可以像viewDidLoad
这样设置它们:
self.pickerView1.dataSource = self
self.pickerView2.delegate = self
您正在使用titleForRow
方法崩溃。我猜你的练习数组在该方法触发时没有任何数据。覆盖viewDidLoad
并将代码从viewDidAppear
移至该方法。在选择器尝试显示之前,您需要在练习数组中包含数据。
我在你的viewDidAppear
方法中注意到的另一件事,你必须在视图覆盖中做的第一件事是在你自己的代码之前调用超级super.viewDidAppear(animated)
。同样,您必须先在super.viewDidLoad()
中致电viewDidLoad
。
在switch
语句中,将pickerView3
设为默认大小写,并删除assertionFailure
行。 pickerView委托方法期望返回值,因此这可能会使事情失效。
答案 1 :(得分:0)
你的pickerViews为空的原因是很可能是,因为你没有将它们连接到viewController1作为dataSource和delegate。您可以在故事板或代码中执行此操作:
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
}
}
更新(part 3)
exerciseList是一个字典数组。例如,您在exerciseList中添加了一个新项目:
newMutableList.addObject(dataSet)
其中dataSet的创建/定义如下:
var dataSet:NSMutableDictionary = NSMutableDictionary()
dataSet.setObject(textField.text, forKey: "exercises")
所以你有一个单项词典,用键"练习"。
然后在viewController1中解压缩数组并假设它填充了 strings ,而不是字典:
return exercises[row] as String
在这里,您将字典转换为字符串,该字符串正在崩溃。
线索在堆栈跟踪线swift dynamic cast failed
中
并在这些行
(ObjectiveC.UIPickerView, titleForRow : Swift.Int, forComponent:
Swift.Int) => Swift.ImplicitlyUnwrappedOptional<Swift.String>
如果您正确地从字典键中提取字符串作为值,它将起作用&#34;练习&#34;:
return exercises[row]["exercises"] as String
或者,您可以使用字符串而不是字典填充数组(因为每个条目只有一个条目)。
希望你现在可以运行它而不会崩溃!