Comments 23
Здорово! Только кнопка "дрожит" по ширине, зафиксировать как-нибудь бы размеры.
CustomStepper: UIView
почему не UIControl? не надо было бы никакого делегата придумывать (который ещё и неправильный – что если я хочу узнавать об изменениях двух и более разных таких контролов, как отличить от которого из них пришло событие?)
зачем currentValue приватное? как мне узнавать текущее состояние, чтобы например программно сделать +3? зачем lazy Int?
зачем вообще всё приватное? как мне кастомизировать внешний вид?
... зачем теги кнопкам? в обработчике нажатия кнопки можно проверить кто был sender – increaseButton или же decreaseButton
Продолжу Ваши рассуждения:
Зачем enum
CaseIterable
, если это нигде не используется?Зачем пихать события в один метод, если на каждую кнопку можно повесить свое событие?
Так можно избавиться от бесполезного enum'а.
Выглядит так, будто человек прочитал одну (не самую лучшую) книгу по Swift и начал писать не разбираясь в смысле написанного.
Добрый вечер! Прислушался к вашим рекомендациям и подправил свою статью, спасибо за ваш вклад.
Стало получше.
Но что будет, если:
let stepper = CustomStepper()
stepper.currentValue = 10
?
Спасибо, исправил
Ок, зачем тогда обновлять текст в двух местах – в сеттере и в обработчике кнопок?
Вопрос на подумать: а нужно ли вызывать sendActions(.valueChanged)
в сеттере или нет и почему?
Здравствуйте, еще раз спасибо за вашу внимательность и желание улучшить мои знания, да, нужно, потому что мы хотим прокидывать данные в контроллере, поэтому мы и должны вызывать sendActions(.valueChanged). А если мы закинем sendActions() в didSet, то он попросту не будет вызываться
Я не совсем понял ответ.
А если мы закинем sendActions() в didSet, то он попросту не будет вызываться
Но ведь в обработчике кнопки есть код, который его вызывает, записывая +1 или -1 в currentValue
.
Вот и вопрос – где всё-таки стоит оставить sendActions
– в обработчике кнопки ("человеческое" взаимодействие с контролом) или же перенести в didSet
("программное" взаимодействие с контролом)?
Что будет, если:
let stepper = CustomStepper()
stepper.currentValue = -1
Спасибо, исправил
Теперь есть две одинаковые проверки: в сеттере и в обработчике кнопки
case decreaseButton:
currentValue = currentValue > 1 ? currentValue - 1 : currentValue
Может тут можно сделать -= 1
?
Спасибо, подправил
currentValue = max(0, currentValue)
Нет ощущения, что это похоже на рекурсивный вызов?
Код stepper.currentValue = -1
сначала всё же запишет -1
в свойство, а потом сразу же перезапишет туда же ноль. Код не входит в бесконечный цикл только лишь потому, что didSet
не вызывается при записи примитива с таким же значением (что я скорее отношу к счастливой случайности, и надеяться я бы на это не стал).
В Objective-C было бы наверное так:
- (void)setCurrentValue(NSInteger)value {
_currentValue = max(0, value);
// update label's text
}
т.е. реальная запись нового значения происходила бы в ivar, который точно не имеет никаких сайд-эффектов (как вот сеттер у свойства).
Пишем собственный CustomStepper в Swift