[Разработка под iOS, Swift] Построение графиков в SwiftUI (перевод)

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
14-Май-2021 01:36
Перевод подготовлен в рамках курса "iOS Developer. Basic". Если вам интересно узнать о курсе больше, приходите на день открытых дверей онлайн.

Время от времени мне нужно визуализировать данные в виде красивых графиков. В этой статье будет показано, как рисовать графики в SwiftUI-приложении.Создание пакета для построения графиков с нуля было невозможным из-за ограничений по времени и бюджету, поэтому мне пришлось искать уже существующие решения.Выбор пал на SwifUI-Charts, который предлагает действительно красиво выглядящие графики и простую интеграцию.Установка и конфигурация проектаСначала мы начнем с создания проекта в XCode.
Отправной точкой является стандартное SwiftUI-приложение, которое будет модифицировано для отображения графика.
На следующем этапе пакет будет добавлен, за счет открытия настройки проекта.
Нажав на кнопку "плюс", можно добавить новый пакет. Здесь необходимо указать полный путь к репозиторию: https://github.com/spacenation/swiftui-charts.git.
На следующем экране я оставил все значения по умолчанию.
На последнем экране я также оставил значения по умолчанию такими, какими они были.
Отображение постоянных данныхПришло время добавить код. Для первого теста я просто взял несколько фрагментов кода из Github-Readme и добавил их в ContentView:
import Charts
import SwiftUI
struct ContentView: View {
    var body: some View {
        Chart(data: [0.1, 0.3, 0.2, 0.5, 0.4, 0.9, 0.1])
            .chartStyle(
                LineChartStyle(.quadCurve, lineColor: .blue, lineWidth: 5)
            )
    }
}
При запуске этого в симуляторе будет нарисован красивый график, показывающий постоянные значения.
Это считается первым успешным тестом.Отображение динамических данныхВ той области, в которой я работаю, данные, которые мне нужно визуализировать, меняются со временем, например, в результате сенсорного ввода. Давайте расширим пример, чтобы динамически обновлять графики в соответствии с изменением данных.В качестве "сенсора" будет использоваться класс ObservableObject, который просто публикует случайное значение Double каждые 500 миллисекунд.
import Foundation
class ValuePublisher: ObservableObject {
    @Published var value: Double = 0.0
    init() {
        Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { timer in
            self.value = Double.random(in: 0...1.0)
        }
    }
}
Его нужно инстанцировать в ContentView как переменную @State.
@StateObject var valuePublisher = ValuePublisher()
ValuePublisher выдает только отдельные значения, но нам необходимо, чтобы эти значения были доступны в виде списка. С этой задачей справляется простая очередь структуры данных.
struct Queue<T> {
    var list = [T]()
    mutating func enqueue(_ element: T) {
        list.append(element)
    }
    mutating func dequeue() -> T? {
        if !list.isEmpty {
            return list.removeFirst()
        } else {
            return nil
        }
    }
    func peek() -> T? {
        if !list.isEmpty {
            return list[0]
        } else {
            return nil
        }
    }
}
Эта очередь будет инстанцирована как переменная @State в ContentView
@State var doubleQueue = Queue<Double>()
Основной список должен быть инициализирован при появлении представления.
.onAppear {
    doubleQueue.list = [Double](repeating: 0.0, count: 50)
}
График также должен содержать информацию о списке, в котором хранятся значения.
Chart(data: doubleQueue.list)
На последнем этапе опубликованные значения ValuePublisher должны быть добавлены в очередь, а самое старое значение из очереди должно быть удалено.
.onChange(of: valuePublisher.value) { value in
    self.doubleQueue.enqueue(value)
    _ = self.doubleQueue.dequeue()
}
На этом все, вот полный ContentView, где я также немного изменил внешний вид графика.
import Charts
import SwiftUI
struct ContentView: View {
    @State var doubleQueue = Queue<Double>()
    @StateObject var valuePublisher = ValuePublisher()
    var body: some View {
        Chart(data: doubleQueue.list)
            .chartStyle(
                AreaChartStyle(.quadCurve, fill:
                    LinearGradient(gradient: .init(colors: [Color.blue.opacity(1.0), Color.blue.opacity(0.5)]), startPoint: .top, endPoint: .bottom)
                )
            )
            .onAppear {
                doubleQueue.list = [Double](repeating: 0.0, count: 50)
            }
            .onChange(of: valuePublisher.value) { value in
                self.doubleQueue.enqueue(value)
                _ = self.doubleQueue.dequeue()
            }
            .padding()
    }
}
Вот скриншот окончательного варианта приложения
Я также загрузил видео, чтобы вы могли посмотреть, как это выглядит, когда значения обновляются динамически.
Видео: Графики в SwiftUIРесурсы
===========
Источник:
habr.com
===========

===========
Автор оригинала: Tobias Wissmueller
===========
Похожие новости: Теги для поиска: #_razrabotka_pod_ios (Разработка под iOS), #_swift, #_ios, #_swift, #_swiftui, #_ios_app_development, #_blog_kompanii_otus (
Блог компании OTUS
)
, #_razrabotka_pod_ios (
Разработка под iOS
)
, #_swift
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 25-Ноя 23:11
Часовой пояс: UTC + 5