将 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
}
}
}
我喜欢一个带有新闻源的社交应用程序。如果您在新闻源中单击 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
}
}
}