iOS-如何使用Swift快速编程


185

我正在创建一个使用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???
        }
    }
}

我正在使用上面的类方法来检查会话状态更改,并且工作正常。

问:获得用户数据后,如何在此自定义类中选择下一个视图?

编辑:为了清楚起见,我在情节提要上有一个带有标识符的segue,并且我试图找到一种从不是视图控制器的类中执行segue的方法


2
喜欢performSegue:吗?
2014年

是的,但是代码不在viewController中,如何实现呢?
Shlomi Schwartz 2014年

好吧,在这种情况下,您应该将工作(从工作对象中)委托给视图控制器(通过完成块或委托方法)。
HAS 2014年

获得非零布局异常
克里斯·海耶斯

Answers:


340

如果您的segue存在于情节提要中,并且在两个视图之间都有一个segue标识符,则可以使用以下方式以编程方式调用它:

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

对于旧版本:

performSegueWithIdentifier("mySegueID", sender: nil)

您也可以这样做:

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

或者,如果您在导航控制器中:

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

7
感谢您的答复,如何从不是视图的自定义类中调用performSegueWithIdentifier?
Shlomi Schwartz 2014年

2
如果我使用您的第二种方法。如何将数据传递到下一个视图?
iamprem 2015年

2
您将使用func prepareForSegue(segue:UIStoryboardSegue,sender:AnyObject?)并设置属性。
劳埃德·萨金特

1
请注意,在调用performSequeWithIdentifer()时,将在您的调用控制器中调用prepareForSeque()的实现,并且您可以在其中执行各种数据传递-实际上,在prepareForSeque()中接收到的sender参数就是在其中传递给sender参数的东西。 performSequeWithIdentifier()
timbo,2015年

1
如果故事板中不存在segue怎么办?例如,是否要为ViewController本身创建序列?
scaryguy16年

20

您可以使用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)
}

1
请不要滥用这样的通知。使用委托,使视图控制器与您的类之间的连接明确。观察通知的控制流几乎是不可能的,因为可能有多个订阅者,并且实例可以随意订阅/取消订阅。
uliwitness

17

如果情节提要存在于情节提要中,并且两个视图之间都有一个情节标识符,则可以使用以下方式以编程方式调用它:

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

如果您在导航控制器中

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

我将推荐您使用导航控制器的第二种方法。


self.performSegue(withIdentifier:“ yourIdentifierInStoryboard”,发送者:self)
Rajneesh071

14

您可以这样使用segue:

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

    }
}

感谢您的答复,但是performSegueWithIdentifier是viewController方法,我的代码在外部类中运行
Shlomi Schwartz

13

斯威夫特3 - 还与SpriteKit工作

您可以使用NSNotification

例:

1.)在情节提要中创建一个segue并将其命名为“ segue”

2.)在要从中查找的ViewController中创建一个函数。

func goToDifferentView() {

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

}

3.)在ViewController的ViewDidLoad()中,您正在从创建观察者中分离出来。

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或场景中,在希望触发锁定的任何位置添加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)

斯威夫特3:NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: NSNotification.Name(rawValue: "segue"), object: nil)
萨摩洛夫

3

您想要做的对于单元测试非常重要。基本上,您需要在视图控制器中创建一个小的本地函数。将该函数命名为任何名称,只需包含即可performSegueWithIndentifier

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

接下来,更改您的实用程序类,FBManager以包括一个接受函数自变量的初始化程序和一个变量,以保留执行segue的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")
    }
}

(便捷初始化允许您在执行单元测试时使用它,而无需执行segue。)

最后,在// //有待做的地方:segue到下一个视图???

self.yourFunction()

在单元测试中,您可以简单地将其调用为:

let f = UtilClass()
f.doThatThing()

doThatThing是您的fbsessionstatechange,UtilClass是FBManager。

对于您的实际代码,只需将localFunc(不带括号)传递给FBManager类。


2

这对我有用。

首先,为故事板中的视图控制器提供身份检查器中的故事板ID。然后使用以下示例代码(确保类,情节提要名称和情节提要ID与您所使用的相匹配):

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

您可以使用performSegueWithIdentifier函数来执行此操作。

屏幕截图

句法 :

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

范例:

 performSegueWithIdentifier("homeScreenVC", sender: nil)

1

另一种选择是使用模式搜索

步骤1:转到情节提要,并为View Controller提供一个情节提要ID。您可以在右侧的“身份检查器”中找到在何处更改情节提要ID。让我们调用情节提要IDModalViewController

第2步:打开“发送方”视图控制器(我们称之为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)
   }
}

0

这对我有用:

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


    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.