Я припиняю використовувати SwiftUI

28 серпня 2022 р

Оскільки CiderKit, авторські інструменти для The Untitled Project, починають формуватися та ставати все більш складними, мені потрібно було створювати вікна та елементи інтерфейсу користувача для різних цілей. Моя подорож почалася з Project Selector. Оскільки це також процес навчання, я вирішив використовувати SwiftUI і спробувати зрозуміти його внутрішню роботу.

Вибір проектуСелектор проекту CiderKit

За винятком нетрадиційного середовища та аспектів статусу SwiftUI, робота над перемикачем проектів пройшла гладко, і я закінчив її дуже задоволений SwiftUI. Я навіть створив власний модифікатор, щоб легше відображати сповіщення.

Але незабаром я був би розчарований.

Тоді я почав другий крок цієї чарівної подорожі SwiftUI із впровадженням інспекторів у реальному часі для свого редактора карт. Як і в будь-якому іншому інструменті створення, виберіть об’єкт, і його властивості, які можна перевірити, відображатимуться в спеціальному елементі інтерфейсу користувача.

Спочатку мені було важко з протоколами Swift і з тим, як ця мова обробляє генерики. Але це буде іншим разом.

Я також зіткнувся з деякими проблемами з інтерфейсом SwiftUI, який сильно покладався на фреймворки, що реалізують протокол View. Але оскільки протокол View має пов’язаний тип, ви можете використовувати його лише як обмеження. Однак деякі непрозорі ключові слова та типи прийшли на допомогу, і мені нарешті вдалося реалізувати спосіб, щоб кожен із доступних для вибору об’єктів надавав власні специфічні елементи інтерфейсу.

Редактор карт з інспектором

Мої перші тести були остаточними. Як ви можете бачити на малюнку вище, редактор карти знаходиться зліва, а інспектор справа. Спочатку я протестував один елемент інтерфейсу користувача, прапорець для вмикання та вимикання світла. Він працював нормально, і я тоді не помітив, що стане величезним вузьким місцем.

Справді, коли я почав впроваджувати складніші інспекторські подання з кількома текстовими полями зі кроковими кроками або без них або засобом вибору кольорів, усе стало надзвичайно повільним. Перегляд SpriteKit зазвичай відображає бездоганну швидкість 60 кадрів в секунду (якщо ви не використовуєте Intel iGPU). Але щоразу, коли SwiftUI потрібно оновити подання інспектора (під час руху або навіть просто введення тексту в текстове поле), рендеринг падає до дуже ривчастих 10–15 кадрів/с. Це було неприйнятно.

Я проаналізував усе це й виявив кілька речей. По-перше, вигляд, наданий об’єктом для вибору, повністю відтворювався під час кожного перемальовування. Я отримав деяку продуктивність, кешуючи його, але речі залишалися ледь придатними для використання. Виявилося, що перегляд інспектора SwiftUI не вдалося перемалювати досить швидко. Я шукав рішення в Інтернеті та закінчив тим, що написав відкладену версію ObservableObject, яка публікувала б свої зміни лише раз на секунду (див. код нижче).

