我想使用一个单独的类的实例作为我的UITableView的数据源&代表。我创建了一个应该处理这个角色的类的新实例,并通过我的tableview属性分配它:
autoMakesTable被定义为property:
var autoMakesTable : UITableView?
再向下:
func nextBttnTouched(sender: AnyObject) {
switch self.autoState {
case .NewOrEdit:
self.autoState = .YearEntered
// If the picker wasn't used create a new Auto with the default year value
self.auto = Auto(year: NSNumber(integerLiteral: self.yearPickerValues.count - 2), make: "", model: "", body: "", trim: "", downPaymentBudget: 0, monthlyPaymentBudget: 0)
// Prepare the make & model fields
backgroundFieldView = UIView(frame: CGRectMake(0, 0-self.view.frame.size.height/2, self.view.frame.width, self.view.frame.height/2))
backgroundFieldView!.backgroundColor = UIColor(red: 251/255, green: 251/255, blue: 251/255, alpha: 1.0)
let makeField = UITextField(frame: CGRectMake(self.view.center.x - 100, self.navigationController!.navigationBar.frame.size.height + 34, 200, 30))
makeField.delegate = self
makeField.placeholder = "Make"
makeField.addTarget(self, action: Selector("makeTextChanged:"), forControlEvents: UIControlEvents.EditingChanged)
let modelField = UITextField(frame: CGRectMake(self.view.center.x - 100, makeField.frame.origin.y + makeField.frame.size.height + 8, 200, 30))
modelField.placeholder = "Model"
let newAutoMakesTableData = AutoMakesTableData()
autoMakesTable = UITableView(frame: CGRectMake(makeField.frame.origin.x, makeField.frame.origin.y + makeField.frame.height + 2, makeField.frame.width, 100))
autoMakesTable!.dataSource = newAutoMakesTableData
autoMakesTable!.delegate = newAutoMakesTableData
self.backgroundFieldView?.addSubview(self.autoMakesTable!)
self.autoMakesTable!.reloadData()
makeField.becomeFirstResponder()
self.addBorderToTextField([makeField,modelField])
self.view.addSubview(backgroundFieldView!)
// Move year picker with animation
// Update next button location while loading make / model input fields with animation
UIView.animateWithDuration(0.8, animations: { () -> Void in
self.newYearPicker?.frame.origin.y = 0
self.backgroundFieldView!.frame.origin.y = 0
self.backgroundFieldView!.addSubview(makeField)
self.backgroundFieldView?.addSubview(modelField)
//self.backgroundFieldView?.addSubview(self.autoMakesTable!)
// self.autoMakesTable!.reloadData()
})
case .YearEntered:
self.autoState = .MakeModelEntered
case .MakeModelEntered:
self.autoState = .DetailsEntered
case .DetailsEntered:
self.autoState = .BudgetEntered
case .BudgetEntered:
performSegueWithIdentifier("next", sender: self)
}
}
稍后将其添加到视图层次结构中(我完整地看到一个带有几行的空表视图)。我也尝试对它调用reloadData()无效。
AutoMakesTableData的定义如下:
import UIKit
class AutoMakesTableData: NSObject, UITableViewDataSource, UITableViewDelegate {
// Auto makes URL
// This should be hosted online so changes can be made w/out having to re-submit the app
let urlForMakes = NSBundle.mainBundle().URLForResource("makes", withExtension: "JSON")
var autoMakes : [String]?
override init() {
super.init()
self.populateAutoMakesFromURL(urlForMakes!)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let aCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
print("cell created")
return aCell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("selected row")
}
private func populateAutoMakesFromURL(url: NSURL) {
do {
let jsonAutoMakesData = try NSData(contentsOfURL: url, options: NSDataReadingOptions.DataReadingMappedIfSafe)
do {
let jsonAutoMakes = try NSJSONSerialization.JSONObjectWithData(jsonAutoMakesData, options: NSJSONReadingOptions.MutableContainers) as! [String:[String]]
self.autoMakes = jsonAutoMakes["makes"]
// Sort array alphabetically
self.autoMakes?.sortInPlace(<)
} catch let error as NSError {
print(error.userInfo.debugDescription)
}
} catch let error as NSError {
print(error.userInfo.debugDescription)
}
}
}
我可以毫无问题地访问此实例上的autoMakes数组属性。
表视图显示但没有任何print语句触发(对于索引路径的单元格或者选择行的单元格)。
答案 0 :(得分:1)
我没有看到将表视图安装到视图层次结构中的任何位置。如果不将视图控制器安装到活动视图层次结构中,它将不会执行任何操作。
这是我猜测出了什么问题。
可以将单独的对象用作视图控制器的数据源/委托。
根据下面这个答案的讨论,结果问题是OP在一个方法中创建了他的AutoMakesTableData并将其分配给一个局部变量,但没有保存任何其他强引用。
当返回创建AutoMakesTableData对象的方法时,局部变量超出范围,对该对象没有更强的引用,并且它已被解除分配。 表视图的委托和dataSource属性很弱,因此在取消分配对象时会将其归零。表视图不再具有数据源,因此没有任何反应。