0

I have a list view in my app and I'm adding there the cells dynamically. For each cell I want to attach a segue and thanks to it open a UIViewController (called FullUser) when user presses the cell (that UIViewController will contain the data passed by this segue, fetched from the specific cell chosen by user, stored in a structure called SingleUser). So I have this method:

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

and then:

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

but I'm getting error and when I'm checking it in debugger I see that user2 is nil. Why so? I want to store there a SingleUser object, so how can I pass it there?

user3766930
  • 5,629
  • 10
  • 51
  • 104
  • The docs don't seem super clear on whether these `sender` parameters are the same in both instances. I would try using the `dynamicType` property to check these types while you are working to check your assumptions. Try `print("Sender Type \(sender.dynamicType)")` where your comment is. – JMFR Mar 21 '16 at 21:12
  • Let me know if the answer in this question helps: http://stackoverflow.com/questions/35849931/getting-object-for-tapped-uitableviewcell-in-new-uiview/35850088 – Andre M Mar 21 '16 at 21:12
  • 2
    Is the `user` variable not `nil` before you perform the segue? – Victor Sigler Mar 21 '16 at 21:15
  • ok so this is super weird, I just put a random `print` right at the beginning of function `override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { ` and nothing is printed out when I tap each cell... – user3766930 Mar 21 '16 at 21:18
  • What you'll probably find is that your tableView() function is being called after prepareForSegue() function, so you'll need to do your work in the prepareForSegue() function. This is the approach I indicate in the answer of my other post. – Andre M Mar 21 '16 at 21:20
  • 1
    Not sure if this helps, but I believe if you have an actionSegue connected to your cell in the storyboard, didSelectCell will not be called. If you want to call segues manually, you should connect the segue to the ViewController rather than the cell. – GetSwifty Mar 21 '16 at 22:44

2 Answers2

0

Move the logic into the prepareForSegue() function and then set the property on the destination view controller. Note if the destinationViewController is not of the class you expect it to be, then you should check in the view controller settings in your storyboard.

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!
    }
}
Andre M
  • 6,649
  • 7
  • 52
  • 93
  • I did what you suggested, but then xcode showed me an error here: `self.items[path.row] as?...` saying: `Value of optional type 'NSIndexPath?' not unwrapped; did you mean to use '!' or '?'?` I put there `path!`, but then I'm getting nil when I try to fetch anything from user... so I guess the problem might be now with this `path`... – user3766930 Mar 21 '16 at 21:37
  • I added a `print(username)` just above the last line of your code and I got `optional("someUserLogin")` - that looks good for me, but why I cannot set it as you suggested in last line? Instead I'm getting `fatal error: unexpectedly found nil while unwrapping an Optional value` – user3766930 Mar 21 '16 at 21:40
  • for the `fullRequestDetails!.username.text` line? If so see if username is defined. If it isn't then you should define it or maybe change the property to be fullRequestDetails!.text, as you see appropriate. – Andre M Mar 21 '16 at 21:59
0

I would suggest you add a user property on your FullUser class and update your UI when your user is set, so it'd look something like this:

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

Then your prepareForSegue implementation can become a lot simpler. I would also suggest unwrapping the optionals in the if instead of using force unwrap (you should avoid force unwrapping ! as much as you can)

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let fullUserDetails = segue.destinationViewController as? FullUser,
    user = sender as? SingleUser {
        fullRequestDetails.user = user
    }
}
EmilioPelaez
  • 18,758
  • 6
  • 46
  • 50
  • Thanks! It almost works... I managed to open the new viewController, so the segue worked, but when I added some random print right after this: `func configureView() { guard let user = user where isViewLoaded() else { return }` then I didn't see it, therefore none of my labels has been set... Is there anything that I could potentially missed? – user3766930 Mar 21 '16 at 22:30
  • It is even more weird for me because when I put `print(user?.username)` in the `didset` block then I got the value `Optional("someUserLogin")` in my console, so the data is transferred correctly, but somehow later something goes wrong... – user3766930 Mar 21 '16 at 22:43
  • Try checking the values of `user` and `isViewLoaded()` before the guard. `print(user, isViewLoaded())`. Also, make sure you are calling `configureView()` on `viewDidLoad()`, see the explanation in the code I posted. – EmilioPelaez Mar 21 '16 at 23:29