【问题标题】:swift custom uitextviewcell label always nil快速自定义 uitextviewcell 标签始终为零
【发布时间】:2015-02-07 02:20:20
【问题描述】:

我两天前就被困在这里,找不到如何管理这个.. 我有一个 uitableview,有一系列自定义单元格和部分,这就是我想要做的:

  • 第 1 部分:只有一行,里面有一个标签
  • 第 2 部分:日期选择器(为此我使用了 DVDatePickerTableViewCell 类)

这是表格视图的代码

import UIKit

class DettagliRichiestaTVC: UITableViewController {
    //sections contiene le sezioni
    let sections: NSArray = ["Stato", "Data", "Priorità", "Richiesta", "Risposta"]
    //cells contiene tutte le righe della tabella, un 2D array
    var cells:NSArray = []
    var stato:String = "Completato"
    @IBOutlet weak var statoLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
       // statoLabel.text = stato

        self.tableView.rowHeight = UITableViewAutomaticDimension
        self.tableView.estimatedRowHeight = 44

        // Cells is a 2D array containing sections and rows.
        var cellStato = cellDettagli(style: UITableViewCellStyle.Default, reuseIdentifier: "cellStato")
        cellStato.label?.text = "Ciao"
        cells = [
            [cellStato],
            [DVDatePickerTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: nil)]
        ]

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func selectedStato(segue:UIStoryboardSegue) {
        let statoRichiesteTVC = segue.sourceViewController as StatoRichiesteTVC
        if let selectedStato = statoRichiesteTVC.selectedStato {
            statoLabel.text = selectedStato
            stato = selectedStato
        }
        self.navigationController?.popViewControllerAnimated(true)
    }

    // MARK: - Table view data source


    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }
    */

    override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        var headerFrame:CGRect = tableView.frame


        var title = UILabel(frame: CGRectMake(10, 10, 100, 20))
        title.font = UIFont.boldSystemFontOfSize(12.0)
        title.text = self.sections.objectAtIndex(section) as? String
        title.textColor = UIColor(red: 0.6, green: 0.6, blue: 0.6, alpha: 1)

        var headerView:UIView = UIView(frame: CGRectMake(0, 0, headerFrame.size.width, headerFrame.size.height))
        headerView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.8)
        headerView.addSubview(title)

        return headerView
    }



    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        var cell = self.tableView(tableView, cellForRowAtIndexPath: indexPath)
        if (cell.isKindOfClass(DVDatePickerTableViewCell)) {
            return (cell as DVDatePickerTableViewCell).datePickerHeight()
        }
        return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
    }


    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return cells.count
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return cells[section].count
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        return cells[indexPath.section][indexPath.row] as UITableViewCell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        var cell = self.tableView(tableView, cellForRowAtIndexPath: indexPath)
        if (cell.isKindOfClass(DVDatePickerTableViewCell)) {
            var datePickerTableViewCell = cell as DVDatePickerTableViewCell
            datePickerTableViewCell.selectedInTableView(tableView)
        }
        self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }


    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        //println(segue.identifier)
        if segue.identifier == "SavePlayerDetail" {
        }
        if segue.identifier == "SelezionaStatoRichiesta" {
            let statoRichiesteTVC = segue.destinationViewController as StatoRichiesteTVC
            statoRichiesteTVC.selectedStato = stato
        }
    }

}

这是自定义单元格类

import UIKit

class cellDettagli: UITableViewCell {
    @IBOutlet weak var label: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    func loadItem(#Label: String) {
        label.text = Label
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }

    required init(coder aDecoder: NSCoder) {
        //fatalError("init(coder:) has not been implemented")
        super.init(coder: aDecoder)
    }


    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        // Configure the view for the selected state
    }

}

如果我设置 cellStato.label?.text = "Ciao" ,它会崩溃说“致命错误:在展开可选值时意外发现 nil”。

我还创建了 .xib 文件并将其分配给 cellDettagli 类。 我总是遇到这个错误。

如何设置此标签的值以及日期选择器行的日期?

谢谢

【问题讨论】:

  • 你为什么要创建一个单元格数组?
  • 表格由自定义单元格组成,在使用应用程序期间可能会发生变化。另外,我可能需要以同样的方式在其他情节提要中创建不同的相似表格..
  • 是的。但这些都不是创建存储单元数组的原因。您应该始终使用 tablviews dequeue 方法使单元格出列。这实际上是您在回答中所做的。顺便说一句,您的回答基本上忽略了我首先质疑的单元格数组。
  • 是的,我明白,在我的第二个答案中,我在没有数组的情况下这样做.. 但是.. 这样我需要在加载之前知道每个单元格.. 如果我不知道这些我该怎么办,但只知道它们的类/值,而不知道这些单元格的顺序或存在?
  • 这听起来像是在单元格中存储数据。你根本不应该那样做。就顺序而言,唯一重要的是数据。单元格没有任何顺序。事实上,细胞应该被重复使用,因此总是会不断变化。

标签: ios uitableview swift null


【解决方案1】:

我用这个使它工作:

var cell:cellDettagli? = tableView.dequeueReusableCellWithIdentifier("cellDettagli") as? cellDettagli
if  (cell==nil){
   var nib:NSArray=NSBundle.mainBundle().loadNibNamed("cellDettagli", owner: self, options: nil)
   cell = nib.objectAtIndex(0) as? cellDettagli
}

在我的 cellForRowAtIndexPath 中。

感谢亚历山大的帮助!我已经在使用静态单元格和情节提要...!

【讨论】:

    【解决方案2】:

    您正在使用指定的初始化程序创建单元格,这意味着您在 nib 中添加的视图在运行时将不存在。您需要先使用registerNib:forCellReuseIdentifier: 将您的笔尖注册到tableview,然后使用dequeueReusableCellWithIdentifier:forIndexPath: 相应地使单元格出列。

    https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/index.html

    由于您使用的是静态单元格,因此最好在表格视图中使用具有“静态单元格”内容类型的情节提要,而不是“动态原型”。

    有关静态单元格的更多信息,请参阅文档https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TableView_iPhone/CreateConfigureTableView/CreateConfigureTableView.html

    【讨论】:

    • Q 说的是 XIB,但类似的答案也适用,因为不需要加载 NIB
    • 对不起,但我无法理解您的答案的含义(我是新手程序员,对不起)所以,我添加了这个 self.tableView.registerNib(UINib(nibName: "cellDettagli", bundle: NSBundle.mainBundle()), forCellReuseIdentifier: "cellStato") 进入 viewDidLoad,然后在我的 UITableViewController 类中创建我的 var cellStato .. 但是,在哪里以及如何使该单元格出列?对不起,谢谢你的回答!
    • 另外,有没有更好的方法来实现我的需要?
    • 在回答您的第一条评论时,您将出列cellForRowAtIndexPath 内的单元格。在回答您的第二条评论时,是的,在情节提要中使用静态单元格适合您的需求。但是,如果您还没有在项目中使用故事板,那么这可能是一个太大的改变而无法实施。
    猜你喜欢
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 1970-01-01
    相关资源
    最近更新 更多