简体   繁体   中英

Passing an object between view controllers

Lately I have been working on a new app and I'm struggling to pass data between view controllers.

I use a view controller which holds a container view in which I use google maps. As some of you know it's impossible to put a button on google maps as it overlays everything (that why I put it as a container view). Now I got a problem that I can't make an action button that can performSegue and I also failed to pass an object with the NotificationCenter . I made a model called Song and I want to pass a song List to other controller (a table view).

class Song {
var sid: String
var songName: String
var artistId: String
var length: String
var songImage: String?
var album: String
var lastUpdate:Date?
}

Any ideas or suggestions to move this list between VCs? There is no real connection between those views though, the mainVC is holding them both as containers.

So you have MainController that own both of your controllers that had to exchange data? On way is to use Delegate pattern and setup weak relationsships between your controllers:

protocol SongSelectable {
    func songSelected(_ song: Song) 
}

class PlaylistController: UIViewController {
    weak var songSelectable: SongSelectable?
}

class MapController: UIViewController, SongSelectable {
    func songSelected(_ song: Song)  {
        //do your code
    }
}

class MainController: UIViewController {
   weak var mapController: MapController?
   weak var playlistController: PlaylistController?
   func prepare(for segue: UIStoryboardSegue, sender: Any?) {
       // You can't guaranty order here, so some duplication required
       if let controller = segue as? MapController {
           mapController = controller
           playlistController?.songSelectable = controller

       }
       else if let controller = segue as? PlaylistController {
           playlistController = controller 
           controller.songSelectable = mapController
       }
   }
}

Another option: establish connection via blocks. It is more modern and Swifty way:

typealias SongHandler = (Song)->()

class PlaylistController: UIViewController {
    var songHandler = SongHandler?
}

class MapController: UIViewController {
    func songSelected(_ song: Song)  {
        //do your code
    }
}

class MainController: UIViewController {
   weak var mapController: MapController?

   func prepare(for segue: UIStoryboardSegue, sender: Any?) {
       if let controller = segue as? MapController {
           mapController = controller
       }
       else if let controller = segue as? PlaylistController {
           controller.songHandler = { [unowned self] (song) in self.mapController?.songSelected(song)
       }
   }
}

Mind that code fragments above is just illustrations, you have plenty of ways to access controllers, setup delegation or blocks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM