以非自身数据源&编程方式创建UITableView。代表

时间:2015-09-16 01:17:16

标签: ios uitableview swift2

我想使用一个单独的类的实例作为我的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语句触发(对于索引路径的单元格或者选择行的单元格)。

1 个答案:

答案 0 :(得分:1)

我没有看到将表视图安装到视图层次结构中的任何位置。如果不将视图控制器安装到活动视图层次结构中,它将不会执行任何操作。

这是我猜测出了什么问题。

可以将单独的对象用作视图控制器的数据源/委托。

编辑:

根据下面这个答案的讨论,结果问题是OP在一个方法中创建了他的AutoMakesTableData并将其分配给一个局部变量,但没有保存任何其他强引用。

当返回创建AutoMakesTableData对象的方法时,局部变量超出范围,对该对象没有更强的引用,并且它已被解除分配。 表视图的委托和dataSource属性很弱,因此在取消分配对象时会将其归零。表视图不再具有数据源,因此没有任何反应。