IOS - Cách phân biệt lập trình bằng swift


185

Tôi đang tạo một ứng dụng sử dụng SDK Facebook để xác thực người dùng. Tôi đang cố gắng hợp nhất logic facebook trong một lớp riêng biệt. Đây là mã (tước cho đơn giản):

import Foundation

class FBManager {
    class func fbSessionStateChane(fbSession:FBSession!, fbSessionState:FBSessionState, error:NSError?){
        //... handling all session states
        FBRequestConnection.startForMeWithCompletionHandler { (conn: FBRequestConnection!, result: AnyObject!, error: NSError!) -> Void in

            println("Logged in user: \n\(result)");

            let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
            let loggedInView: UserViewController = storyboard.instantiateViewControllerWithIdentifier("loggedInView") as UserViewController

            loggedInView.result = result;

            //todo: segue to the next view???
        }
    }
}

Tôi đang sử dụng phương thức lớp trên để kiểm tra các thay đổi trạng thái phiên và nó hoạt động tốt.

H: Khi tôi có dữ liệu của người dùng, làm cách nào tôi có thể phân biệt chế độ xem tiếp theo trong lớp tùy chỉnh này?

EDIT: để rõ ràng, tôi có một segue với định danh trên bảng phân cảnh và tôi đang cố gắng tìm cách để thực hiện một segue từ một lớp không phải là trình điều khiển xem


2
Giống như performSegue:?
ĐÃ

Có, nhưng mã không có trong viewContoder, làm thế nào tôi có thể đạt được điều này?
Shlomi Schwartz

Chà, trong trường hợp đó, bạn nên ủy thác công việc đó (cách ly) từ đối tượng bạn thực hiện công việc vào bộ điều khiển xem (thông qua khối hoàn thành hoặc phương thức ủy nhiệm).
ĐÃ

nhận được một ngoại lệ bố cục không phải là con số không
Chris Hayes

Câu trả lời:


340

Nếu segue của bạn tồn tại trong bảng phân cảnh với một định danh segue giữa hai chế độ xem của bạn, bạn có thể gọi nó bằng lập trình bằng cách sử dụng:

performSegue(withIdentifier: "mySegueID", sender: nil)

Đối với phiên bản cũ hơn:

performSegueWithIdentifier("mySegueID", sender: nil)

Bạn cũng có thể làm:

presentViewController(nextViewController, animated: true, completion: nil)

Hoặc nếu bạn đang ở trong bộ điều khiển Điều hướng:

self.navigationController?.pushViewController(nextViewController, animated: true)

7
Cảm ơn bạn đã trả lời, làm cách nào tôi có thể gọi PerformanceSegueWithIdentifier từ một lớp tùy chỉnh không phải là dạng xem?
Shlomi Schwartz

2
Nếu tôi sử dụng phương pháp thứ hai của bạn. Làm thế nào để truyền dữ liệu cho chế độ xem tiếp theo?
iamprem

2
Bạn sẽ sử dụng func ChuẩnForSegue (segue: UIStoryboardSegue, sender: AnyObject?) Và đặt các thuộc tính.
Lloyd Sargent

1
Lưu ý khi gọi PerformanceSequeWithIdentifer (), việc triển khai readyForSeque () trong bộ điều khiển cuộc gọi của bạn sẽ được gọi và bạn có thể thực hiện nhiều dữ liệu khác nhau ở đó - trên thực tế, tham số người gửi nhận được trong ChuẩnForSeque () chỉ đơn giản là những gì được truyền cho tham số người gửi trong biểu diễnSequeWithIdentifier ()
timbo

1
Điều gì xảy ra nếu segue không tồn tại trong bảng phân cảnh? Ví dụ: nếu bạn muốn tạo một segue cho chính ViewContoder?
đáng sợ

20

Bạn có thể sử dụng NSNotification

Thêm một phương thức bài trong lớp tùy chỉnh của bạn:

NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)

Thêm một người quan sát trong ViewContoder của bạn:

NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOFReceivedNotication:", name:"NotificationIdentifier", object: nil)

Thêm chức năng trong bạn ViewContoder:

func methodOFReceivedNotication(notification: NSNotification){
    self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)
}

1
Xin đừng lạm dụng thông báo như thế này. Sử dụng một ủy nhiệm và làm cho kết nối giữa trình điều khiển xem và lớp của bạn rõ ràng. Gần như không thể quan sát luồng kiểm soát của thông báo, bởi vì có thể có nhiều người đăng ký và các trường hợp có thể đăng ký / hủy đăng ký theo ý muốn.
uliwitness

17

Nếu segue của bạn tồn tại trong bảng phân cảnh với một định danh segue giữa hai chế độ xem của bạn, bạn có thể gọi nó bằng lập trình bằng cách sử dụng

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

Nếu bạn đang ở trong bộ điều khiển Điều hướng

let viewController = YourViewController(nibName: "YourViewController", bundle: nil)        
self.navigationController?.pushViewController(viewController, animated: true)

Tôi sẽ đề nghị bạn cho cách tiếp cận thứ hai bằng cách sử dụng bộ điều khiển điều hướng.


14

Bạn có thể sử dụng segue như thế này:

self.performSegueWithIdentifier("push", sender: self)
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if segue.identifier == "push" {

    }
}

Cảm ơn bạn đã trả lời, tuy nhiên performSegueWithIdentifier là một phương pháp viewController, và mã chạy của tôi trong một lớp bên ngoài
Shlomi Schwartz

13

Swift 3 - Cũng hoạt động với SpriteKit

Bạn có thể sử dụng NSNotification .

Thí dụ:

1.) Tạo một segue trong bảng phân cảnh và đặt tên cho định danh là "segue"

