Connect with us

Программирование

Создаем виджеты для экрана блокировки на SwiftUI

Мы можем заполнить наш экран блокировки красивыми виджетами. Реализовать виджет для экрана блокировки несложно, поскольку его API использует тот же код, что и виджеты домашнего экрана.

Фото аватара

Опубликовано

/

     
     

Одной из самых востребованных функций для iOS были настраиваемые экраны блокировки. И, наконец, они появились у нас с последней версией iOS 16. Мы можем заполнить наш экран блокировки красивыми виджетами. Реализовать виджет для экрана блокировки несложно, поскольку его API использует тот же код, что и виджеты домашнего экрана. В этой статье мы узнаем, как реализовать виджеты экрана блокировки для наших приложений.

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

struct WidgetView: View {
    let entry: Entry
    
    @Environment(\.widgetFamily) private var family
    
    var body: some View {
        switch family {
        case .systemSmall:
            SmallWidgetView(entry: entry)
        case .systemMedium:
            MediumWidgetView(entry: entry)
        case .systemLarge, .systemExtraLarge:
            LargeWidgetView(entry: entry)
        default:
            EmptyView()
        }
    }
}

В приведенном выше примере у нас есть типичное представление, определяющее виджет. Мы используем среду, чтобы понять семейство виджетов и отобразить представление правильного размера. Все, что нам нужно сделать для поддержки виджетов экрана блокировки, — это удалить оператор по умолчанию и реализовать все новые случаи, определяющие виджеты экрана блокировки.

struct WidgetView: View {
    let entry: Entry
    
    @Environment(\.widgetFamily) private var family
    
    var body: some View {
        switch family {
        case .systemSmall:
            SmallWidgetView(entry: entry)
        case .systemMedium:
            MediumWidgetView(entry: entry)
        case .systemLarge, .systemExtraLarge:
            LargeWidgetView(entry: entry)
        case .accessoryCircular:
            Gauge(value: entry.goal) {
                Text(verbatim: entry.label)
            }
            .gaugeStyle(.accessoryCircularCapacity)
        case .accessoryInline:
            Text(verbatim: entry.label)
        case .accessoryRectangular:
            VStack(alignment: .leading) {
                Text(verbatim: entry.label)
                Text(entry.date, format: .dateTime)
            }
        default:
            EmptyView()
        }
    }
}

Напомню, что система использует разные режимы рендеринга для виджетов экрана блокировки и домашнего экрана. Система предоставляет нам три разных режима рендеринга.

  1. Полноцветный режим для виджетов главного экрана и расширений watchOS с поддержкой цветов. И да, вы также можете использовать WidgetKit для реализации расширений watchOS, начиная с watchOS 9.
  2. В ярком режиме система обесцвечивает текст, изображения и датчики, превращая их в монохромные, и окрашивает их подходяще для фона экрана блокировки.
  3. Акцентный режим используется только в watchOS, где система делит виджет на две группы: по умолчанию и акцентированные. Система окрашивает акцентированную часть вашего виджета в оттенок, который пользователь выбирает в настройках циферблата.

Создаем виджеты для экрана блокировки на SwiftUI

Режим рендеринга доступен через среду SwiftUI, поэтому вы всегда можете проверить, какой режим рендеринга активен, и отразить его в своем дизайне. Например, вы можете использовать разные изображения с разными режимами рендеринга.

struct WidgetView: View {
    let entry: Entry
    
    @Environment(\.widgetRenderingMode) private var renderingMode
    
    var body: some View {
        switch renderingMode {
        case .accented:
            AccentedWidgetView(entry: entry)
        case .fullColor:
            FullColorWidgetView(entry: entry)
        case .vibrant:
            VibrantWidgetView(entry: entry)
        default:
            EmptyView()
        }
    }
}

Как вы можете видеть в приведенном выше примере, мы используем значение среды widgetRenderingMode, чтобы получить фактический режим рендеринга и изменить виджет. Как я уже говорил, в акцентированном режиме система делит ваш виджет на части и раскрашивает их особым образом. Вы можете пометить часть вашей иерархии представлений с помощью модификатора представления widgetAccentable. В этом случае система будет знать, какие представления будут использовать цвет оттенка.

struct AccentedWidgetView: View {
    let entry: Entry
    var body: some View {
        HStack {
            Image(systemName: "moon")
                .widgetAccentable()
            Text(verbatim: entry.label)
        }
    }
}

Наконец, нам нужно настроить наш виджет для поддерживаемых типов.

@main
struct MyAppWidget: Widget {
    let kind: String = "Widget"
    
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: Provider()) { entry in
            WidgetView(entry: entry)
        }
        .configurationDisplayName("My app widget")
        .supportedFamilies(
            [
                .systemSmall,
                .systemMedium,
                .systemLarge,
                .systemExtraLarge,
                .accessoryInline,
                .accessoryCircular,
                .accessoryRectangular
            ]
        )
    }
}

Если вы все еще поддерживаете iOS 15, вы можете проверить поддержку новых виджетов экраном блокировки.

@main
struct MyAppWidget: Widget {
    let kind: String = "Widget"
    
    private var supportedFamilies: [WidgetFamily] {
        if #available(iOSApplicationExtension 16.0, *) {
            return [
                .systemSmall,
                .systemMedium,
                .systemLarge,
                .accessoryCircular,
                .accessoryRectangular,
                .accessoryInline
            ]
        } else {
            return [
                .systemSmall,
                .systemMedium,
                .systemLarge
            ]
        }
    }
    
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: Provider()) { entry in
            WidgetView(entry: entry)
        }
        .configurationDisplayName("My app widget")
        .supportedFamilies(supportedFamilies)
    }
}

Сегодня мы узнали, как внедрить новые виджеты экрана блокировки в iOS 16. Помните, что мы можем повторно использовать один и тот же API для создания дополнений для watchOS. И вы можете легко в коде виджета получить значения среды, чтобы понять, какой режим рендеринга активен в данный момент.

Еще

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.
Advertisement

Наши партнеры:

LEGALBET

Мобильные приложения для ставок на спорт
Telegram

Популярное

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: