Создайте закрытие Swift для создания UIView

Я хотел бы применить DRY к линиям, которые я создаю в Swift. Как я могу реорганизовать этот код, чтобы вызвать замыкание? Он находится на контроллере представления.

var topLineView: UIView = {
    let lineView = UIView()
    lineView.layer.borderWidth = 1.0
    lineView.layer.borderColor = UIColor.lightGray.cgColor
    return lineView
}()

var bottomLineView: UIView = {
    let lineView = UIView()
    lineView.layer.borderWidth = 1.0
    lineView.layer.borderColor = UIColor.lightGray.cgColor
    return lineView
}()

var centerLineView: UIView = {
    let lineView = UIView()
    lineView.layer.borderWidth = 1.0
    lineView.layer.borderColor = UIColor.lightGray.cgColor
    return lineView
}()

Я попытался создать переменную, но это вызвало ошибку:

let lineView = {
    let lineView = UIView()
    lineView.layer.borderWidth = 1.0
    lineView.layer.borderColor = UIColor.lightGray.cgColor
    return lineView
}

var centerLineView = lineView()

ошибка (невозможно определить тип закрытия и т. д.)


person Rik    schedule 22.10.2019    source источник


Ответы (2)


Swift не может сделать вывод о типе возврата вашего замыкания, поэтому вам нужно заранее сообщить ему, что вы возвращаете UIView. Это компилируется и работает нормально.

let lineView = { () -> UIView in
    let lineView = UIView()
    lineView.layer.borderWidth = 1.0
    lineView.layer.borderColor = UIColor.lightGray.cgColor
    return lineView
}
var myViewFromClosure = lineView()
var myViewFromClosure2 = lineView()
var myViewFromClosure3 = lineView()

Однако лично я бы выбрал function вместо closure в этом случае. Как это:

func lineViewFunc() -> UIView {
    let lineView = UIView()
    lineView.layer.borderWidth = 1.0
    lineView.layer.borderColor = UIColor.lightGray.cgColor
    return lineView
}

var myViewFromFunc = lineViewFunc()
var myViewFromFunc2 = lineViewFunc()
var myViewFromFunc3 = lineViewFunc()
person joehinkle11    schedule 22.10.2019
comment
Насчет функции согласен. Стоит помнить, что функция может быть локально вложена внутрь другой функции, и это хороший способ извлечь локально повторяющийся код, не загрязняя внешнее пространство имен. - person Rob Napier; 22.10.2019
comment
Я попробовал функцию, но компилятор жалуется, что self не инициализирован - person Rik; 23.10.2019
comment
@Rik, вы можете поделиться своей реализацией, если хотите - person joehinkle11; 23.10.2019
comment
В итоге я создал отдельный класс, потому что функция не работала, но также повторял себя в аналогичной ситуации, потому что мой менеджер сказал также использовать функцию, но тогда мне пришлось бы сделать ее необязательной. - person Rik; 23.10.2019
comment
Я думаю, я мог бы просто создать пустой и использовать метод для его настройки в viewdidload... - person Rik; 23.10.2019
comment
@Rik Я добавил пример функции в свой ответ - person joehinkle11; 23.10.2019
comment
Кроме того, в конечном итоге не имеет значения, используете ли вы function или closure. Связано: stackoverflow. com/questions/24108667/ - person joehinkle11; 23.10.2019

Проблема с функцией в том, что я должен вызвать ее перед super.init, но self еще не существует.

person Rik    schedule 23.10.2019