swift - 在 UIViewController 中正确使用 present

标签 swift uiviewcontroller closures

我遇到无法使用“self”在类里面呈现动态 UIViewController 的问题。它告诉我“'(LoginScreenVC) -> () -> (LoginScreenVC)' 类型的值没有成员'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 是一个函数名,就像之前一样。

关于swift - 在 UIViewController 中正确使用 present,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54516946/

相关文章:

ios - 控制iOS 13模态呈现的高度

javascript - JavaScript 中匿名函数中的参数变量

javascript - 为什么我无法切换 for 语句中每个元素(组内)的可见性,而只能切换组中的最后一个元素?

c - 如何为 C 函数创建闭包

swift - 使 UIColor Codable - 符合协议(protocol) 'Encodable'

ios - 使用restKit解析xml

ios - 链接无法从 iOS 9.0 中的 safari 应用程序打开,但在 iOS 9.3 中有效

ios - 调用 topLayoutGuide 会完全中断滚动吗?

ios - 如何拆分冗长的 uiviewcontroller 类?

iphone - 应该使用 NIB 或 iPhone 中的代码创建 View 吗?