Анимация по isPressed выбрана верно, но ButtonStyle требует makeBody(configuration:), а Configuration.Label нужно использовать напрямую, без Text.
Плавный переход масштаба при нажатии кнопки
Анимация по isPressed выбрана верно, но ButtonStyle требует makeBody(configuration:), а Configuration.Label нужно использовать напрямую, без Text.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо добавить анимацию к пользовательскому стилю кнопки, чтобы изменение её масштаба происходило плавно, а не резкими скачками.
struct AppButtonStyle: ButtonStyle {
func body(_ ctx: Configuration) -> some View {
Text(ctx.label)
.scaleEffect(ctx.isPressed ? 0.5 : 1.0)
.animation(.easeInOut(duration: 0.2), value: ctx.isPressed)
}
}
В данном примере используется SwiftUI. При нажатии (ctx.isPressed == true) кнопка уменьшится до 50 % от исходного размера, а при отпускании вернётся к нормальному размеру. Плавность достигается за счёт применения анимации easeInOut с длительностью 0.2 секунды.
Ответ
Анимация по isPressed выбрана верно, но ButtonStyle требует makeBody(configuration:), а Configuration.Label нужно использовать напрямую, без Text.
Исправленный стиль:
struct AppButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.scaleEffect(configuration.isPressed ? 0.5 : 1)
.animation(.easeInOut(duration: 0.2),
value: configuration.isPressed)
}
}
Применение: .buttonStyle(AppButtonStyle()). Label уже является View, а не строкой для конструктора Text. Анимация запускается при изменении состояния нажатия и охватывает масштабирование. Для интерфейса обычно выбирают менее сильное уменьшение и учитывают пользовательскую настройку Reduce Motion.