2つのView Controllerと2つのビューがあります。最初のビューでは、変数「currentUser」をfalseに設定しました。 2番目のView Controllerで「currentUser」をtrueに設定できる必要があります。
2番目のビューから「currentUser」を参照しようとすると、最初のビューコントローラーで「currentUser」が定義されているため、それを選択しません。
セグエを使用して変数間を移動するにはどうすればよいですか?
セグエを使用して任意の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 {
ここでの問題は、currentUser
変数がBool
型であり、これが値型であることです。したがって、最初のView Controllerから2番目のView Controllerに渡すと、実際に新しいBool
インスタンスが作成されます。必要なのは、最初のView Controllerから2番目のView Controllerに参照を渡すことです(Swiftでの値と参照の詳細については、 Value and Reference Types を参照してください)。
それにより、ニーズ/好みに応じて、次の例のいずれかを選択できますthree。
ここでは、クラス内に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
}
}
}
ここでは、クロージャー内の最初の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?()
}
}
ここでは、最初の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()
}
}
目的の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
}
}
オーバーライドとして定義する必要がある関数は次のとおりです。
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
}
}
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