UIPickerView:从另一个swift文件中重新加载所有组件

时间:2016-09-26 08:52:34

标签: ios xcode7 uipickerview swift3

我的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()**
  }
} 

1 个答案:

答案 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实例。我要把这部分留给你了。我认为这将解决您的问题。