【问题标题】:Retrieving firebase data of a tableview cell to a view controller's label将 tableview 单元格的 firebase 数据检索到视图控制器的标签
【发布时间】:2016-05-10 09:38:38
【问题描述】:

我喜欢一个带有新闻源的社交应用。如果您从新闻源中的帖子中单击用户名,您将转到他的个人资料。现在我无法从该特定单元格/帖子中检索数据到另一个视图控制器。 所以我必须显示用户的个人资料,他的用户名等,但这不起作用?

我有一个 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 来执行 segue。 在我的 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 的错误:线程 1: EXC_BAD_ACCESS(code=1, address = 0x1)

【问题讨论】:

  • 如何将数据传递给视图控制器。你在用prepareForSegue吗?
  • 我更新了我的代码 :) 它尝试将 prepareForSeque 与destinationController 一起使用,但这也给了我一个错误..

标签: ios swift firebase label tableview


【解决方案1】:

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

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

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

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

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

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

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

更新:

我不确定您为什么要为此添加点击手势识别器,您可以使用didSelectRowAtIndexPath,看看其他question and answer

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

更新二:

在 op 私下分享他们的代码后,我注意到问题是用户在 tableView 中使用了 tapGestureRecognser。我在被调用的函数中添加了一些代码来获取包含被点击视图的行,一旦我有了 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
        }
    }
}

【讨论】:

  • vc.post = post // 你的第二个帖子是什么?是不是像帖子:帖子!或 var post = [Post]() 我现在正在尝试创建和呈现视图控制器
  • 是的,我使用它是因为我在一个单元格中有 3 个可点击的东西。一个按钮,一个 profileImage 和一个配置文件用户名标签。所以我使用 tapGestureRecognizer 来点击 profileImg 和 usernameLbl .. 我尝试了你的第二个选项,但是我的导航栏和标签栏消失了。用户名标签也只是空的。虽然我确实在 mij profileVC 中说 username.text =post.username
  • 如果我打印这个,它仍然给我一个零。
  • prepare for segue 方法应该适合你,我用过很多次类似的方法。如果您可以在 github 上或私下分享代码,我会看看并为您找到问题。
  • 如何私下发送? :)
猜你喜欢
  • 2017-06-29
  • 1970-01-01
  • 2018-04-25
  • 2021-09-12
  • 1970-01-01
  • 2019-05-23
  • 2023-03-23
  • 1970-01-01
  • 2017-07-27
相关资源
最近更新 更多