web-dev-qa-db-ja.com

Swiftを使用してSegueでデータを送信する

2つのView Controllerと2つのビューがあります。最初のビューでは、変数「currentUser」をfalseに設定しました。 2番目のView Controllerで「currentUser」をtrueに設定できる必要があります。

2番目のビューから「currentUser」を参照しようとすると、最初のビューコントローラーで「currentUser」が定義されているため、それを選択しません。

セグエを使用して変数間を移動するにはどうすればよいですか?

36
Alex Catchpole

セグエを使用して任意のViewControllerから2番目のViewControllerに値を設定

これと同様:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    if(segue.identifier == "yourIdentifierInStoryboard") {

        let yourNextViewController = (segue.destinationViewController as yourNextViewControllerClass)
        yourNextViewController.value = yourValue

そして、yourNextViewControllerクラスで。

class yourNextViewControllerClass {

    var value:Int! // or whatever

これはプログラムで呼び出すこともできます。

 self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)

DestinationViewControllerの値をプライマリ(最初の)ViewControllerに戻す

1。プロトコルを実装します。たとえば、protocol.Swiftというファイルを作成します。

    protocol changeUserValueDelegate {
       func changeUser(toValue:Bool)
    }

2。 2番目のビューにデリゲートを設定します

    class yourNextViewControllerClass {

    var delegate:changeUserValueDelegate?

ロード時にデリゲートを設定する(prepareForSegue)

    if(segue.identifier == "yourIdentifierInStoryboard") {

        var yourNextViewController = (segue.destinationViewController as yourNextViewControllerClass)
        yourNextViewController.delegate = self

4。 FirstViewControllerに関数を追加

    func changeUser(toValue:Bool) {
        self.currentUserValue = toValue
    }

5。 SecondViewControllerからこの関数を呼び出す

     delegate?.changeUser(true)

6。 FirstViewControllerにデリゲートを設定します

    class FirstViewController: UIViewController, ChangeUserValueDelegate {
56
derdida

ここでの問題は、currentUser変数がBool型であり、これが値型であることです。したがって、最初のView Controllerから2番目のView Controllerに渡すと、実際に新しいBoolインスタンスが作成されます。必要なのは、最初のView Controllerから2番目のView Controllerに参照を渡すことです(Swiftでの値と参照の詳細については、 Value and Reference Types を参照してください)。

それにより、ニーズ/好みに応じて、次の例のいずれかを選択できますthree


1.ボクシングスタイル

ここでは、クラス内にBoolを「ボックス化」し、そのクラスインスタンスの参照を2番目のView Controllerに渡します。

1.1。 CurrentUserクラスを作成します:

class CurrentUser {
    var someBooleanValue = true {
        didSet {
            print(someBooleanValue)
        }
    }
}

1.2。最初のView Controller用にUIViewControllerサブクラスを作成します:

import UIKit

class ViewController1: UIViewController {

    let currentUser = CurrentUser()

    override func viewDidLoad() {
        super.viewDidLoad()
        currentUser.someBooleanValue = false
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let viewController2 = segue.destinationViewController as? ViewController2 {
            viewController2.currentUser = currentUser
        }
    }

}

1.3。 2番目のView ControllerのUIViewControllerサブクラスを作成します:

import UIKit

class ViewController2: UIViewController {

    var currentUser: CurrentUser?

    // Link this IBAction to a UIButton or a UIBarButtonItem in the Storyboard
    @IBAction func toggleBoolean(sender: AnyObject) {
        if let currentUser = currentUser {
          currentUser.someBooleanValue = !currentUser.someBooleanValue
        }
    }

}

2.閉鎖スタイル

ここでは、クロージャー内の最初のView Controllerの弱い参照を取得し、このクロージャーを2番目のView Controllerに渡します。

2.1。最初のView Controller用にUIViewControllerサブクラスを作成します:

import UIKit

class ViewController1: UIViewController {

    var currentUser = true {
        didSet {
            print(currentUser)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        currentUser = false
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let viewController2 = segue.destinationViewController as? ViewController2 {
            let closureToPerform = { [weak self] in
                if let strongSelf = self {
                    strongSelf.currentUser = !strongSelf.currentUser
                }
            }
            viewController2.closureToPerform = closureToPerform
        }
    }

}

2.2。 2番目のView ControllerのUIViewControllerサブクラスを作成します:

import UIKit

class ViewController2: UIViewController {

    var closureToPerform: (() -> Void)?

    // Link this IBAction to a UIButton or a UIBarButtonItem in the Storyboard
    @IBAction func toggleBoolean(sender: AnyObject) {
        closureToPerform?()
    }

}

3.プロトコルデリゲートスタイル

ここでは、最初のView Controllerを何らかのプロトコルに適合させ、その弱い参照を2番目のView Controllerに渡します。

3.1。カスタムプロトコルを作成します:

protocol MyDelegate: class {
    func changeValue()
}

3.2。最初のView Controller用にUIViewControllerサブクラスを作成し、以前のプロトコルに準拠させます:

import UIKit

class ViewController1: UIViewController, MyDelegate {

    var currentUser = true {
        didSet {
            print(currentUser)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        currentUser = false
    }

    func changeValue() {
        currentUser = !currentUser
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let viewController2 = segue.destinationViewController as? ViewController2 {
            viewController2.delegate = self
        }
    }

}

3.3。 2番目のView ControllerのUIViewControllerサブクラスを作成します:

import UIKit

class ViewController2: UIViewController {

    weak var delegate: MyDelegate?

    // Link this IBAction to a UIButton or a UIBarButtonItem in the Storyboard
    @IBAction func toggleBoolean(sender: AnyObject) {
        delegate?.changeValue()
    }

}
15
Imanou Petit

目的のView Controllerに属性currentUserSecondVCを追加し、prepareForSegueを使用します

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "Name Of Your Segue" {
        var vc = segue.destinationViewController as NameOfTheSecondViewController
        vc.currentUserSecondVC = !currentUser //you can do whatever you want with it in the 2nd VC
    }
}
1
ielyamani

オーバーライドとして定義する必要がある関数は次のとおりです。

open func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if (segue.identifier == "Segue Name Defined In Storyboard") {
        //set the property of the designated view controller with the value you need
    }
}
0
Trombe

2つのViewcontrollersで同じ変数、つまりcurrentUser(Bool型)を使用しているためです。

したがって、両方のクラスでグローバル変数にする方が適切です。

Swiftのグローバル変数の概念に来るとき

Swiftのデフォルトではすべてがパブリックであるため、次のように宣言した場合:

class FirstViewController: UIViewController {

    var someVariable: Boll = YES

    init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }
}

インスタンスがある限り、アクセスして値を設定できます。

var MySecondViewController: FirstViewController = FirstViewController(nibName: nil, bundle: nil)
var getThatValue = MySecondViewController.someVariable
0
Saranjith