РЕДАКТИРОВАТЬ # 3
Использование одного обобщенного c класса:
public protocol UIViewRepresentableHelper: UIViewRepresentable {
var configuration: (UIViewType) -> () { get set }
}
public extension UIViewRepresentableHelper {
func makeUIView(context: UIViewRepresentableContext<Self>) -> UIViewType { UIViewType() }
func updateUIView(_ uiView: UIViewType, context: UIViewRepresentableContext<Self>) { configuration(uiView) }
}
public struct ViewConfigurator<UIViewType: UIView>: UIViewRepresentableHelper {
public var configuration: (UIViewType) -> ()
public init(configuration: @escaping (UIViewType) -> ()) {
self.configuration = configuration
}
}
Вы можете использовать его, явно указав тип аргумента закрытия :
let labelConfigurator = ViewConfigurator { (label: UILabel) in
print(label.text ?? "empty")
}
var label = UILabel()
labelConfigurator.configuration(label) // Optional("")
label.text = "some text"
labelConfigurator.configuration(label) // Optional("some text")
или явно с указанием аргумента generi c:
typealias ButtonConfigurator = ViewConfigurator<UIButton>
let buttonConfigurator = ButtonConfigurator { button in
print(button.title(for: .normal) ?? "empty")
}
var button = UIButton()
buttonConfigurator.configuration(button) // Optional("")
button.setTitle("some title", for: .normal)
buttonConfigurator.configuration(button) // Optional("some title")
в любом случае вы должны «помочь» компилятору на вызывающем сайте но вы делаете это только один раз.
Я думаю, что это не сработало, когда вы попробовали мой первый ответ, потому что вы не объявили ViewConfigurator
вот так:
public struct ViewConfigurator<UIViewType: UIView>: UIViewRepresentableHelper
РЕДАКТИРОВАТЬ # 2
Это сработало, потому что я объявил:
func updateUIView(_ uiView: UITextField, context: Context) {
}
, но как только я поставил UIViewType
, ошибка вернулась, я думаю, что моя первая мысль была правильно, компилятор плохо справляется со связанными типами и замыканиями
EDIT # 1
Таким образом, проблема на самом деле заключалась в том, что UIViewType
и configuration
не были объявлены в одном протоколе.
Я мог бы обойти это, создав типалиас UIViewType
в UIViewRepresentableHelper
вот так:
protocol UIViewRepresentableHelper: UIViewRepresentable {
typealias ViewType = UIViewType
var configuration: (ViewType) -> () { get set }
}
struct TextFieldView: UIViewRepresentableHelper {
var configuration: (UITextField)->()
}
использование :
let textFieldView = TextFieldView { textField in
print(textField.text)
}
var textField = UITextField()
textFieldView.configuration(textField) // Optional("")
textField.text = "some text"
textFieldView.configuration(textField) // Optional("some text")