ݺߣ

ݺߣShare a Scribd company logo
Кастомная кнопка:
взгляд изнутри
Кирилл Аверьянов
iOS Developer
• Идея и предназначение💡
• Пример👌
• Компоненты 🔑
• Демо 🖥
2
Коротко
Идея
-William Edmund Hick
“The time it takes to make a decision increases
as the number of alternatives increases.”
4
Зачем?
• Требования дизайна
• Изменение layout
• Неоднозначное поведение
5
Пример
7
Компоненты
Компоненты для
реализации
• Состояния
• Отслеживание их
• Изменение цвета 🖍
• Layout
9
Состояния
Состояния (UIControl)
• var isEnabled: Bool { get set }
• var isSelected: Bool { get set }
• var isHighlighted: Bool { get set }
11
isFocused { get } (UIView)
12
iOS 9+
isFocused { get } (UIView)
iOS 9+
TF?!
14
Состояния (UIControl)
• func beginTracking(UITouch, with: UIEvent?) -> Bool
• func continueTracking(UITouch, with: UIEvent?) -> Bool
• func endTracking(UITouch?, with: UIEvent?)
• func cancelTracking(with: UIEvent?)
• var isTracking: Bool { get }
15
State
(UIControlState)
• var state: UIControlState { get }
• Состояния:
• normal
• highlighted, disabled, selected
• focused, application, reserved
16
iOS 9+
Немного про биты 😳
• Конъюнкция( & ) - есть ноль, то ноль
• Дизъюнкция( | ) - есть единица, то единица
A B A & B A | B
0 0 0 0
0 1 0 1
1 0 0 1
1 1 1 1
Немного про биты 😳
• a = 1 ( 0001 )
• b = 2 ( 0010 )
• c = 4 ( 0100 )
• d = 8 ( 1000 )
18
• a | d = 9 ( 1001 ) = X
• X & d = d ( 1000 )
• X & b = 0 ( 0000 )
19
• state = a | b | c
• Состояния:
• normal = 0
• highlighted = 1, disabled = 2, selected = 4
• print(state & a > 0) // 0 или 1, другого не дано
• print(state.rawValue &
UIControlState.disabled.rawValue > 0)
State
(UIControlState)
Изменение цвета
Изменение цвета
21
• Определение яркости🎨
• Сдвиг цветов🏃
Определение яркости
22
((red * 299) + (green * 587) + (blue * 114)) / 1000
W3C Algorithm
W3C = World Wide Web Consortium
Определение яркости
23
http://www.nbdtech.com/Blog/archive/2008/04/27/
Calculating-the-Perceived-Brightness-of-a-Color.aspx
sqrt(.241 * red² + .691 * green² + .068 * blue²)
X ∈ 0 … 255
24
.net 3.0
Сдвиг цветов
25
X < 130 ? Brighter : Darker
X
Демо
Начало
1. Создаем xib
class MyButton: UIButton {
@IBOutlet var label: UILabel!
@IBOutlet var viewHeight: NSLayoutConstraint!
}
2. Создаем класс
3. Конектим
Загрузка
28
override func awakeAfter(using aDecoder: NSCoder) -> Any? {
return loadFromNibIfEmbeddedInDifferentNib()
}
29
func loadFromNibIfEmbeddedInDifferentNib() -> Self {
let isJustAPlaceholder = subviews.count == 0
if isJustAPlaceholder {
let theRealThing = type(of: self).viewFromNib()
theRealThing.frame = frame
translatesAutoresizingMaskIntoConstraints = false
theRealThing.translatesAutoresizingMaskIntoConstraints = false
return theRealThing
}
return self
}
Загрузка
30
Загрузка
class func viewFromNib(withOwner owner: Any? = nil) -> Self {
let name = String(describing: type(of
self)).components(separatedBy: ".")[0]
let view = UINib(nibName: name, bundle:
nil).instantiate(withOwner: owner, options: nil)[0]
return cast(view)!
}
private func cast<T, U>(_ value: T) -> U? {
return value as? U
}
Результат
31
override var isHighlighted: Bool {
didSet {
if oldValue != isHighlighted {
notChange = true
updateAppearance()
}
}
}
override var isSelected: Bool {
didSet {
if oldValue != isSelected {
notChange = true
updateAppearance()
}
}
}
override var isEnabled: Bool {
didSet {
if oldValue != isEnabled {
notChange = true
updateAppearance()
}
}
}
33
Демо DIY
private func updateAppearance() {
isSetup = true
if (isSelected || isHighlighted) && isEnabled {
buttonTouchedIn()
} else {
buttonTouchedOut()
}
alpha = isEnabled ? 1 : 0.8
isSetup = false
}
34
Демо DIY
private func buttonTouchedIn() {
delegate?.buttonIn()
backgroundColor = nessesaryBackgroundColor?.tapButtonChangeColor
textForLabel = ".."
startTimer()
UIView.animate(withDuration: 0.3, animations: {
self.viewHeightConstraint.constant += 40.0
self.layoutIfNeeded()
})
animateClouds()
}
35
Демо DIY
private func buttonTouchedOut() {
delegate?.buttonOut()
backgroundColor = nessesaryBackgroundColor
invalidateTimer()
label.text = text
UIView.commitAnimations()
UIView.animate(withDuration: 0.3, animations: {
self.viewHeightConstraint.constant -= 40.0
self.layoutIfNeeded()
})
}
36
Демо DIY
override var backgroundColor: UIColor? {
didSet {
if oldValue == backgroundColor || notChange {
notChange = false
return
}
if !isSetup {
nessesaryBackgroundColor = backgroundColor
notChange = true
backgroundColor = oldValue
}
updateAppearance()
}
}
~ 100 строк
37
Результат
😱😱😱
Результат
Репозиторий
39
https://github.com/Kirillzzy/CustomButton
😱😱😱
Спасибо
за внимание😉
@kirillzzy - everywhere
kirillaveryanov.me
Кирилл Аверьянов

More Related Content

Кастомная кнопка: взгляд изнутри