将 tableview 单元格的 firebase 数据检索到视图控制器的标签

Retrieving firebase data of a tableview cell to a view controller's label

我喜欢一个带有新闻源的社交应用程序。如果您在新闻源中单击 post 中的用户名,您将转到他的个人资料。现在我无法将数据从那个特定的 cell/post 检索到另一个 viewController。 所以我必须显示用户的个人资料,以及他的用户名等,但这不起作用?

我有一个 Post 型号:

class Post {
    private var _postDescription: String!
    private var _profileImageURL: String?
    private var _likes: Int!
    private var _username: String!
    private var _postKey: String!
    private var _timeStamp: String!
    private var _postRef: Firebase!

    var postDescription: String? {
        return _postDescription
    }

    var likes: Int {
        return _likes
    }

    var username: String {
        return _username
    }

    var postKey: String {
        return _postKey
    }

    var profileImageURL: String? {
        return _profileImageURL
    }

    init(description: String, username: String, profileImageURL: String?) {
        self._postDescription = description
        self._username = username
        self._profileImageURL = profileImageURL
    }

    init(postKey: String, dictionary: Dictionary<String, AnyObject>) {
        self._postKey = postKey

        if let likes = dictionary["likes"] as? Int {
            self._likes = likes
        }

        if let desc = dictionary ["description"] as? String {
            self._postDescription = desc
        }

        if let imgUrl = dictionary["profileImg"] as? String {
            self._profileImageURL = imgUrl
        }

        if let user = dictionary ["username"] as? String {
            self._username = user
        } else {
            self._username = ""
        }

        self._postRef = DataService.ds.REF_POST.childByAppendingPath(self._postKey)
    }

} 

这是我的个人资料VC:

class ProfileVC: UIViewController {

    @IBOutlet weak var username: UILabel!

    var post: Post?

    override func viewDidLoad() {
        super.viewDidLoad()

            username.text = post.username // gives me a nil error.  
    }
}

并且我在我的 tableViewCell 中使用 TapGestureRecognizer 来执行转场。 在我的 cellForRowAtIndexPath:

let profileLblTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(NewsVC.goToProfileScreen(_:)))
        profileLblTapRecognizer.numberOfTapsRequired = 1
        profileLblTapRecognizer.delegate = self

    cell.usernameLabel.tag = indexPath.row
    cell.usernameLabel.userInteractionEnabled = true
    cell.usernameLabel.addGestureRecognizer(profileLblTapRecognizer)

和 goToProfileScreen 函数:

func goToProfileScreen(gesture: UITapGestureRecognizer) {
        self.performSegueWithIdentifier("ProfileScreen", sender: self)

    }

这是我在 firebase 上的数据模型:

更新:

我试过这个:

let profileLblTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(NewsVC.prepareForSegue(_:sender:)))

具有此功能:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "ProfileScreen" {
            if let cell = sender as? NewsCell, row = tableView.indexPathForCell(cell)?.row, vc = segue.destinationViewController as? ProfileVC {
                vc.post = posts[row]

            }

        }


    }

但这让我在 appDelegate 上出错:Thread 1: EXC_BAD_ACCESS(code=1, address = 0x1)

我将此添加为答案而不是评论,以便我可以添加和格式化一些代码示例。

当您调用 performSegueWithIdentifier 时,将创建一个由该 segue 标识的视图控制器的新实例,因此它的所有属性都将是它们的默认值。

您有两种方法可以在加载之前实例化此视图控制器和设置属性。第一个是 prepareForSegue 选项,在您的情况下它可能看起来像这样:

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if (segue.identifier == "ProfileScreen") {
        let vc = segue.destinationViewController as! ProfileVC
        vc.post = post
    }
}

另一种选择是自己创建和呈现视图控制器,此示例使用故事板 ID

let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = mainStoryboard.instantiateViewControllerWithIdentifier("profileVC") as! ProfileVC
vc.post = post

presentViewController(vc, animated: false, completion: nil)

更新:

我不确定你为什么要为此添加点击手势识别器,你可以使用 didSelectRowAtIndexPath,看看另一个

您可以在 table 视图控制器上有一个名为 selectedItem 或类似名称的 属性。然后在 didSelectRowAtIndexPath 中将 selectedItem 设置为当前索引处的项目。然后在准备 segue 时,您只需执行 vc.post = selectedItem

更新二:

在 op 私下分享他们的代码后,我注意到问题是用户在 tableView 中使用了 tapGestureRecogniser。我在被调用的函数中添加了一些代码以获取包含点击视图的行,一旦我有了 indexPath 就可以很容易地将它存储在临时 属性 中并稍后在 prepareForSegue 方法中检索,详情如下

// temp property
var selectedPost:Post?

// function called on tap
func viewProfile(sender:UITapGestureRecognizer) {

    if (sender.state == UIGestureRecognizerState.Ended) {
        let point = sender.locationInView(self.tableView)
        if let indexPath = self.tableView.indexPathForRowAtPoint(point) {
            selectedPost = self.posts[indexPath.row]
            performSegueWithIdentifier("ProfileScreen", sender: self)
        }
    }
}

// Prepare for segue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if (segue.identifier == "ProfileScreen") {
        let vc = segue.destinationViewController as! ProfileVC
        if let post = selectedPost {
            vc.post = post
        }
    }
}