【问题标题】:Segue using didSelectRowAtIndexPath使用 didSelectRowAtIndexPath 进行转场
【发布时间】:2015-03-01 18:01:37
【问题描述】:

我有一个核心数据项目的主从 VC 设置。如果searchBar 处于活动状态,则显示一组结果,如果未处于活动状态,则 fetchedResultsController 中的对象将显示在 MasterVC 中。

我一直在尝试使用 prepareForSegue 进行转场,但我的导师建议我使用 didSelectRowAtIndexPath 进行转场。

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

    // Check to see which table view cell was selected.
    if tableView == self.tableView {
        selectedNote = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Note // <--this is "everything"
    } else {
        // need this to unwrap the optional
        if let filteredObjects = filteredObjects {
            selectedNote = filteredObjects[indexPath.row]
        }
    }

    // Set up the detail view controller to show.
    let detailViewController = DetailViewController()
    detailViewController.detailDescriptionLabel = selectedNote.valueForKey("noteBody") as! UILabel

    // Note: Should not be necessary but current iOS 8.0 bug requires it.
    tableView.deselectRowAtIndexPath(tableView.indexPathForSelectedRow()!, animated: false)

    // original code
    navigationController?.pushViewController(detailViewController, animated: true)

}

我收到此编译器错误:

Variable 'selectedNote' used before being initialized--在方法顶部声明!

如果我像这样在selectedNote 之前添加"self"

    detailViewController.detailDescriptionLabel = self.selectedNote.valueForKey("noteBody") as! UILabel

'MasterViewController' does not have a member named 'selectedNote' 尽管在那里。所以我显然在搞砸一些事情。

我在let detailViewController = DetailViewController()lldb 之前放置了一个断点,它打印出正确的对象。我在这里四处寻找解决方案,但我做不到。我在 GitHub 上找不到适用的代码。

class Note: NSManagedObject {

    @NSManaged var dateCreated: NSDate
    @NSManaged var dateEdited: NSDate
    @NSManaged var noteTitle: String
    @NSManaged var noteBody: String

}

任何想法如何将selectedNote 的属性转发给detailViewController

更新:

根据我得到的回复,我已经用这段代码关闭了编译器警告:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    var selectedNote: Note?

    // Check to see which table view cell was selected.
    if tableView == self.tableView {
        selectedNote = self.fetchedResultsController.objectAtIndexPath(indexPath) as? Note // <--this is "everything"
    } else {
        // need this to unwrap the optional
        if let filteredObjects = filteredObjects {
            selectedNote = filteredObjects[indexPath.row]
        }
    }

    // Set up the detail view controller to show.
    let detailViewController = DetailViewController()

    detailViewController.detailDescriptionLabel.text = (selectedNote!.valueForKey("noteBody") as! String)

    // Note: Should not be necessary but current iOS 8.0 bug requires it.
    tableView.deselectRowAtIndexPath(tableView.indexPathForSelectedRow()!, animated: false)

    // original code
    navigationController?.pushViewController(detailViewController, animated: true)

}

但是当它崩溃时,我在控制台中得到了这个: There are already notes in the app fatal error: unexpectedly found nil while unwrapping an Optional value

但是,当我键入 po selectedObject 时,我单击的对象会显示在控制台中。

【问题讨论】:

    标签: ios swift core-data segue didselectrowatindexpath


    【解决方案1】:

    您需要像这样将 selectedNote 声明为可选:

      var selectedNote: Note?
    

    然后在使用之前检查值是否存在。

      if let note = selectedNote {
        // Set up the detail view controller to show.
        let detailViewController = DetailViewController()
        detailViewController.detailDescriptionLabel = note.valueForKey("noteBody") as! UILabel
    
        // Note: Should not be necessary but current iOS 8.0 bug requires it.
        tableView.deselectRowAtIndexPath(tableView.indexPathForSelectedRow()!, animated: false)            
        // original code
        navigationController?.pushViewController(detailViewController, animated: true)
      }
    

    更新

    问题是您正在尝试创建 DetailViewController

    let detailViewController = DetailViewController()
    

    但是您需要的是引用 DetailViewController 以便将信息传递给它。

    因此,您可以在 Interface builder 中创建从 Master 到 Detail 控制器的 segue。然后从 didSelectRowAtIndexPath

    中删除逻辑
     override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    
        // Note: Should not be necessary but current iOS 8.0 bug requires it.
        tableView.deselectRowAtIndexPath(tableView.indexPathForSelectedRow()!, animated: false)
    }
    

    并在prepareForSegue方法中实现:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    
        if segue.identifier == "showDetail" {
    
            if let cell = sender as? UITableViewCell {
    
                let indexPath = tableView.indexPathForCell(cell)!
    
                var selectedNote: Note?
    
                if filteredObjects?.count > 0 {
                    selectedNote = filteredObjects![indexPath.row]
                }else {
                    selectedNote = self.fetchedResultsController.objectAtIndexPath(indexPath) as? Note // <--this is "everything"
                }
    
                if let note = selectedNote {
    
                    let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController
                    controller.detailItem = note
                }
            }
        }
    }
    

    showDetail - 您需要在 IB 中设置的 segue 标识符。 var detailItem: AnyObject? - 你需要在 DetailViewController 中声明它。

    【讨论】:

    • 这是一个小小的进步。现在我明白了:There are already notes in the app Could not cast value of type '__NSCFString' (0x10f759c90) to 'UILabel' (0x110b1b968). 我在lldb 上做了po selectedNote,它返回了我选择的注释,但它崩溃了
    • 虽然这在技术上消除了编译器错误,但很有可能 selectedNote 没有被初始化,导致使用 selectedNote 时崩溃。您最好使用常规的可选... var selected注意:注意?
    • Adrian,看看这段代码:selectedNote.valueForKey("noteBody") as! UIL标签。你确定 selectedNote 包含 UILabel 吗?我猜它包含您想要放入 detailDescriptionLabel 的文本。在这种情况下,您需要转换为 NSString 而不是 UILabel?
    • 这是来自DetailVC的属性:@IBOutlet weak var detailDescriptionLabel: UILabel!
    • 我不知道 Note 类的内部结构,但我猜你想写的内容如下:detailViewController.detailDescriptionLabel.text = note.valueForKey("noteBody") as! NSString.
    猜你喜欢
    • 2014-07-18
    • 2018-05-11
    • 2011-12-12
    • 2012-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多