我的ViewController中有2个UIPickerViews。每个选择器视图都有一个单独的swift文件,它充当选择器的数据源和委托。我希望第二个pickerView中的行数取决于第一个pickerView中选择的行。当我尝试在" didSelect"第一个pickerView的功能我收到一个错误:"在展开一个Optional值"
时意外地发现了nil这是我的代码:
ViewController.swift:
import UIKit
class ViewController: UIViewController {
@IBOutlet var bookPickerView: UIPickerView!
@IBOutlet var chapterPickerView: UIPickerView!
var booksClass: BooksClass!
var chaptersClass: ChaptersClass!
override func viewDidLoad() {
super.viewDidLoad()
booksClass = BooksClass()
chaptersClass = ChaptersClass()
bookPickerView.delegate = booksClass
bookPickerView.dataSource = booksClass
chapterPickerView.delegate = chaptersClass
chapterPickerView.dataSource = chaptersClass
chaptersClass.chaptersList = chaptersClass.chaptersList0
}
}
ChaptersClass.swift:
import UIKit
class ChaptersClass: UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource {
var chaptersList: [String]!
func numberOfComponents(in: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return chaptersList.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return chaptersList[row]
}
//Number of chapters for each book:
var chaptersList0: [String]! = ["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", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37"]
var chaptersList1: [String]! = ["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"]
var chaptersList2: [String]! = ["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", "26", "27"]
}
BooksClass.swift:
import UIKit
class BooksClass: UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource {
var viewController: ViewController!
var chaptersClass: ChaptersClass!
var booksList: [String]! = ["Jenesis", "Exodus", "Livitikōs"]
func numberOfComponents(in: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return booksList.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return booksList[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
chaptersClass = ChaptersClass()
viewController = ViewController()
switch row {
case 0:
chaptersClass.chaptersList = chaptersClass.chaptersList0
case 1:
chaptersClass.chaptersList = chaptersClass.chaptersList1
case 2:
chaptersClass.chaptersList = chaptersClass.chaptersList2
default:
return
}
viewController.chapterPickerView.reloadAllComponents()
}
}
我的BooksClass.swift文件的以下行发生错误:
viewController.chapterPickerView.reloadAllComponents()
更新 @Sanchit Kumar Singh
我已经在Sanchit的建议的帮助下更新了我的代码。我目前没有收到任何错误,但是"章节"由于某种原因,pickerView仍未更新。谁能指出我做错了什么?
注意:我修改了" ViewController.swift"和#34; BooksClass.swift"文件。我的代码中的新条目被**星号**包围。
ViewController.swift:
import UIKit
class ViewController: UIViewController, **BooksClassDelegate** {
@IBOutlet var bookPickerView: UIPickerView!
@IBOutlet var chapterPickerView: UIPickerView!
var booksClass: BooksClass!
var chaptersClass: ChaptersClass!
**func updateChaptersList() {**
**self.chapterPickerView.reloadAllComponents()**
**}**
override func viewDidLoad() {
super.viewDidLoad()
booksClass = BooksClass()
chaptersClass = ChaptersClass()
bookPickerView.delegate = booksClass
bookPickerView.dataSource = booksClass
chapterPickerView.delegate = chaptersClass
chapterPickerView.dataSource = chaptersClass
chaptersClass.chaptersList = chaptersClass.chaptersList0
**booksClass.referenceToViewController = self**
}
}
BooksClass.swift:
import UIKit
**protocol BooksClassDelegate {**
**func updateChaptersList()**
**}**
class BooksClass: UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource {
var viewController: ViewController!
var chaptersClass: ChaptersClass!
**var referenceToViewController: BooksClassDelegate?**
var booksList: [String]! = ["Jenesis", "Exodus", "Livitikōs"]
func numberOfComponents(in: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return booksList.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return booksList[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
chaptersClass = ChaptersClass()
switch row {
case 0:
chaptersClass.chaptersList = chaptersClass.chaptersList0
case 1:
chaptersClass.chaptersList = chaptersClass.chaptersList1
case 2:
chaptersClass.chaptersList = chaptersClass.chaptersList2
default:
return
}
**referenceToViewController?.updateChaptersList()**
}
}
答案 0 :(得分:0)
我在didSelectRow函数中看到的唯一问题,即
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
chaptersClass = ChaptersClass()
**viewController = ViewController()**
switch row {
case 0:
chaptersClass.chaptersList = chaptersClass.chaptersList0
case 1:
chaptersClass.chaptersList = chaptersClass.chaptersList1
case 2:
chaptersClass.chaptersList = chaptersClass.chaptersList2
default:
return
}
viewController.chapterPickerView.reloadAllComponents()
}
是,为什么要初始化一个新的ViewController。看,主要的问题是你刚刚初始化了ViewController类,但是没有将它添加到你的视图层次结构中,所以从不调用ViewDidLoad,这将进一步导致chapterClass中的chaplist到nil,因为它从未设置过。
我认为您希望使用已存在于视图层次结构中的相同viewcontroller实例,因为您需要使用委托或其他方法来通知您已存在的viewcontroller实例。我要把这部分留给你了。我认为这将解决您的问题。