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 实例,它已经存在出现在那里。我把这部分留给你。我想这会解决你的问题。