Избегайте множественных предложений if для вызова разных методов
У меня есть подобная структура кода для этого:
if !checkFirstName(firstName: firstNameField.text!) {
firstNameField.text = "foo"
return false
}
firstNameField.text = "bar"
if !checkLastName(lastName: lastNameField.text!) {
lastNameField.text = "foo"
return false
}
lastNameField.text = "bar"
...
Проблема здесь в том, что мне нужно сделать еще несколько проверок, но они отличаются только именем функции и UITextField
Я работаю над
Я хочу, чтобы они были частью единого for
петля или map
, но кажется, что я не мог заставить его работать, используя Selector()
чем-то похож на следующее:
let functionNames = ["FirstName", "LastName", ...]
let fields = ["FirstName": firstNameField, "LastName": lastNameField, ...]
...
for name in functionNames {
let sel = Selector("check" + name + ":")
if !view.perform(sel) {
fields[name].text = "foo"
return false
}
fields[name].text = "bar"
return true
}
Selector()
не рекомендуется в Swift и, даже если это может сработать, я хочу избежать этого.
Должен ли я продолжать исследования в создании Selector()
работа или это вся проблема дублирования архитектурная проблема? В любом случае, как мне этого избежать
2 ответа
Функции являются первоклассными объектами в Swift, что означает, что вы можете передавать их как переменные. Вместо того, чтобы динамически создавать имя функции, свяжите их с UITextField
в кортеже.
Предполагая, что у вас есть эти функции:
func check (firstName: String) -> Bool {
// ...
}
func check (lastName: String) -> Bool {
// ....
}
Вы можете зациклить их так:
// checks is an array of tuples. Each tuple has 2 components:
// a UITextField and a function which takes a String and return a Bool
let checks: [(field: UITextField, checker: (String) -> Bool)] = [
(firstNameField, check(firstName:)),
(lastNameField , check(lastName:))
]
for c in checks {
guard c.checker(c.field.text!) else {
c.field.text = "foo"
return false
}
c.field.text = "bar"
}
Я бы предложил получить все текстовые поля из вашего представления, а затем продолжить с общей функцией.
(Я не скомпилировал ниже код.)
func getAllTextFields() -> [UITextField] {
var results:[UITextField] = []
for subview in view.subviews {
results += getAllTextFields(in: subview)
if subview.isKind(of: UITextField.self) {
if let textField = subview as? UITextField {
results.append(textField)
}
}
}
return results
}
func YourFuncName() -> Bool {
var allTextFields = getAllTextFields()
var returnValue = true
for textField in allTextFields {
if !checkTextField(text: textField.text) {
textField.text = “foo”
returnValue = false
break
} else {
textField.text = “bar”
}
}
return returnValue
}
func checkTextField (text :String ) -> Bool {
//Your checking func body goes here
}
Модифицировано: я могу выполнить "выполнить селектор"