it-swarm.com.ru

IOS - Как программно переходить с помощью swift

Я создаю приложение, которое использует Facebook 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: просто чтобы прояснить, у меня есть переход с идентификатором на раскадровке, и я пытаюсь найти способ выполнить переход из класса, который не является контроллером представления

172
Shlomi Schwartz

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

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

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

performSegueWithIdentifier("mySegueID", sender: nil)

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

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

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

self.navigationController?.pushViewController(nextViewController, animated: true)
314
Jérôme Leducq

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

Добавьте метод post в свой пользовательский класс:

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)
}
20
Rodrigo Otero

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

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

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

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

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

14
Manish Mahajan

Вы можете использовать Segue, как это:

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

    }
}
14
Ricky

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

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

Пример:

1.) Создайте переход в раскадровке и назовите идентификатор "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 везде, где вы хотите, чтобы переход запускался.

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

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

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

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

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

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

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 позволяет использовать это в модульном тестировании без выполнения перехода.)

Наконец, где у вас есть // todo: segue to next view ???, поместите что-то вроде:

self.yourFunction()

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

let f = UtilClass()
f.doThatThing()

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

Для реального кода просто передайте localFunc (без скобок) в класс FBManager.

2
Bill

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

Screenshot

Синтаксис:

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

Пример:

 performSegueWithIdentifier("homeScreenVC", sender: nil)
1
Jayprakash Dubey

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

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

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 наилучшие пожелания

1
amdan