【问题标题】:Passing an object between view controllers在视图控制器之间传递对象
【发布时间】:2018-06-22 00:17:27
【问题描述】:

最近我一直在开发一个新应用程序,但我正在努力在视图控制器之间传递数据。

我使用一个视图控制器,它包含一个容器视图,我在其中使用谷歌地图。正如你们中的一些人所知,在谷歌地图上放置一个按钮是不可能的,因为它覆盖了所有内容(这就是为什么我把它作为一个容器视图)。现在我遇到了一个问题,我无法制作可以performSegue 的操作按钮,而且我也未能通过NotificationCenter 传递对象。我制作了一个名为 Song 的模型,我想将歌曲 List 传递给其他控制器(表格视图)。

类歌曲{
var sid: 字符串
var songName: 字符串
var 艺术家 ID:字符串
变量长度:字符串
var songImage:字符串?
var 专辑:字符串
var lastUpdate:日期?
}

对于在 VC 之间移动此列表有何想法或建议? 但是,这些视图之间没有真正的联系,mainVC 将它们都作为容器保存。

【问题讨论】:

  • 我正在寻找不包括 segues 的快速解决方案。遗憾的是,您引用我的这篇文章中不存在此信息。 segue 很棒,但谷歌地图让它变得不可能或者我错过了什么?

标签: ios swift uitableview uiviewcontroller uicontainerview


【解决方案1】:

所以你的 MainController 拥有两个必须交换数据的控制器?方法是使用 Delegate 模式并设置控制器之间的弱关系:

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

另一种选择:通过块建立连接。这是一种更现代、更快捷的方式:

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

请注意,上面的代码片段只是说明,您有很多方法可以访问控制器、设置委托或块。

【讨论】:

  • 非常感谢。我对 swift 很陌生,所以如果我能得到一些小解释,看看我是否理解你的话。 segue 的 prepre 正在等待一个动作?喜欢点击按钮?谁是“发件人”?或者它基本上可以在没有发送者的情况下工作,然后我可以从函数中返回一个歌曲列表?
  • 如果您使用故事板来布局您的 UI,这很重要。当您将场景放置在故事板中时,您将它们与转场联系起来。有一个特定的 Container 关系,允许您在场景中呈现多个 ViewController。在 segue 执行之前,它必须自己准备,所以它调用了prepare() 函数。在这种特殊情况下,它将在 viewDidLoad 之后但在 viewWillAppear 之前执行,并且发送者将是主视图控制器本身。如果您将 VC 放置在没有情节提要的情况下,那就更简单了——您必须手动实例化它们。
  • 好的伟人真的很佩服耐心。我仍然认为我错过了一些东西。有了您的建议/示例,我是否需要进行 preformsegue ?或者它们之间的连接是否足够,并且发送者在 viewdidload 时正在加载。我问这个是因为谷歌地图是不同的视图,并且我使用的功能是在我预先设置函数后在 300m 距离内给我标记我想将此详细信息传递给作为独立视图控制器的 playlistVC。这些观点之间没有任何联系。因此,在执行此功能后,如何将我在 mapVC 中创建的歌曲列表加载到 playlistVC
  • 只是为了清楚“发件人”,我的意思是当 prepre 函数被调用而不进行 preform segue 时?移动到另一个视图时?
猜你喜欢
  • 2020-06-07
  • 1970-01-01
  • 1970-01-01
  • 2018-07-03
  • 1970-01-01
  • 2015-09-10
  • 1970-01-01
  • 1970-01-01
  • 2012-07-19
相关资源
最近更新 更多