在没有 Segues 的 ViewController 之间传递数据

Posted

技术标签:

【中文标题】在没有 Segues 的 ViewController 之间传递数据【英文标题】:Pass data between ViewController without Segues 【发布时间】:2017-08-23 00:12:20 【问题描述】:

我是快速开发的新手,在理解如何在 ViewController 之间传递数据时遇到了一些问题。

我想构建一个简单的音乐播放器应用程序,它具有三个视图(PlayerPlaylistsTracks)。

在开始时,播放器会显示给用户。从那里,用户可以按下一个按钮,播放列表视图就会出现。现在他可以选择一个播放列表并显示下一个视图Tracks

如果他按下一个曲目,他会回到 Player 视图并且曲目正在播放。所以我需要将我的曲目传递给我的 PlayerViewController。

目前我正在使用 Segues 来显示每个 ViewController。 播放器 -> 播放列表 -> 曲目 -> 播放器

但这会再次初始化播放器,这意味着值/变量会被重置。我怎样才能避免这种情况?

【问题讨论】:

解释您如何从播放器到播放列表再到曲目(每个)。 我已经完成了一个类似的音乐播放器应用程序。我有许多本地音乐文件,我创建了一个音乐数组来保存音乐的 URL、标题、专辑、艺术家。播放列表视图是一个tableView,每一行包含一个音乐名称和专辑。当我单击单元格时,它将呈现playViewcontroller,并传递音乐的URL。 你如何展示下一个 ViewController?如果您不确定,请查看本指南。 developer.apple.com/library/content/featuredarticles/… @Stefan 目前我正在使用 segues 来显示下一个 ViewController;播放器 -> 播放列表 -> 曲目 -> 播放器;问题是,如果我再次从 segue 返回到 Player ViewController,所有更改的值都会被重置。 如果你以模态方式呈现下一个视图控制器,它下面的视图控制器将持续存在。 【参考方案1】:

如果您通过说 present 从视图控制器 B 到视图控制器 C,那么视图控制器 C 可以将视图控制器 B 作为其 presentingViewController 说话。

【讨论】:

【参考方案2】:

尝试使用 Unwind segues 传递数据,我想它们可以帮助你。

    An unwind segue (sometimes called exit segue) can be used to navigate 
    back through push, modal or popover segues (as if you popped the navigation
     item from the navigation bar, closed the popover or dismissed the modally
     presented view controller). On top of that you can actually unwind through
     not only one but a series of push/modal/popover segues, e.g. "go back"multiple steps in your navigation hierarchy with a single unwind action.When you perform an unwind segue, you need to specify an action, which is an action method of the view controller you want to unwind to.
        
//ViewControllerA:

import UIKit

class ViewControllerA: UIViewController 
    
    var dataRecieved: String? 
        willSet 
            labelOutlet.text = newValue
        
    
    
    @IBOutlet weak var labelOutlet:UILabel!
    @IBOutlet weak var nextButtonOutlet: UIButton!

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    
    
    @IBAction func nextButtonAction(_ sender:UIButton) 
        
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let controller = storyboard.instantiateViewController(withIdentifier: "ViewControllerB") as! ViewControllerB
        controller.dataPassed = labelOutlet.text
        self.present(controller, animated: true, completion: nil)
        
    

    // segue ViewControllerB -> ViewControllerA
    @IBAction func unwindToThisView(sender: UIStoryboardSegue) 
        if let sourceViewController = sender.source as? ViewControllerB 
            dataRecieved = sourceViewController.dataPassed
        
    



//ViewControllerB

import UIKit

class ViewControllerB: UIViewController , UITextFieldDelegate
    
    @IBOutlet weak var textFieldOutlet: UITextField!
    var dataPassed : String?

    override func viewDidLoad() 
        super.viewDidLoad()

        textFieldOutlet.text = dataPassed
  
        textFieldOutlet.delegate = self
    

    // UITextFieldDelegate
    func textFieldShouldReturn(_ textField: UITextField) -> Bool 
        // User finished typing (hit return): hide the keyboard.
        textField.resignFirstResponder()
        return true
    
    
    func textFieldDidEndEditing(_ textField: UITextField) 
        dataPassed = textField.text
    


//从Return Button点击控件并拖动退出viewcontrollerB,如图所示。

【讨论】:

希望对您有所帮助。【参考方案3】:

要在视图控制器之间传递数据,请在代码中包含此块:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    let feed = segue.destination as! SecondViewControllerName

    feed.variableinsecondviewcontroller = variableincurrentviewcontroller

如果这没有帮助,您可能需要详细说明您的代码到底想要什么...

【讨论】:

目前我在我的代码中使用这个方法。问题是,如果我从 segue 返回到 FirstViewController(播放器),所有更改的值都会被重置。 你可以做的是在你的 ViewController 中嵌入一个 View 来防止这种情况,或者创建另一个 segue 数据传输以返回到第一个 View Controller。希望有帮助!【参考方案4】:

使用 struct 类并在任何使用 stuct 对象的地方访问您的对象 像这样

struct SomeStruct var name: String init(name: String) self.name = name var aStruct = SomeStruct(name: "Bob") var bStruct = aStruct // aStruct 和 bStruct 是两个相同的结构体价值! bStruct.name = "Sue" println(aStruct.name) // "Bob" println(bStruct.name) // "Sue"

【讨论】:

以上是关于在没有 Segues 的 ViewController 之间传递数据的主要内容,如果未能解决你的问题,请参考以下文章

在没有 Segues 的故事板之间传递变量 - Swift

使用没有 Storyboard Segues 的 UIViewControllerAnimatedTransitioning

在没有Segues的故事板之间传递变量 - Swift

在 iOS 5 上使用 Segues/Storyboard 弹出当前视图

我无法向 segues 添加标识符。有没有办法修复 ios xamarin 故事板?

使用没有 segues 的协议将数组从 appDelegate 传递到 Viewcontroller