UIPickerView:从另一个 swift 文件重新加载所有组件
UIPickerView: Reload all components from another swift file
我的 ViewController 中有 2 个 UIPickerView。每个选择器视图都有一个单独的 swift 文件,用作选择器的数据源和委托。我希望第二个 pickerView 中的行数取决于第一个 pickerView 中选择的行。当我尝试在第一个 pickerView 的 "didSelect" 函数中实现它时,出现错误:"unexpectedly found nil while unwrapping an Optional value"
这是我的代码:
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 的建议的帮助下更新了我的代码。我目前没有收到任何错误,但 "chapters" pickerView 由于某种原因仍未更新。谁能指出我做错了什么?
注意:我修改了 "ViewController.swift" 和 "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()**
}
}
我在您的 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 class,但还没有将它添加到视图层次结构中,因此永远不会调用 ViewDidLoad,这将进一步导致 chaptersClass 中的 chaptersList 为 nil,因为它从未被设置。
我想你想使用相同的 viewcontroller 实例,它已经存在于你的视图层次结构中,因为你需要使用委托或其他一些方式来通知你的 viewcontroller 实例,它已经存在出现在那里。我把这部分留给你。我想这会解决你的问题。
我的 ViewController 中有 2 个 UIPickerView。每个选择器视图都有一个单独的 swift 文件,用作选择器的数据源和委托。我希望第二个 pickerView 中的行数取决于第一个 pickerView 中选择的行。当我尝试在第一个 pickerView 的 "didSelect" 函数中实现它时,出现错误:"unexpectedly found nil while unwrapping an Optional value"
这是我的代码:
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 的建议的帮助下更新了我的代码。我目前没有收到任何错误,但 "chapters" pickerView 由于某种原因仍未更新。谁能指出我做错了什么?
注意:我修改了 "ViewController.swift" 和 "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()**
}
}
我在您的 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 class,但还没有将它添加到视图层次结构中,因此永远不会调用 ViewDidLoad,这将进一步导致 chaptersClass 中的 chaptersList 为 nil,因为它从未被设置。
我想你想使用相同的 viewcontroller 实例,它已经存在于你的视图层次结构中,因为你需要使用委托或其他一些方式来通知你的 viewcontroller 实例,它已经存在出现在那里。我把这部分留给你。我想这会解决你的问题。