імпорт об'єднати імпортна основа розширення ObservableObject { func delay(_ delay: TimeInterval = 1.0) -> DelayedObservableObject { return .init(object: self, delay: delay) } } @dynamicMemberLookup class DelayedObservableObject: ObservableObject where Object: ObservableObject { оригінальна приватна змінна: об'єкт приватна змінна підписка: AnyCancellable? fileprivate init(object: object, timeout: time range) { self.original = об'єкт підписка = object.objectWillChange .throttle(для: RunLoop.SchedulerTimeType.Stride(затримка), планувальник: RunLoop.main, останній: істина) .sink { [weak self] _ self?.objectWillChange.send() } } index(dynamicMember keyPath : WritableKeyPath) -> Object { get { original[keyPath : keyPath] } set { original[keyPath: keyPath] = newValue } } }

З рідшими перемальовуваннями знову стало доступним маніпулювання об’єктами на карті. Після цього бракувало лише кількох кадрів на секунду. Але значення в інспекторі були запізнілими, а отже, неточними під час взаємодії в редакторі карт (наприклад, під час використання інструмента «Переміщення»), який, очевидно, не був ідеальним.

Однак я розглянув цей дуже специфічний випадок використання, можливо, не дуже підходить для SwiftUI, і вирішив рухатися далі.

Мої перші інспектори запровадили, я почав працювати над іншою темою: редактором ресурсів Sprite. Цей інструмент дозволяє мені створювати складні ресурси з кількох спрайтів і, можливо, анімувати їх. Це відображається як аркуш головного вікна, і я хотів знову використати SwiftUI і продовжити свою...

Я припиняю використовувати SwiftUI
28 серпня 2022 р

Оскільки CiderKit, авторські інструменти для The Untitled Project, починають формуватися та ставати все більш складними, мені потрібно було створювати вікна та елементи інтерфейсу користувача для різних цілей. Моя подорож почалася з Project Selector. Оскільки це також процес навчання, я вирішив використовувати SwiftUI і спробувати зрозуміти його внутрішню роботу.

Вибір проектуСелектор проекту CiderKit

За винятком нетрадиційного середовища та аспектів статусу SwiftUI, робота над перемикачем проектів пройшла гладко, і я закінчив її дуже задоволений SwiftUI. Я навіть створив власний модифікатор, щоб легше відображати сповіщення.

Але незабаром я був би розчарований.

Тоді я почав другий крок цієї чарівної подорожі SwiftUI із впровадженням інспекторів у реальному часі для свого редактора карт. Як і в будь-якому іншому інструменті створення, виберіть об’єкт, і його властивості, які можна перевірити, відображатимуться в спеціальному елементі інтерфейсу користувача.

Спочатку мені було важко з протоколами Swift і з тим, як ця мова обробляє генерики. Але це буде іншим разом.

Я також зіткнувся з деякими проблемами з інтерфейсом SwiftUI, який сильно покладався на фреймворки, що реалізують протокол View. Але оскільки протокол View має пов’язаний тип, ви можете використовувати його лише як обмеження. Однак деякі непрозорі ключові слова та типи прийшли на допомогу, і мені нарешті вдалося реалізувати спосіб, щоб кожен із доступних для вибору об’єктів надавав власні специфічні елементи інтерфейсу.

Редактор карт з інспектором

Мої перші тести були остаточними. Як ви можете бачити на малюнку вище, редактор карти знаходиться зліва, а інспектор справа. Спочатку я протестував один елемент інтерфейсу користувача, прапорець для вмикання та вимикання світла. Він працював нормально, і я тоді не помітив, що стане величезним вузьким місцем.

Справді, коли я почав впроваджувати складніші інспекторські подання з кількома текстовими полями зі кроковими кроками або без них або засобом вибору кольорів, усе стало надзвичайно повільним. Перегляд SpriteKit зазвичай відображає бездоганну швидкість 60 кадрів в секунду (якщо ви не використовуєте Intel iGPU). Але щоразу, коли SwiftUI потрібно оновити подання інспектора (під час руху або навіть просто введення тексту в текстове поле), рендеринг падає до дуже ривчастих 10–15 кадрів/с. Це було неприйнятно.

Я проаналізував усе це й виявив кілька речей. По-перше, вигляд, наданий об’єктом для вибору, повністю відтворювався під час кожного перемальовування. Я отримав деяку продуктивність, кешуючи його, але речі залишалися ледь придатними для використання. Виявилося, що перегляд інспектора SwiftUI не вдалося перемалювати досить швидко. Я шукав рішення в Інтернеті та закінчив тим, що написав відкладену версію ObservableObject, яка публікувала б свої зміни лише раз на секунду (див. код нижче).

імпорт об'єднати імпортна основа розширення ObservableObject { func delay(_ delay: TimeInterval = 1.0) -> DelayedObservableObject { return .init(object: self, delay: delay) } } @dynamicMemberLookup class DelayedObservableObject: ObservableObject where Object: ObservableObject { оригінальна приватна змінна: об'єкт приватна змінна підписка: AnyCancellable? fileprivate init(object: object, timeout: time range) { self.original = об'єкт підписка = object.objectWillChange .throttle(для: RunLoop.SchedulerTimeType.Stride(затримка), планувальник: RunLoop.main, останній: істина) .sink { [weak self] _ self?.objectWillChange.send() } } index(dynamicMember keyPath : WritableKeyPath) -> Object { get { original[keyPath : keyPath] } set { original[keyPath: keyPath] = newValue } } }

З рідшими перемальовуваннями знову стало доступним маніпулювання об’єктами на карті. Після цього бракувало лише кількох кадрів на секунду. Але значення в інспекторі були запізнілими, а отже, неточними під час взаємодії в редакторі карт (наприклад, під час використання інструмента «Переміщення»), який, очевидно, не був ідеальним.

Однак я розглянув цей дуже специфічний випадок використання, можливо, не дуже підходить для SwiftUI, і вирішив рухатися далі.

Мої перші інспектори запровадили, я почав працювати над іншою темою: редактором ресурсів Sprite. Цей інструмент дозволяє мені створювати складні ресурси з кількох спрайтів і, можливо, анімувати їх. Це відображається як аркуш головного вікна, і я хотів знову використати SwiftUI і продовжити свою...

What's Your Reaction?

like

dislike

love

funny

angry

sad

wow