在 ViewController 中连接 TableView - self.tableView.reloadData() 在 Swift 中不起作用
Connecting TableView within ViewController - self.tableView.reloadData() not working in Swift
我是学习 iOS 和 Swift 的新手,所以提前致歉。目前我正在尝试在 viewController 中设置一个 tableView 并在屏幕的一部分的单元格中显示数据。我当前的问题似乎是在为 numberOfRowsInSection() 调用 viewDidLoad() 中的 Alamofire HTTP 请求后重新加载 tableView 数据。这是代码:
import UIKit
import Alamofire
import SwiftyJSON
class CourseDetailViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var titleLabel: UILabel?
@IBOutlet weak var creditsLabel: UILabel?
@IBOutlet weak var descriptionLabel: UILabel?
@IBOutlet weak var tableView: UITableView!
var detailCourse: Course? {
didSet {
configureView()
}
}
var course: Course!
func configureView() {
self.title = detailCourse?.abbr
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "SectionCell")
tableView.delegate = self
tableView.dataSource = self
if let theCourse: Course = self.detailCourse as Course! {
var abbr: String = theCourse.abbr!
APIService.getCourseByAbbr(abbr) { (data) -> Void in
self.course = Course(courseJSON: data)
// Set labels
self.titleLabel?.text = self.course.title!
self.descriptionLabel?.text = self.course.description!
if let creditsArray = self.course.credits {
let minimumCredit = creditsArray[0] as Int
self.creditsLabel?.text = String(minimumCredit)
}
self.tableView.reloadData()
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return course.sections.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Configure the cell...
let cell = tableView.dequeueReusableCellWithIdentifier("SectionCell", forIndexPath: indexPath) as! SectionTableViewCell
let sectionCell = course.sections[indexPath.row]
cell.termLabel?.text = sectionCell.term
cell.timeLabel?.text = sectionCell.startTime
cell.instructorLabel?.text = sectionCell.instructor
return cell
}
}
当我 运行 时,出现以下错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
我认为原因可能是我在 viewController 中设置的 tableView 不正确。
对于完整的项目,这里是 link 到 repo:https://github.com/classmere/app/tree/develop
问题是您正在尝试解包一个值为 nil 的可选值。当你声明课程 属性 时,因为它是可选的,所以它的初始值为 nil。通常,可选值是用 ?
声明的,编译器会在不检查值是否仍然是 nil
的情况下阻止您访问基础值。然而,在这种情况下,您已将课程 属性 设置为预期的可选课程:
var course: Course!
这就像在说 "I know that course
will always have a value and will never be nil
"。但是我们不知道,因为它的值为 nil
,直到 Alamofire 回调成功完成。
要解决此问题,请先将 course
设为标准可选:
var course: Course?
现在 Xcode 会抱怨您正在访问 course
而不打开它,因为您对 course
的声明不再打开它。
通过强制展开 Alamofire 回调中的所有内容来解决此问题:
APIService.getCourseByAbbr(abbr) { (data) -> Void in
println("APIService()")
self.course = Course(courseJSON: data)
// Notice we can access self.course using ! since just assigned it above
self.titleLabel?.text = self.course!.title!
self.descriptionLabel?.text = self.course!.description!
if let creditsArray = self.course!.credits {
let minimumCredit = creditsArray[0] as Int
self.creditsLabel?.text = String(minimumCredit)
}
self.tableView.reloadData()
}
然后在 cellForRowAtIndexPath
中,我们将使用可选链接来确保我们只访问 course
存在的属性:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Configure the cell...
let cell = tableView.dequeueReusableCellWithIdentifier("SectionCell", forIndexPath: indexPath) as! SectionTableViewCell
if let section = course?.sections[indexPath.row] {
cell.termLabel?.text = section.term
cell.timeLabel?.text = section.startTime
cell.instructorLabel?.text = section.instructor
}
return cell
}
最后在 numberOfRowsForSection
中确保获得实际的部分数量而不是总是 returning 50。如果 course
是 nil
:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return course?.sections.count ?? 0
}
这应该可以解决您的问题!
我是学习 iOS 和 Swift 的新手,所以提前致歉。目前我正在尝试在 viewController 中设置一个 tableView 并在屏幕的一部分的单元格中显示数据。我当前的问题似乎是在为 numberOfRowsInSection() 调用 viewDidLoad() 中的 Alamofire HTTP 请求后重新加载 tableView 数据。这是代码:
import UIKit
import Alamofire
import SwiftyJSON
class CourseDetailViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var titleLabel: UILabel?
@IBOutlet weak var creditsLabel: UILabel?
@IBOutlet weak var descriptionLabel: UILabel?
@IBOutlet weak var tableView: UITableView!
var detailCourse: Course? {
didSet {
configureView()
}
}
var course: Course!
func configureView() {
self.title = detailCourse?.abbr
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "SectionCell")
tableView.delegate = self
tableView.dataSource = self
if let theCourse: Course = self.detailCourse as Course! {
var abbr: String = theCourse.abbr!
APIService.getCourseByAbbr(abbr) { (data) -> Void in
self.course = Course(courseJSON: data)
// Set labels
self.titleLabel?.text = self.course.title!
self.descriptionLabel?.text = self.course.description!
if let creditsArray = self.course.credits {
let minimumCredit = creditsArray[0] as Int
self.creditsLabel?.text = String(minimumCredit)
}
self.tableView.reloadData()
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return course.sections.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Configure the cell...
let cell = tableView.dequeueReusableCellWithIdentifier("SectionCell", forIndexPath: indexPath) as! SectionTableViewCell
let sectionCell = course.sections[indexPath.row]
cell.termLabel?.text = sectionCell.term
cell.timeLabel?.text = sectionCell.startTime
cell.instructorLabel?.text = sectionCell.instructor
return cell
}
}
当我 运行 时,出现以下错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
我认为原因可能是我在 viewController 中设置的 tableView 不正确。
对于完整的项目,这里是 link 到 repo:https://github.com/classmere/app/tree/develop
问题是您正在尝试解包一个值为 nil 的可选值。当你声明课程 属性 时,因为它是可选的,所以它的初始值为 nil。通常,可选值是用 ?
声明的,编译器会在不检查值是否仍然是 nil
的情况下阻止您访问基础值。然而,在这种情况下,您已将课程 属性 设置为预期的可选课程:
var course: Course!
这就像在说 "I know that course
will always have a value and will never be nil
"。但是我们不知道,因为它的值为 nil
,直到 Alamofire 回调成功完成。
要解决此问题,请先将 course
设为标准可选:
var course: Course?
现在 Xcode 会抱怨您正在访问 course
而不打开它,因为您对 course
的声明不再打开它。
通过强制展开 Alamofire 回调中的所有内容来解决此问题:
APIService.getCourseByAbbr(abbr) { (data) -> Void in
println("APIService()")
self.course = Course(courseJSON: data)
// Notice we can access self.course using ! since just assigned it above
self.titleLabel?.text = self.course!.title!
self.descriptionLabel?.text = self.course!.description!
if let creditsArray = self.course!.credits {
let minimumCredit = creditsArray[0] as Int
self.creditsLabel?.text = String(minimumCredit)
}
self.tableView.reloadData()
}
然后在 cellForRowAtIndexPath
中,我们将使用可选链接来确保我们只访问 course
存在的属性:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Configure the cell...
let cell = tableView.dequeueReusableCellWithIdentifier("SectionCell", forIndexPath: indexPath) as! SectionTableViewCell
if let section = course?.sections[indexPath.row] {
cell.termLabel?.text = section.term
cell.timeLabel?.text = section.startTime
cell.instructorLabel?.text = section.instructor
}
return cell
}
最后在 numberOfRowsForSection
中确保获得实际的部分数量而不是总是 returning 50。如果 course
是 nil
:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return course?.sections.count ?? 0
}
这应该可以解决您的问题!