在 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
是一个函数名,就像以前一样。
我遇到无法使用 "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
是一个函数名,就像以前一样。