#swift #authentication #delegates
#swift #аутентификация #делегаты
Вопрос:
Я новичок в swift. Я использую делегирование для успешного входа в систему. но когда я нажал кнопку входа в систему, я вижу, что работает только индикатор выполнения. Как я могу заставить кнопку работать и перейти на следующую страницу? Если я использую в кнопке loginButtonTapped ниже. Это работает. но делегирование вообще не работает.
Presentermanager.shared.show(vc: .mainTabBarController)
Пожалуйста, помогите мне.
Это мои исходные коды.
LoadingViewController.swift
import UIKit
protocol LoginDelegate: class {
func showMainTabBarController()
}
class LoadingViewController: UIViewController {
private let isUserLoggedIn = false
weak var delegate: LoginDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
delay(durationInSeconds: 2.0) {
self.showInitialView()
}
}
private func showInitialView() {
// if user is logged in => main tab bar controller
// if user is not logged in => show onboarding controller
if isUserLoggedIn {
Presentermanager.shared.show(vc: .mainTabBarController)
} else {
Presentermanager.shared.show(vc: .loginViewController)
}
}
}
LoginViewController.swift
import UIKit
import MBProgressHUD
//protocol LoginDelegate: class {
// func showMainTabBarController()
//}
class LoginViewController: UIViewController {
private let isSuccessfulLogin = true
weak var delegate: LoginDelegate?
@IBOutlet weak var loginButton: UIButton!
@IBOutlet weak var signUpButton: UIButton!
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var passwordConfirmationTextField: UITextField!
@IBOutlet weak var segmentedControl: UISegmentedControl!
@IBOutlet weak var errorLabel: UILabel!
@IBOutlet weak var forgetPasswordButton: UIButton!
private enum PageType {
case login
case signUp
}
private var errorMessage: String? {
didSet {
showErrorMessageIfNeeded(text: errorMessage)
}
}
private var currentPageType: PageType = .login {
didSet{
setupViewFor(pageType: currentPageType)
print(currentPageType)
}
}
override func viewDidLoad() {
super.viewDidLoad()
setupViewFor(pageType: .login)
}
private func setupViewFor(pageType: PageType) {
errorLabel.text = ""
passwordConfirmationTextField.isHidden = pageType == .login
signUpButton.isHidden = pageType == .login
forgetPasswordButton.isHidden = pageType == .signUp
loginButton.isHidden = pageType == .signUp
}
private func showErrorMessageIfNeeded(text: String?) {
errorLabel.isHidden = text == nil
errorLabel.text = text
}
@IBAction func forgetPasswordButtonTapped(_ sender: UIButton) {
}
@IBAction func segmentedControlChanged(_ sender: UISegmentedControl){
currentPageType = sender.selectedSegmentIndex == 0 ? .login : .signUp
}
@IBAction func signUpButtonTapped(_ sender: UIButton) {
}
@IBAction func loginButtonTapped(_ sender: UIButton) {
MBProgressHUD.showAdded(to: view, animated: true)
delay(durationInSeconds: 2.0) {
MBProgressHUD.hide(for: self.view, animated: false)
if self.isSuccessfulLogin == true {
print("test")
self.delegate?.showMainTabBarController()
} else {
self.errorMessage = "Your password is invalid. Please try again."
}
}
}
@IBAction func closeButtonTapped(_ sender: UIButton) {
Presentermanager.shared.show(vc: .mainTabBarController)
}
}
extension LoginViewController: LoginDelegate {
func showMainTabBarController() {
Presentermanager.shared.show(vc: .mainTabBarController)
}
}
Комментарии:
1.
self.delegate?.showMainTabBarController()
это вызывает проблему? Ну, если вы отлаживаете, что вы видите? Я думаюself.delegate
nil
, именно поэтому метод не вызывается. Вам нужно установить делегата.2. Да, если я использую
self.delegate?.showMainTabBarController()
, то это вообще не работает. Я установил делегат следующим образомprotocol LoginDelegate: class { func showMainTabBarController() }
3. Это не настройка делегата, это определение того, что может делать делегат. Где-то вам нужно, чтобы переменная указывала на фактический экземпляр. Большая проблема заключается в том, что вы, похоже, пытаетесь определить
LoginViewController
как делегата, так и объект, который использует делегат.4. Что
Presentermanager.shared.show(vc: .mainTabBarController)
? Я предполагаю, что где-то есть либоLoginViewController()
или экземпляр из Storyboard / Xib, но именно там вам нужно установить делегат, где вы можете получить экземпляр. Прямо сейчас она скрыта, вы ничего не можете установить.5. хм .. я думал, что это настройка делегата. Как мне тогда настроить? и я должен удалить define delegate в LoginViewController?
Ответ №1:
Это не отвечает на ваш конкретный вопрос, но если вы попробуете это на игровой площадке, это может прояснить основную идею о том, какие элементы необходимы для работы делегирования.
В частности, обратите внимание, что класс, который реализует протокол, не является классом, который вызывает метод делегирования.
protocol SomeService {
func thingToDo() // Define what a delegate can do
}
class ServingClass: SomeService { // Define a class that can be a delegate
func thingToDo() { // Implement what this class does when it is a delegate
print("I can do this")
}
}
class ClientClass {
var delegate: SomeService? // Create a variable that may (or may not) point to a delegate
func action() {
if let delegate = delegate { // Check if the delegate is available
delegate.thingToDo() // Use the delegate
} else {
print("Delegate wasn't set")
}
}
}
func testDelegation() {
let cc = ClientClass()
cc.action() // Result when delegate is not set
cc.delegate = ServingClass() // Create a delegate object
cc.action() // Result when delegate is set
}
testDelegation()
Комментарии:
1. @Phillips Mills Спасибо за ваш образец. Я должен попробовать это.