New Data Not Updating after Unwind Segue Performed

2019-09-11 06:42发布

问题:

I'm relatively new to Swift and am stumbling on this problem that is likely very simple to fix, I just can't figure it out and keep hitting a brick wall.

I'm making an app where a user taps an image in a collection view controller and it performs an unwind segue back to the main view controller and updates a uiimageview with the image that the user selected. I got the unwind segue to work but the problem is that the uiimageview is always one image behind (i.e. I select image A, unwind segue back and no image displays, so I select image B unwind segue back and then the original image I selected the first time, image A, is in the uiimageview).

Here is the code for the destination view controller (main view controller where I want the uiimageview to update based on the image selected in the collection view)...

 @IBAction func unwindToVC(segue:UIStoryboardSegue) {
    if(segue.sourceViewController .isKindOfClass(FrancoCollectionCollectionViewController))
    {
        let francoCollectionView:FrancoCollectionCollectionViewController = segue.sourceViewController as! FrancoCollectionCollectionViewController
        let selectedImageFromLibrary = selectedFranco
        dragImage!.image = UIImage(named: selectedImageFromLibrary)
    }

On the collection view controller where the user selects the image and it unwinds back, I just ctrl + dragged the cell to "exit" on the storyboard and selected the unwindToVC segue.

As far as my collection view here is how I have that set up, since I have a suspiscion it's related to the didSelectItemAtIndexPath part of it but I'm not sure...

    override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of items
    return francoPhotos.count 
}

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! FrancoCellCollectionViewCell

    // sets each cell of collection view to be a uiimage view of francoPhotos

    let image = UIImage(named: francoPhotos[indexPath.row])
    cell.francoImageCell.image = image

    return cell
}

    // highlights cell when touched 
    override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        selectedFranco = francoPhotos[indexPath.row]
        let cell = collectionView.cellForItemAtIndexPath(indexPath)
        cell!.layer.borderWidth = 3.0
        cell!.layer.borderColor = UIColor.blueColor().CGColor

}
    override func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
        let cell = collectionView.cellForItemAtIndexPath(indexPath)
        cell!.layer.borderWidth = 0.0
        cell!.layer.borderColor = UIColor.clearColor().CGColor
    }

Sorry if I posted way too much code but this is my first post and like I said I'm new to development, so I figured it would be better to include a little extra rather than not have something that is needed.

Any advice is greatly appreciated!

Thanks so much!!! :)

回答1:

This is happening because collectionView:didSelectItemAtIndexPath: is called after the segue is triggered. So, it is always one behind.

One way to fix this is to call the unwind segue programmatically with performSegueWithIdentifier instead of wiring it from the cell to the exit. To do this, wire your exit segue from the viewController icon (left most icon) at the top of your viewController to the exit icon (right most icon).

Find this segue in the Document Outline view and give it an identifier such as "myExitSegue" in the Attributes Inspector on the right. Then in didSelectItemAtIndexPath, the last thing to do is to call performSegueWithIdentifier("myExitSegue", sender: self).



回答2:

Here's what I would do:

Remove the code in the source VC unwind action for an empty unwind segue like so (the logic for displaying the new image will be put in the collection VC):

@IBAction func unwindToVC(segue: UIStoryboardSegue) {
}

Give your unwind segue a string identifier so that you may perform the segue programmatically not automatically. Here, I just called mine "Unwind".

Then, inside of FrancoCollectionCollectionViewController put a property to hold the selected UIImage:

var selectedFranco: UIImage!

Within didSelectItemAtIndexPath set the property to the selected image and then manually perform the segue:

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    // ... 
    self.selectedFranco = francoPhotos[indexPath.row]
    self.performSegueWithIdentifier("Unwind", sender: self)
}

Then I would add the prepareForSegue method in your FrancoCollectionCollectionViewController to set the source view controller's image to the selected image:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "Unwind" {
        let sourceVC = segue.destinationViewController as! YourSourceViewController
        sourceVC.dragImage.image = selectedImageView.image
    }
}