2.) Tạo một hàm trong ViewContoder mà bạn đang phân tách.

func goToDifferentView() {

    self.performSegue(withIdentifier: "segue", sender: self)

}

3.) Trong ViewDidLoad () của ViewContoder của bạn, bạn đang tách biệt khỏi việc tạo trình quan sát.

NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: "segue" as NSNotification.Name, object: nil)

Cập nhật - Lần cuối tôi sử dụng, tôi phải thay đổi .addObservercuộc gọi thành mã sau để tắt các lỗi.

NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: NSNotification.Name(rawValue: "segue"), object: nil)

4.) Trong ViewContoder hoặc Cảnh bạn đang phân tách, hãy thêm Phương thức Đăng bất cứ nơi nào bạn muốn kích hoạt phân tách.

NotificationCenter.default.post(name: "segue" as NSNotification.Name, object: nil)

Cập nhật - Lần cuối tôi sử dụng, tôi phải thay đổi .postcuộc gọi thành mã sau để tắt các lỗi.

NotificationCenter.default.post(NSNotification(name: NSNotification.Name(rawValue: "segue"), object: nil) as Notification)

Swift 3:NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: NSNotification.Name(rawValue: "segue"), object: nil)
Michael Samoylov

3

Những gì bạn muốn làm là thực sự quan trọng để thử nghiệm đơn vị. Về cơ bản, bạn cần tạo một hàm cục bộ nhỏ trong trình điều khiển khung nhìn. Đặt tên cho chức năng bất cứ điều gì, chỉ cần bao gồm performSegueWithIndentifier.

func localFunc() {
    println("we asked you to do it")
    performSegueWithIdentifier("doIt", sender: self)
}

Tiếp theo thay đổi lớp tiện ích của bạn FBManagerđể bao gồm một trình khởi tạo lấy một đối số của hàm và một biến để giữ chức năng của ViewContoder thực hiện phân tách.

public class UtilClass {

    var yourFunction : () -> ()

    init (someFunction: () -> ()) {
        self.yourFunction = someFunction
        println("initialized UtilClass")
    }

    public convenience init() {
        func dummyLog () -> () {
            println("no action passed")
        }
        self.init(dummyLog)
    }

    public func doThatThing() -> () {
        // the facebook login function
        println("now execute passed function")
        self.yourFunction()
        println("did that thing")
    }
}

(Init tiện lợi cho phép bạn sử dụng điều này trong thử nghiệm đơn vị mà không cần thực hiện segue.)

Cuối cùng, nơi bạn có // todo: segue cho chế độ xem tiếp theo ???, đặt một cái gì đó dọc theo dòng:

self.yourFunction()

Trong các bài kiểm tra đơn vị của bạn, bạn chỉ cần gọi nó là:

let f = UtilClass()
f.doThatThing()

trong đó doThatThing là fbsessionstatechange của bạn và UtilClasslà FBManager.

Đối với mã thực tế của bạn, chỉ cần chuyển localFunc(không có dấu ngoặc đơn) cho lớp FBManager.


2

Điều này làm việc cho tôi.

Trước hết, cung cấp cho trình điều khiển chế độ xem trong bảng phân cảnh của bạn một ID Storyboard bên trong trình kiểm tra danh tính. Sau đó sử dụng mã ví dụ sau (đảm bảo lớp, tên bảng phân cảnh và ID bảng câu chuyện khớp với những mã bạn đang sử dụng):

let viewController:
UIViewController = UIStoryboard(
    name: "Main", bundle: nil
).instantiateViewControllerWithIdentifier("ViewController") as UIViewController
// .instantiatViewControllerWithIdentifier() returns AnyObject!
// this must be downcast to utilize it

self.presentViewController(viewController, animated: false, completion: nil)

Để biết thêm chi tiết, hãy xem http://sketchytech.blogspot.com/2012/11/instantiate-view-controll-USE.html lời chúc tốt đẹp nhất


1

Bạn có thể làm điều này bằng cách sử dụng performSegueWithIdentifierchức năng.

Ảnh chụp màn hình

Cú pháp:

func performSegueWithIdentifier(identifier: String, sender: AnyObject?)

Thí dụ :

 performSegueWithIdentifier("homeScreenVC", sender: nil)

1

Một lựa chọn khác là sử dụng phương thức segue

BƯỚC 1: Chuyển đến bảng phân cảnh và cung cấp cho Trình điều khiển Chế độ xem ID . Bạn có thể tìm nơi thay đổi ID bảng phân cảnh trong Trình kiểm tra danh tính ở bên phải. Hãy gọi ID bảng phân cảnhModalViewController

BƯỚC 2: Mở trình điều khiển xem 'người gửi' (hãy gọi nó ViewController) và thêm mã này vào nó

public class ViewController {
  override func viewDidLoad() {
    showModalView()
  }

  func showModalView() {
    if let mvc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as? ModalViewController {
      self.present(mvc, animated: true, completion: nil)
    }
  }
}

Lưu ý rằng Trình điều khiển xem mà chúng tôi muốn mở cũng được gọi là ModalViewController

BƯỚC 3: Để đóng ModalViewCont kiểm soát, hãy thêm nó vào nó

public class ModalViewController {
   @IBAction func closeThisViewController(_ sender: Any?) {
      self.presentingViewController?.dismiss(animated: true, completion: nil)
   }
}

0

Điều này làm việc cho tôi:

//Button method example
 @IBAction func LogOutPressed(_ sender: UIBarButtonItem) {

        do {
            try Auth.auth().signOut()
            navigationController?.popToRootViewController(animated: true)

        } catch let signOutError as NSError {
          print ("Error signing out: %@", signOutError)
        }


    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.