在 UIViewController 中正确使用 present

Using present in UIViewController properly

我遇到无法使用 "self" 在 class 中显示动态 UIViewController 的问题。它告诉我 "Value of type '(LoginScreenVC) -> () -> (LoginScreenVC)' has no member 'view'"。

它可以使用闭包,例如if let loginScreen = UIStoryBoard ...,但由于要切换到的 UIViewController 是动态的,我无法将其转换为特定的 UIViewController。

还有其他方式来呈现ViewController吗?

这是我的代码:

SWIFT 4.2 / XCode 10.1

import UIKit

class LoginScreenVC: UIViewController {
    let myTokenHandler = TokenHandler()

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func loginButton(_ sender: Any) {
        print("Login button pressed")

        let usernameInputField = self.view.viewWithTag(6548) as! UITextField
        let passwordInputField = self.view.viewWithTag(6549) as! UITextField

        userInput = usernameInputField.text!
        passInput = passwordInputField.text!

        // call completion handler
        requestToken(success: handlerBlock)

    }
    // completion handler step 1: request token and get redirect string to switch screen
    func requestToken(success: (String) -> Void) {
        let requestResult = myTokenHandler.requestToken(password: passInput, username: userInput)
        success(requestResult)
    }

    // completion handler step 2: use redirect string to switch screen
    let handlerBlock: (String) -> Void = { redirect in
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let loginScreen = storyboard.instantiateViewController(withIdentifier: redirect)
            self.present(loginScreen, animated: true, completion: nil) //Value of type '(LoginScreenVC) -> () -> (LoginScreenVC)' has no member 'view'
    }
}

你是说:

let handlerBlock: (String) -> Void = { redirect in
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let loginScreen = storyboard.instantiateViewController(withIdentifier: redirect)
    self.present(loginScreen, animated: true, completion: nil)
}

问题是您在没有 self 的上下文中使用术语 self。 (嗯,有一个self,但不是你想的。)present是一个UIViewController实例方法,所以self需要是一个UIViewController实例;在这种情况下,它不是。

我可以想出六种方式来表达您要表达的意思,但最简单的可能是将其重写为:

func handlerBlock(_ redirect:String) -> Void {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let loginScreen = storyboard.instantiateViewController(withIdentifier: redirect)
    self.present(loginScreen, animated: true, completion: nil)
}

现在handlerBlock是一个实例方法self是有意义的——它就是实例,这正是你想要的。其余代码未更改,因为表达式 requestToken(success: handlerBlock) 中的裸名 handlerBlock 是一个函数名,就像以前一样。