所以,我在解决这个问题时遇到了一些重大问题,我已经广泛搜索了一个解决方案,但我出乎意料地找不到一个。我正在尝试为用户创建一个多页面(准确地说是5个)。
我首先向您展示第1页和第5页的布局(因为解决该问题将解决第2-4页的问题):
正如您所看到的(从页面控制点),我使用页面视图控制器允许用户从一个页面滚动到另一个页面。我想要完成的是让用户能够在第1-5页输入他们的注册信息,然后一次提交(可以在第5页找到)。
以下是我用于第1页的当前代码:
class SignUpInfoViewController: UIViewController {
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
以下是我用于第5页的当前代码:
class TermsOfUseViewController: UIViewController {
let minPasswordCharCount = 6
@IBAction func signUpAction(_ sender: Any) {
let providedEmailAddress = SignUpInfoViewController().emailTextField.text!
let providedPassword = SignUpInfoViewController().passwordTextField.text!
let trimmedPassword = providedPassword.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
if !(validEmail(enteredEmail: providedEmailAddress) && validPassword(enteredPassword: trimmedPassword)) {
invalidCredentialsAlert()
}
else {
FIRAuth.auth()?.createUser(withEmail: providedEmailAddress, password: providedPassword) { user, error in
if error == nil {
FIRAuth.auth()!.signIn(withEmail: providedEmailAddress,
password: providedPassword)
}
else {
let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
}
}
// Email is valid if it has a standard email format
func validEmail(enteredEmail: String) -> Bool {
let emailFormat = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
let emailPredicate = NSPredicate(format:"SELF MATCHES %@", emailFormat)
return emailPredicate.evaluate(with: enteredEmail)
}
// Password is valid if it is not empty or greater than a specified number of characters
func validPassword(enteredPassword: String) -> Bool {
if (enteredPassword != "" && enteredPassword.characters.count >= minPasswordCharCount) {
return true
}
return false
}
在TermsOfUseViewController类中,我试图使用SignUpInfoViewController中的emailTextField和passwordTextField出口,但是我收到以下错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
我调试了错误,发现SignUpInfoViewController的emailTextField属性为nil,因此强行展开会导致应用程序崩溃(注意:我已经正确地将IBOutlets连接到SignUpInfoViewController,所以没有问题)。
如何安全地将IBOutlets的使用从SignUpInfoViewController类转移到TermsOfUseViewController类而不会崩溃?换句话说,当我在TermsOfUseViewController类中引用IBOutlets时,如何将它发送到IBOutlets不再为零的位置?
谢谢!
答案 0 :(得分:1)
这是delegate pattern
protocol SignUpProtocol: class {
func didProvideUserData(username: String ,password: String)
}
在您的注册类中声明委托:public weak var delegate:SignUpProtocol?
我假设当用户提供了需求信息时,他们需要按某个按钮进入下一步:因此在该按钮中你应该提出代表
@IBAction func nextButton(sender:UIButton) {
guard let username = usernameTextfield?.text, let password = passwordTextField?.text, else { fatalError("textfields were empty") }
if delegate != nil { // this saying when someone is listening to me, I will expose any method associated to me
delegate?.didProvideUserData(username:username, password:password) // passing the username and password from textfield
}
}
如果您没有按钮,请查看property observer
,您可以在哪里找到属性
var didFulfill:Bool? = nil {
didSet {
if didFulfill != nil && didFulfill == true {}
// here you check if your textfields are sets then raise the delegate
}
}
设置此属性didFulfill = when both textfields are not empty :)
现在在您的条款课程中,只需订阅该代表
class TermsOfUseViewController: UIViewController, SignUpProtocol {
var signUpVc: SignUpInfoViewController?
override func viewDidLoad() {
super.viewDidLoad()
signUpVc = SignUpInfoViewController()
signUpVc?.delegate = self
}
func didProvideUserData(username: String, password:String) {
// there is your data
}
}
答案 1 :(得分:0)
您必须考虑到您并非始终拥有所有UIPageViewController
的所有引用。话虽这么说,我建议要么在UIPageViewController
中保留对象的更新信息,要么使用 Singleton Pattern 来使用它来存储信息并稍后使用它。 UIPageViewController正在被重用,你可能有一个之前和一个之后,并依赖它们是错误的。
您可以将UIPageViewController用作self.parentViewController
或类似的东西。