2014-09-28 19 views
28

Tôi có hai bộ điều khiển chế độ xem và hai chế độ xem. Trong giao diện đầu tiên của tôi, tôi đặt biến 'currentUser' thành false. Tôi cần có thể đặt 'currentUser' thành true trong bộ điều khiển chế độ xem thứ hai.Gửi dữ liệu với Segue bằng Swift

Khi cố gắng tham chiếu 'currentUser' từ chế độ xem thứ hai, nó sẽ không chọn nó khi 'currentUser' được xác định trong bộ điều khiển xem đầu tiên.

Làm cách nào để thực hiện các biến có phân tách?

Trả lời

49

Set giá trị từ bất kỳ ViewController để One Second sử dụng segues

Như thế này:

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

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

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

Và trong lớp yourNextViewController của bạn.

class yourNextViewControllerClass { 

    var value:Int! // or whatever 

Bạn có thể gọi đây là cũng cách lập trình:

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

Set giá trị từ DestinationViewController của bạn trở lại Chính (First) ViewController

1. Thực hiện một giao thức, ví dụ tạo một tệp có tên protocol.swift.

protocol changeUserValueDelegate { 
     func changeUser(toValue:Bool) 
    } 

2. thiết lập các đại biểu vào View thứ hai của bạn

class yourNextViewControllerClass { 

    var delegate:changeUserValueDelegate? 

3. thiết lập các đại biểu trên tải (prepareForSegue)

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

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

4. add Chức năng để FirstViewController

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

5. cuộc gọi chức năng này từ SecondViewController bạn

 delegate?.changeUser(true) 

6. Đặt các đại biểu trong FirstViewController bạn

class FirstViewController: UIViewController, ChangeUserValueDelegate { 
+0

Tôi không thể sử dụng chức năng cho kiến ​​thức của mình, tôi cần thực hiện điều này trong câu lệnh 'if'. Xin lỗi vì không làm cho nó rõ ràng hơn. – AlexCatch

+0

Với 2 phương pháp này, bạn có thể gửi dữ liệu từ Bộ điều khiển Xem thứ nhất đến thứ hai và từ phương thức thứ hai của bạn đến lần đầu tiên. Nó không phải là một vấn đề để gọi điều này trong một tuyên bố "nếu". – derdida

+0

Tôi đã thử phương pháp đầu tiên, tôi không thể sử dụng chức năng ghi đè trong câu lệnh if, biến không được tìm thấy trong bộ điều khiển chế độ xem thứ hai. – AlexCatch

1

Thêm một thuộc tính currentUserSecondVC trong bộ điều khiển xem đích, và sử dụng 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 
    } 
} 
12

Vấn đề ở đây là biến số currentUser của bạn thuộc loại Bool, là loại giá trị. Vì vậy, chuyển nó từ bộ điều khiển xem đầu tiên của bạn đến bộ điều khiển xem thứ hai của bạn sẽ thực tế tạo ra một cá thể Bool mới. Những gì bạn cần là để vượt qua một tham chiếu từ bộ điều khiển xem đầu tiên của bạn để điều khiển xem thứ hai của bạn (xem Value and Reference Types để biết thêm chi tiết về giá trị và tham chiếu với Swift).

Do đó, tùy theo nhu cầu/sở thích của bạn, bạn có thể chọn một trong số ba ví dụ sau.


1. Các đấm bốc kiểu

Ở đây, chúng tôi "hộp" của chúng tôi Bool bên trong một lớp và thông qua một tài liệu tham khảo về điều đó thể hiện lớp với bộ điều khiển xem thứ hai.

1.1. Tạo một lớp CurrentUser:

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

1,2. Tạo một lớp con UIViewController cho bộ điều khiển xem đầu tiên:

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. Tạo một lớp con UIViewController cho bộ điều khiển xem thứ hai:

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. Việc đóng cửa phong cách

Ở đây, chúng ta có được một tài liệu tham khảo yếu của điều khiển xem đầu tiên của chúng tôi trong một đóng cửa và vượt qua đóng cửa này để bộ điều khiển xem thứ hai.

2.1. Tạo một lớp con UIViewController cho bộ điều khiển xem đầu tiên:

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. Tạo một lớp con UIViewController cho bộ điều khiển xem thứ hai:

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. Phong cách giao thức-đại biểu

Ở đây, chúng ta thực hiện điều khiển xem đầu tiên của chúng tôi phù hợp với một số giao thức và vượt qua một tham chiếu yếu nó vào bộ điều khiển xem thứ hai.

3.1. Tạo giao thức tùy chỉnh:

protocol MyDelegate: class { 
    func changeValue() 
} 

3.2. Tạo một lớp con UIViewController cho bộ điều khiển xem đầu tiên và làm cho nó phù hợp với các giao thức theo thời gian:

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.Tạo một lớp con UIViewController cho bộ điều khiển xem thứ hai:

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

} 
+1

Câu trả lời hay với đoạn mã tuyệt vời. Điều này cung cấp thêm 2 cách để đối phó với việc gửi dữ liệu so với câu trả lời của derdida. –

0

Chức năng đó phải được định nghĩa là ghi đè lên là:

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

Vì bạn đang sử dụng cùng một biến qua hai Viewcontrollers, cụ thể là CurrentUser (gõ Bool).

Vì vậy, tốt hơn nên biến nó thành biến toàn cầu trong cả hai lớp.

Khi đến khái niệm biến toàn cầu nhanh chóng.

Tất cả mọi thứ theo mặc định trong nhanh chóng là công khai, và do đó nếu bạn khai báo một cái gì đó như thế này:

class FirstViewController: UIViewController { 

    var someVariable: Boll = YES 

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

Bạn có thể truy cập vào nó và thiết lập các giá trị như miễn là bạn có một thể hiện của nó:

var MySecondViewController: FirstViewController = FirstViewController(nibName: nil, bundle: nil) 
var getThatValue = MySecondViewController.someVariable 
Các vấn đề liên quan