0

I have like a social app with a sort of newsfeed. if u click on the users name from a post in the newsfeed, you will go to his profile. Now i can't retrieve the data from that specific cell/post to the other viewController. so i have to display the user's profile, with he's username, etc. but that doesn't work?

i have a Post model:

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) } } 

this is my profileVC:

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. } } 

and i use a TapGestureRecognizer in my tableViewCell to perform the segue. in my 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) 

and the goToProfileScreen function:

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

this is my datamodel on firebase: enter image description here

UPDATE:

i tried this instead:

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

with this function:

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] } } } 

but that gave me an error on appDelegate: Thread 1: EXC_BAD_ACCESS(code=1, address = 0x1)

2
  • how are you passing the data to the view controller. are you using prepareForSegue? Commented May 10, 2016 at 9:56
  • i updated my code :) it tried to use prepareForSeque with destinationController but this also gives me an error.. Commented May 10, 2016 at 10:03

1 Answer 1

1

I've added this as an answer rather than a comment so that I can add and format some code examples.

When you call performSegueWithIdentifier, a NEW instance of the view controller identified by that segue is created, so all of its properties will be their defaults.

You have two ways of instantiating this view controller and setting properties before it loads. The first is the prepareForSegue option, in your case it may look something like this:

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

Another option is to create and present the view controller yourself, this example uses a storyboardID

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

Update:

I'm not sure why you are adding a tap gesture recogniser to this, you could just use didSelectRowAtIndexPath, have a look at this other question and answer

you could have a property on your table view controller called selectedItem or something similar. and then in didSelectRowAtIndexPath set selectedItem to the item at the current index. Then in prepare for segue you would just do vc.post = selectedItem

Update Two:

After the op sharing their code privately, I noticed that the issue is that the user is using tapGestureRecogniser in the tableView. I added some code into the called function to get the row in which contained the tapped view, once I had the indexPath it was then easy to store it in a temporary property and retreive later in the prepareForSegue method, details below

// 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 } } } 
Sign up to request clarification or add additional context in comments.

7 Comments

the vc.post = post // which is the second post for you? is it like post: Post! or var post = [Post]() i'm trying now with creating and presenting the view controller
yeah i use it because i have 3 clickable things in one cell. a button, and a profileImage and a profile username label. so i use tapGestureRecognizer for the click on the profileImg and usernameLbl.. i tried your second option but then my navigation bar and tabbar disappears. also the username label is just empty. while i do say in mij profileVC username.text =post.username
it still gives me a nil if i print this.
the prepare for segue method should work for you, i have used it in a similar way alot of times. if you could share the code on github or privately I will have a look and find the issue for you.
how can i send it privately? :)
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.