IOS - Hızlı kullanarak programlı olarak nasıl segue edilir


185

Kullanıcıların kimliğini doğrulamak için Facebook SDK'sını kullanan bir uygulama oluşturuyorum. Facebook mantığını ayrı bir sınıfta birleştirmeye çalışıyorum. İşte kod (basitlik için soyulmuş):

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

Oturum durumu değişikliklerini kontrol etmek için yukarıdaki sınıf yöntemini kullanıyorum ve iyi çalışıyor.

S: Kullanıcının verilerini aldıktan sonra, bu özel sınıfın içinden bir sonraki görünüme nasıl geçebilirim?

EDIT: sadece net olmak için, film şeridi üzerinde tanımlayıcı ile bir segue var ve görünüm denetleyicisi olmayan bir sınıftan bir segue gerçekleştirmek için bir yol bulmaya çalışıyorum


2
Gibi performSegue:mi?
HAS

Evet, ancak kod viewController'da değil, bunu nasıl başarabilirim?
Shlomi Schwartz

Bu durumda, bu çalışmayı (segueing) çalıştığınız nesneden görünüm denetleyicisine (bir tamamlama bloğu veya bir temsilci yöntemi aracılığıyla) devretmeniz gerekir.
HAS

Nil düzeni olmayan bir istisna alıyorum
Chris Hayes

Yanıtlar:


340

Segue'iniz film şeridinde iki görünümünüz arasında bir segue tanımlayıcıyla varsa, bunu kullanarak programlı olarak çağırabilirsiniz:

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

Eski sürümler için:

performSegueWithIdentifier("mySegueID", sender: nil)

Ayrıca şunları da yapabilirsiniz:

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

Veya bir Gezinti denetleyicisindeyseniz:

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

7
Cevabınız için teşekkürler, performSegueWithIdentifier'ı görünüm olmayan özel bir sınıftan nasıl çağırabilirim?
Shlomi Schwartz

2
İkinci yönteminizi kullanırsam. Veriler bir sonraki görünüme nasıl aktarılır?
iamprem

2
Func preparForSegue (segue: UIStoryboardSegue, sender: AnyObject?) Kullanır ve özelliklerini ayarlarsınız.
Lloyd Sargent

1
PerformSequeWithIdentifer () çağrılırken, çağrı denetleyicinizde bir preparForSeque () uygulaması çağrılır ve oradan geçen çeşitli veriler yapabilirsiniz - aslında, preparForSeque () 'de alınan gönderen parametresi yalnızca performSequeWithIdentifier ()
timbo

1
Film şeridinde segue yoksa ne olur? Örneğin, ViewController için bir segue oluşturmak mı istiyorsunuz?
scaryguy

20

NSNotification kullanabilirsiniz

Özel sınıfınıza bir gönderi yöntemi ekleyin:

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

ViewController'ınıza bir gözlemci ekleyin:

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

ViewController'da fonksiyon ekleyin:

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

1
Lütfen bunun gibi bildirimleri kötüye kullanmayın. Bir temsilci kullanın ve görünüm denetleyicisi ile sınıfınız arasındaki bağlantıyı açık yapın. Bir bildirimin kontrol akışını gözlemlemek neredeyse imkansızdır, çünkü birden fazla abone olabilir ve örnekler istediği zaman abone olabilir / aboneliği iptal edebilir.
uliwitness

17

Segue'iniz film şeridinde iki görünümünüz arasında bir segue tanımlayıcıyla varsa, bunu kullanarak programlı olarak arayabilirsiniz.

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

Gezinti denetleyicisindeyseniz

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

Gezinti denetleyicisini kullanarak ikinci bir yaklaşım önereceğim.


self.performSegue (withIdentifier: "yourIdentifierInStoryboard", gönderen: self)
Rajneesh071

14

Segue'i şu şekilde kullanabilirsiniz:

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

    }
}

Yanıt için teşekkürler, ancak performSegueWithIdentifier bir viewController yöntemidir ve kodum harici bir sınıfta çalışır
Shlomi Schwartz

13

Swift 3 - SpriteKit ile de çalışır

NSNotification kullanabilirsiniz .

Misal:

1.) Film şeridinde bir segue oluşturun ve tanımlayıcıya "segue" adını verin.

2.) ViewController içinde aradığınız bir fonksiyon oluşturun.

func goToDifferentView() {

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

}

3.) ViewController'ınızın ViewDidLoad () öğesinde gözlemciyi oluşturmayı tercih edersiniz.

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

Güncelleme - Bunu en son kullandığımda .addObserverhataları susturmak için çağrıyı aşağıdaki koda değiştirmek zorunda kaldım .

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

4.) Segmen istediğiniz ViewController veya Scene'de, Post Metodunu seguein tetiklenmesini istediğiniz yere ekleyin.

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

Güncelleme - Bunu en son kullandığımda .posthataları susturmak için çağrıyı aşağıdaki koda değiştirmek zorunda kaldım .

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

Ünite testi için yapmak istediğiniz şey gerçekten önemlidir. Temel olarak görünüm denetleyicisinde küçük bir yerel işlev oluşturmanız gerekir. Fonksiyona herhangi bir ad verin, sadece performSegueWithIndentifier.

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

Daha sonra yardımcı program sınıfınızı FBManager, bir işlev argümanı alan bir başlatıcı ve sekmeyi gerçekleştiren ViewController işlevini tutmak için bir değişken içerecek şekilde değiştirin .

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

(Kolaylık başlangıcı bunu segue yürütmeden birim testinde kullanmanızı sağlar.)

Son olarak, // todo: segue sonraki görünüme ??? sahip olduğunuz yerde, aşağıdaki satırlara bir şey koyun:

self.yourFunction()

Birim testlerinizde basitçe şu şekilde çağırabilirsiniz:

let f = UtilClass()
f.doThatThing()

Burada doThatThing sizin fbsessionstatechange ve UtilClassFBManager olduğunu.

Gerçek kodunuz localFunciçin FBManager sınıfına (parantez olmadan) geçmeniz yeterlidir.


2

Bu benim için çalıştı.

Her şeyden önce film şeridinizdeki görünüm denetleyicisine kimlik denetçisinin içinde bir Storyboard Kimliği verin. Ardından aşağıdaki örnek kodu kullanın (sınıf, film şeridi adı ve hikaye panosu kimliğinin kullandığınız kodlarla eşleştiğinden emin olun):

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)

Daha fazla ayrıntı için bkz. Http://sketchytech.blogspot.com/2012/11/instantiate-view-controller-using.html en iyi dileklerimle


1

Bu performSegueWithIdentifierişlevi fonksiyonu kullanarak yapabilirsiniz .

Ekran görüntüsü

Sözdizimi:

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

Misal :

 performSegueWithIdentifier("homeScreenVC", sender: nil)

1

Başka bir seçenek modal segue kullanmaktır

ADIM 1: Film şeridine gidin ve Görüntü Denetleyicisine bir Film şeridi kimliği verin . Film şeridi kimliğini nerede değiştireceğinizi sağdaki Kimlik Denetçisinde bulabilirsiniz. Film şeridi kimliğini arayalımModalViewController

ADIM 2: 'Gönderen' görünüm denetleyicisini açın (diyelim ViewController) ve bu kodu buna ekleyin

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

Açmak istediğimiz Görünüm Kontrolörünün de ModalViewController

ADIM 3: ModalViewController'ı kapatmak için buna ekleyin

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

0

Bu benim için çalıştı:

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


    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.