-1

I have this function, which is called when the user clicks on the image on the collectionView. There is a variable url (in the line print("IMAGE CLICKED:", url)) I want to send the value of the url to another viewController and set url in a UIImage.

Here is my unfinished function in the firstVC. From here I'd like to send the url to the secondVC.

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    selectedCommunity = (liveCommunities?[indexPath.row].communityId)!
    let home = HomeViewController()
    home.showCommunityDetail()

    //url is the source for a image in another viewController
    //TODO: Send url to other viewController
    //There is no relation between the thwo viewControllers (only via tabbar)

    print("--------")
    print("IMAGE CLICKED:", url)
    print("--------")

}

Is that possible? Thanks for your help in advance!

j10
  • 109
  • 11
  • I assume that there are *many* questions about this topic. https://stackoverflow.com/questions/24222640/passing-data-between-view-controllers-in-swift, https://stackoverflow.com/questions/29734954/how-do-you-share-data-between-view-controllers-and-other-objects-in-swift, https://stackoverflow.com/questions/25215476/how-do-you-pass-data-between-view-controllers-in-swift – Ahmad F Jul 06 '17 at 08:22
  • these questions are for viewControllers with segue, I don't have a segue. – j10 Jul 06 '17 at 08:25
  • Rx is really awesome for this https://github.com/ReactiveX/RxSwift create a stream (Observable) and pass it to both viewControllers on creation. Then post your url in the one and listen in the other. Can be a bit confusing to start with but its worth taking a look at. – sbarow Jul 06 '17 at 08:47

4 Answers4

1

You can do this easily via a custom notification. Set up an observer in the second view controller and post a notification with an userInfo containing the variable in the first one. You can easily handle the URL in the second view controller by retrieving the userInfo.

First view controller:

NotificationCenter.default.post(name: Notification.Name.init(rawValue: "imagePressed"), object: nil, userInfo: ["imageUrl": url])

Second view controller:

NotificationCenter.default.addObserver(self, selector: #selector(imagePressed(_:)), name: Notification.Name.init(rawValue: "imagePressed"), object: nil)

func imagePressed(_ notification: Notification) {
    let url = notification.userInfo!["imageUrl"] as! URL
} 
Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
  • I got this error: Could not cast value of type '__NSCFString' (0x1070424f0) to 'UIImage' (0x10b3dab30). – j10 Jul 06 '17 at 08:57
1

find some example here https://stackoverflow.com/a/24036067/8263682 how to create controller from storyboard if needed and present it (or you could push it)

// Swift 3.0
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "someViewController")
self.present(controller, animated: true, completion: nil)

This is how you could set image Url as property for it (or send as method parameter)

controller.url = url

But I see you have second controller in tab bar. So you could access it this way (see https://stackoverflow.com/a/25393586/8263682)

var svc:SecondViewController = self.tabBarController.viewControllers[1] as SecondViewController!
svc.url = url

Or use NotificationCenter.default.post... if you want

0

Yes you can. Use delegates. You can also post notifications and observe it in the previous controller. Please check this answer for using delegates. If you prefer to use Notifications, use this answer

Amal T S
  • 3,327
  • 2
  • 24
  • 57
0

As others mentioned in their answers, there are two mainstream ways we do this.There is sufficient literature on the internet about the usage of both. I will provide short explanations in my own words

Delegates

Delegation refers to the process of passing on a piece of work to some other object which is better suited to perform that task. You can go the delegate way given you have with you both the delegate and delegating object. In your case, the viewController with the collection view will be the delegating object where as the view controller that sets the image will be the delegate.

Basically you will need the following in the delegating viewcontroller.

  1. A 'protocol' which will include a method to pass the required information to the delegate object.

  2. A delegate object.

  3. A reference to the second view controller, which will be set as the delegate of the first viewcontroller.

  4. Call the method on the delegate wherever applicable.

In the delegate view controller

  1. You will have to confirm to the protocol declared earlier.
  2. Implement the required methods in the protocol.

Notifications

Notifications are more like broadcasts. You send out an app wide message that can be received and processed by any listeners. We use the NSNotification class for this. The information or the message will be captured in the NSNotification's userInfo object. Each notification is identified by a name.

The advantage of notifications is that you do not typically need to keep track or references of listeners. You just need to generate the payload data, publish a notification and be done with it. The notification can be listened to by any class and your information has the potential to be processed in any object that is alive give it is listening for it. This can become an advantage or a disadvantage.

Comparison

In my personal experience, working in large projects excessive use of Notifications combined with repeated unplanned patching in of changes and fixes eventually leads to unreadable & unmaintainable code. Delegation requires more planning and time to implement, but you always know who's doing what. That said these are two different tools and should be used as per the requirement.

humblePilgrim
  • 1,818
  • 4
  • 25
  • 47