【问题标题】:Why I can't cast the sender in my prepareForSegue method in swift?为什么我不能在我的 prepareForSegue 方法中快速转换发件人?
【发布时间】:2016-03-22 05:43:56
【问题描述】:

我的应用中有一个列表视图,我正在动态添加单元格。 对于每个单元格,我想附加一个segue,并感谢它在用户按下单元格时打开一个UIViewController(称为FullUser)(UIViewController 将包含此segue 传递的数据,从用户选择的特定单元格中获取,存储在一个名为SingleUser的结构。 所以我有这个方法:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    var cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath) as! SingleEventCell

    let user =  self.items[indexPath.row] as? SingleUser

    self.performSegueWithIdentifier("fullUserFromListSegue", sender: user)
    }

然后:

var fullUserDetails: FullUser?

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
     if (segue.identifier == "fullUserFromListSegue"){

        fullUserDetails = segue.destinationViewController as? FullUser

       //now I want to set the textfield on the other panel:

        let user2 =  sender as? SingleUser

        var username = user2?.username

        fullRequestDetails!.username.text = username!
    }
}

但是我遇到了错误,当我在调试器中检查它时,我看到 user2 为零。为什么这样?我想在那里存储一个SingleUser 对象,那么我怎样才能将它传递到那里呢?

【问题讨论】:

  • 文档似乎不太清楚这些sender 参数在两种情况下是否相同。在您检查假设时,我会尝试使用 dynamicType 属性来检查这些类型。试试print("Sender Type \(sender.dynamicType)") 你的评论在哪里。
  • 如果这个问题的答案有帮助,请告诉我:stackoverflow.com/questions/35849931/…
  • 在你执行segue之前user变量不是nil吗?
  • 好吧,这太奇怪了,我只是在函数override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 的开头放了一个随机的print,当我点击每个单元格时什么都没有打印出来......
  • 不确定这是否有帮助,但我相信如果你有一个 actionSegue 连接到故事板中的单元格,didSelectCell 将不会被调用。如果你想手动调用 segue,你应该将 segue 连接到 ViewController 而不是单元格。

标签: ios swift segue uistoryboardsegue


【解决方案1】:

将逻辑移到prepareForSegue() 函数中,然后在目标视图控制器上设置属性。请注意,如果 destinationViewController 不是您期望的类,那么您应该检查情节提要中的视图控制器设置。

var fullUserDetails: FullUser?

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // check the destintation view controller is of correct class        
    if let fullUserDetails = segue.destinationViewController as? FullUser {
        let path = self.tableView.indexPathForSelectedRow
        let user =  self.items[path.row] as? SingleUser

        var username = user?.username

        fullRequestDetails!.username.text = username!
    }
}

【讨论】:

  • 我按照你的建议做了,但是 xcode 在这里向我显示了一个错误:self.items[path.row] as?... 说:Value of optional type 'NSIndexPath?' not unwrapped; did you mean to use '!' or '?'? 我放在那里path!,但是当我尝试获取时我得到了 nil来自用户的任何东西......所以我想问题可能出在这个path......
  • 我在代码最后一行的上方添加了一个print(username),我得到了optional("someUserLogin") - 这对我来说看起来不错,但为什么我不能按照你在最后一行中的建议进行设置?相反,我得到fatal error: unexpectedly found nil while unwrapping an Optional value
  • 对于fullRequestDetails!.username.text 行?如果是这样,请查看是否定义了用户名。如果不是,那么您应该定义它,或者根据您认为合适的方式将属性更改为 fullRequestDetails!.text。
【解决方案2】:

我建议你在 FullUser 类上添加一个 user 属性,并在设置用户时更新你的 UI,所以它看起来像这样:

class FullUser: UIViewController {
    var user: SingleUser? {
        didSet {
            configureView()
        }
    }

    @IBOutlet weak var usernameField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        configureView() // Call configure in viewDidLoad because
        // your user might be set before the view is loaded
    }

    func configureView() {
        guard let user = user where isViewLoaded() else { return }
        usernameField.text = user.username
    }
}

那么你的prepareForSegue 实现会变得简单很多。我还建议展开 if 中的选项,而不是使用强制展开(你应该尽可能避免强制展开 !

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let fullUserDetails = segue.destinationViewController as? FullUser,
    user = sender as? SingleUser {
        fullRequestDetails.user = user
    }
}

【讨论】:

  • 谢谢!它几乎可以工作......我设法打开了新的 viewController,所以 segue 工作了,但是当我在此之后添加一些随机打印时:func configureView() { guard let user = user where isViewLoaded() else { return } 然后我没有看到它,因此我的标签都没有设置。 .. 有什么我可能错过的吗?
  • 这对我来说更奇怪,因为当我将 print(user?.username) 放入 didset 块中时,我在控制台中得到了值 Optional("someUserLogin"),因此数据被正确传输,但不知何故稍后出了点问题……
  • 尝试在警卫前检查userisViewLoaded() 的值。 print(user, isViewLoaded())。另外,请确保您在viewDidLoad() 上调用configureView(),请参阅我发布的代码中的说明。
猜你喜欢
  • 2020-04-22
  • 2014-08-02
  • 1970-01-01
  • 2017-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多