Плавный переход масштаба при нажатии кнопки

Анимация по 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.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее