IOS - Как перечислить программно, используя быстрый

Я создаю приложение, использующее SDK для проверки подлинности пользователей. Я пытаюсь консолидировать логику facebook в отдельном классе. Вот код (снятый для простоты):

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???
        }
    }
}

Я использую вышеуказанный метод класса для проверки изменений состояния сеанса, и он отлично работает.

Q: Как только я получу пользовательские данные, как я могу перейти к следующему представлению из этого пользовательского класса?

EDIT:, чтобы быть ясным, у меня есть segue с идентификатором на раскадровке, и я пытаюсь найти способ выполнить segue из класса, который не является контроллером представления

Ответ 1

Если ваш segue существует в раскадровке с идентификатором segue между двумя вашими представлениями, вы можете просто называть его программным путем, используя:

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

Для более старых версий:

performSegueWithIdentifier("mySegueID", sender: nil)

Вы также можете сделать:

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

Или, если вы находитесь в контроллере навигации:

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

Ответ 2

Вы можете использовать NSNotification

Добавьте почтовый метод в свой собственный класс:

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

Добавить наблюдателя в ViewController:

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

Добавить функцию в вас ViewController:

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

Ответ 3

Вы можете использовать segue следующим образом:

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

    }
}

Ответ 4

Если ваш сценарий существует в раскадровке с идентификатором перехода между двумя вашими представлениями, вы можете просто вызвать его программно, используя

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

Если вы находитесь в навигационном контроллере

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

Я порекомендую вас для второго захода с использованием навигационного контроллера.

Ответ 5

Swift 3 - Также работает с SpriteKit

Вы можете использовать NSNotification.

Пример:

1.) Создайте segue в раскадровке и назовите идентификатор "segue"

2.) Создайте функцию в ViewController, из которой вы переходите.

func goToDifferentView() {

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

}

3.) В ViewDidLoad() вашего ViewController вы отступаете от создания наблюдателя.

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

Обновить - В прошлый раз, когда я использовал это, мне пришлось изменить вызов .addObserver на следующий код, чтобы отключить ошибки.

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

4.) В ViewController или Scene, к которому вы переходите, добавьте метод Post, где бы вы не захотели, чтобы сгенерировался segue.

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

Обновить - В прошлый раз, когда я использовал это, мне пришлось изменить вызов .post на следующий код, чтобы отключить ошибки.

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

Ответ 6

То, что вы хотите сделать, действительно важно для модульного тестирования. В основном вам нужно создать небольшую локальную функцию в контроллере представления. Назовите функцию что угодно, просто включите performSegueWithIndentifier.

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

Затем измените свой класс утилиты FBManager, чтобы включить инициализатор, который принимает аргумент функции и переменную, чтобы удерживать функцию ViewController, выполняющую segue.

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

(Утилита удобства позволяет использовать это при модульном тестировании без выполнения сеанса.)

Наконец, где у вас есть //todo: segue для следующего представления???, поместите что-то вдоль строк:

self.yourFunction()

В ваших модульных тестах вы можете просто вызвать его как:

let f = UtilClass()
f.doThatThing()

где doThatThing - ваш fbsessionstatechange, а UtilClass - FBManager.

Для вашего фактического кода просто передайте localFunc (без скобок) в класс FBManager.

Ответ 7

Вы можете сделать это, используя функцию performSegueWithIdentifier.

Снимок экрана

Синтаксис:

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

Пример:

 performSegueWithIdentifier("homeScreenVC", sender: nil)

Ответ 8

Это сработало для меня.

Прежде всего, дайте контроллеру вида в вашем раскадровке идентификатор раскадровки внутри инспектора идентификации. Затем используйте следующий пример кода (убедитесь, что класс, имя раскадровки и идентификатор панели рассказов соответствуют тем, которые вы используете):

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)

Подробнее см. http://sketchytech.blogspot.com/2012/11/instantiate-view-controller-using.html наилучшие пожелания

Ответ 9

Другой вариант - использовать модальный переход

ШАГ 1: Перейдите к раскадровке и присвойте View Controller идентификатор раскадровки. Вы можете найти место для изменения идентификатора раскадровки в Identity Inspector справа. Позволяет назвать ID раскадровки ModalViewController

ШАГ 2: Откройте контроллер представления 'sender' (позвольте назвать его ViewController) и добавьте в него этот код

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

Обратите внимание, что View Controller, который мы хотим открыть, также называется ModalViewController

ШАГ 3: Чтобы закрыть ModalViewController, добавьте это в него

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