Как я мог бы успешно использовать делегирование? Кнопка не работает с делегатами

#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 Спасибо за ваш образец. Я должен попробовать это.