How do ı move UITextFieldDelegate to ViewModel

44 Views Asked by At
extension ViewModel: TextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        search()
        textField.resignFirstResponder()
        return true
    }
}


protocol TextFieldDelegate: AnyObject {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool
}

I created the ViewModel in this way

searchView.textField.delegate = viewModel

and also I defined it this way in ViewDidLoad but I get the error that Cannot assign value of type 'ConsentListSelectionViewModel' to type '(any UITextFieldDelegate)?'

Xcode offers me this as a solution

searchView.textField.delegate = viewModel as? any UITextFieldDelegate

when I run it this way, the delegate is equal to nil and there is no triggering.

What do I have to do?

1

There are 1 best solutions below

1
lazarevzubov On

First of all, I wouldn't recommend you doing this, because UITextFieldDelegate should stay on the view layer. Instead, delegate implementation details of UITextFieldDelegate methods to your view model.

But if you really want to, you need to declare the view model in your view the way that the view is certain that the view model implements UITextFieldDelegate. For instance:

import UIKit

class ViewModel: NSObject { }

extension ViewModel: UITextViewDelegate { }

class YourView {
    let viewModel: ViewModel & UITextViewDelegate
    init(viewModel: ViewModel & UITextViewDelegate) {
        self.viewModel = viewModel
    }
}

Or a protocol-based approach:

import UIKit

protocol ViewModel: UITextViewDelegate { }

class DefaultViewModel: NSObject, ViewModel { }

class YourView {
    private let viewModel: ViewModel
    init(viewModel: ViewModel) {
        self.viewModel = viewModel
    }
}