Apple рассматривает возможность изменений в App Store. Главная цель - увеличить доход, который компания получает от своей платформы. Инициативу продвигают новый генеральный директор Джон Тернус и старший вице-президент по сервисам Эдди Кью. Конкретные изменения пока не определены, но речь идет о поиске способов повысить маржу и увеличить долю повторяющихся поступлений.
Почему ушел Фил Шиллер:
Новый курс стал одной из причин, по которой Фил Шиллер покинул руководство App Store. 66-летний топ-менеджер хотел уделять больше времени семье и благотворительности, но, по информации Bloomberg, одновременно опасался, что попытка извлечь из магазина еще больше денег усилит противостояние Apple с разработчиками и государственными регуляторами.
Шиллер не поддерживал идею дальнейшего увеличения доходов от App Store. Он считал, что такие шаги могут еще сильнее раздражать разработчиков и регулирующие органы. Открытого конфликта внутри компании не произошло, однако Шиллер не захотел участвовать в реализации новой стратегии.
Как Шиллер относился к разработчикам:
Бывший глава отдела проверки приложений Apple Филлип Шумейкер, напротив, рад уходу Шиллера. Его мнение: «У него не было ни малейшего желания садиться за стол с разработчиками и модернизировать правила. Не из злого умысла, а из убеждения, что правила пишет Apple, а разработчики должны им следовать - и точка».
Что может измениться:
Есть несколько потенциальных способов увеличить прибыльность App Store.
Конкретных изменений Apple еще не объявляла. Пока это лишь возможные варианты. Но ясно одно: новое руководство Apple рассматривает App Store не только как платформу распространения приложений, но и как направление, из которого можно получать больше регулярной выручки и более высокую прибыль.
Какой путь выберет Apple - покажет время. Но уже сейчас очевидно, что отношения с разработчиками могут измениться. Вопрос в том, в какую сторону.
Подписаться на канал:
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯14👀8👍5❤1🤔1
Apple выпустила руководство по адаптации приложений под iPhone Duo - свой первый складной смартфон. Главная новость: отдельного FoldableKit нет. Apple просто продолжает двигать разработчиков в сторону адаптивных интерфейсов.
С чего стоит начать:
Приложение будет работать на iPhone Duo, даже если оно не собрано при помощи iOS 27 SDK. Но чтобы использовать все возможности, нужно обновление.
В режиме совместимости, как iPhone-приложение на iPad, все будет работать не очень красиво. Если собрать с iOS 27 SDK, появится полноэкранный режим с черным статус-баром. С iOS 27.1 SDK можно сделать полноценную поддержку.
Для тестирования нужно скачать Xcode 27.1 и выбрать симулятор iPhone Duo в Device Hub. Там можно открыть, закрыть, повернуть и сложить устройство, чтобы посмотреть, как ведет себя layout.
Как работает адаптация:
На внешнем экране iPhone Duo все выглядит как на обычном iPhone: regular для вертикального положения, compact для горизонтального. На внутреннем экране - regular и по горизонтали и по вертикали. Это позволяет показывать sidebar и больше контента.
Внутренний экран не обязан соблюдать supportedInterfaceOrientations. Apple прямо говорит: не проверяйте ориентацию для layout-решений. Используйте size classes.
Проблема с UIScreen.main:
У iPhone Duo два дисплея, поэтому понятие UIScreen.main становится неоднозначным. Apple объявила такие обращения устаревшими.
Если действительно нужен экран конкретного окна, его можно получить через UIWindowScene:
window?.windowScene?.screen
Но лучше вообще работать через environment, traits и размеры самой scene.
Асимметричные safe areas:
Safe area теперь может быть асимметричной. Формула width - leftInset * 2 больше не гарантирует правильный результат. Левый и правый inset могут отличаться из-за формы устройства, камеры и системного UI.
Apple советует считать каждую сторону отдельно. Весь интерактивный UI держать внутри safe area, а фон растягивать edge-to-edge.
Автоматическая адаптация:
Если вы используете стандартную навигацию, большая часть адаптации произойдет автоматически. NavigationSplitView, UISplitViewController, TabView, UITabBarController, sheets, popovers и alerts уже умеют адаптироваться к разным положениям Duo.
На внутреннем экране tab bar можно автоматически превратить в sidebar. Для SwiftUI это настройка default tab bar placement, для UIKit - preferred placement.
ReservedRegion:
В iOS 27.1 появилась новая возможность - ReservedRegion в SwiftUI и UIViewReservedRegion в UIKit. Она нужна кастомному edge-to-edge UI, чтобы сказать системе: дай максимум пространства, но не залезай туда, где уже живет системный интерфейс.
Это полезно для собственных баров и сложных лайаутов.
iPhone Duo не приносит отдельный фреймворк. Apple просто продолжает давить в сторону адаптивного интерфейса. Не определять устройство. Не ориентироваться на конкретную ширину. Не считать, что экран один. Не ожидать симметричные safe areas. Если вы уже следовали этим правилам, у вас будет минимум работы по адаптации.
Подписаться на канал:
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤8🤯4 4🔥1🤝1
Компания Apple опубликовала официальные макеты iPhone Duo и iPhone 18. Они доступны в разделе Product Bezels и предназначены для использования в маркетинговых материалах, дизайне и разработке. При работе с макетами Apple рекомендует сверяться с Marketing Resources и Identity Guidelines.
Размер экрана iPhone 18 не изменился - существующие layout-решения продолжат работать без адаптации. iPhone Duo, как первое складное устройство Apple, требует нового подхода: у него два экрана, и макеты позволяют увидеть устройство в открытом, закрытом и сложенном состояниях.
Подписаться на канал:
Please open Telegram to view this post
VIEW IN TELEGRAM
❤15👍8🔥3🗿1 1
С выходом iPhone Duo компания Apple добавила не только новый форм-фактор, но и новые API для работы с двумя экранами.
Режимы совместимости:
Приложение будет работать на iPhone Duo, даже если оно не собрано с использованием iOS 27 SDK. Но в режиме совместимости от статус-бара появится черный отступ. Это значит, что интерфейс не будет занимать весь экран.
С новым SDK iOS 27.1 приложение займет все доступное пространство. Поэтому если вы планируете поддержку iPhone Duo, стоит обновиться до iOS 27.1 SDK.
Что такое ArrangementView:
ArrangementView - это контейнер, который управляет двумя частями контента: основной и дополнительной. Вы описываете их отношение, а система решает, как их расположить в зависимости от доступного пространства и конфигурации устройства.
Вместо ручного переключения layout при изменении геометрии вы описываете роли контента. SwiftUI сам определяет, как их показать.
NavigationStack {
ArrangementView {
PlayerView()
} secondary: {
UpNextView()
}
}Стили компоновки:
Есть два встроенных стиля: split и overlay.
Split - для контента, который должен оставаться видимым независимо. Основное и дополнительное представления разделяют доступное пространство. Если контейнер широкий, SwiftUI предпочитает горизонтальное разделение, иначе - вертикальное.
ArrangementView {
PlayerView()
} secondary: {
TranscriptView()
}
.arrangementViewStyle(.split)Можно ограничить разделение конкретной осью:
.arrangementViewStyle(
.split.axes(.horizontal)
)
Overlay - для контента с отношением «передний план - задний план». Одно представление может располагаться поверх другого.
ArrangementView {
ContentView()
} secondary: {
ControlsView()
}
.arrangementViewStyle(.overlay)Дочернее представление может узнать, находится ли оно поверх другого, через environment-значение overlayArrangementZIndex.
struct ControlsView: View {
@Environment(\.overlayArrangementZIndex)
private var zIndex
var body: some View {
Controls(compact: zIndex > 0)
}
}ReservedRegion:
iPhone Duo вводит ReservedRegion - области, которые представляют аппаратные части, влияющие на доступный контент. SwiftUI может запрашивать их через GeometryProxy.
GeometryReader { proxy in
let regions = proxy.reservedRegions(kind: .division)
}Division regions разделяют доступные области, например вокруг шарнира. Occlusion regions описывают аппаратные части, которые закрывают часть дисплея.
iPhone Duo приносит новые API для адаптивной компоновки. Режимы совместимости дают время на миграцию. ArrangementView позволяет описывать роли контента, а не жестко задавать layout.
Главная идея: перестать кодировать каждую возможную конфигурацию вручную. Вместо этого описать отношение между частями интерфейса и позволить системе выбрать подходящее представление.
Подписаться на канал:
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Кот Денисова
Сейчас появилось много людей, которые раньше не могли написать даже простую программу, но с приходом ИИ-агентов вдруг почувствовали себя настоящими разработчиками. Они искренне верят, что за пару вечеров могут создать продукт, готовый к выходу на рынок. «Смотри, какую крутую штуку я за вечер сделал!» - делятся они своими успехами.
Да, выглядит впечатляюще. Для домашнего использования или пет-проекта этого, возможно, даже достаточно. Но когда речь заходит о том, чтобы выкатить такое на сотни тысяч пользователей, становится понятно: это игрушки, а не продукты. Проблема не в том, что они делают лендинги или простые сайты. Они лезут в сложные системы, даже не осознавая, какой объем знаний и опыта нужен, чтобы довести технический продукт до ума.
В чем здесь главная ловушка:
ИИ-агенты - это мощный инструмент, но они не заменяют понимание того, как устроена разработка. Чтобы эффективно работать с ними, нужна сноровка. Нужно уметь не просто сформулировать запрос, а задать правильные правила, ограничения, архитектурные рамки. Иначе агент будет генерировать все, что ему вздумается, а не то, что действительно нужно.
Без этого фундамента код превращается в кашу. Он может работать на маленьком объеме данных, но как только нагрузка вырастает, все начинает сыпаться. И человек, который «за вечер сделал приблуду», просто не понимает, почему это произошло. Потому что он не знает, как работают базы данных под нагрузкой, как кешировать ответы, как обрабатывать ошибки и как проектировать архитектуру, которая не развалится через месяц.
Где место вайбкодингу:
Для экспериментов, для обучения, для прототипов - это отлично. Быстро проверить идею, накидать интерфейс, посмотреть, как что работает. Дома, в ознакомительных целях - супер. Но лезть в боевые проекты без понимания технической базы - это все равно что пытаться управлять самолетом, прочитав инструкцию к игрушке.
Результат таких попыток обычно один: проект с треском проваливается, код переписывают нормальные разработчики, а автор остается с убеждением, что все пропало и ИИ ничего не умеет. Хотя на самом деле проблема была не в ИИ, а в непонимании того, что именно нужно делать и как.
Вайбкодинг - это не замена инженерному мышлению, а его инструмент. Если у вас нет базы, агент не сделает вас разработчиком. Он сделает вас оператором, который генерирует код, не понимая его смысла. А в серьезных проектах это не прокатит.
Подписаться на канал:
Please open Telegram to view this post
VIEW IN TELEGRAM
💯17👍8🤝3❤1👀1🗿1
В Xcode 27.2 компания Apple добавила новый формат конфигурации проекта. Внутри привычного .xcodeproj теперь может лежать project.xcproj вместо project.pbxproj. И это не просто смена расширения.
Формат .pbxproj годами был одним из самых неприятных файлов в iOS-проекте. Огромный плоский список объектов. Ссылки через непонятные ID, merge-конфликты после добавления одного файла. Ручное редактирование почти всегда с мыслями «только бы проект в Xcode открылся».
Что представляет собой новый формат:
Новый .xcproj - это иерархический, самодокументируемый JSON. Структура файла становится ближе к тому, что мы видим в Xcode. Apple выделяет три причины перехода:
Как перейти на новый формат:
В Xcode 27.2 новые проекты по умолчанию уже используют JSON. Старые можно перевести вручную.
Нужно выбрать проект в навигаторе, открыть инспектор файла и в разделе документ проекта выбрать JSON из меню формат проекта. После этого внутри .xcodeproj файл project.pbxproj удаляется и появляется project.xcproj.
Сам .xcodeproj никуда не исчезает. Schemes, Package.resolved, user data и остальная структура остаются как были. Это не новый способ описывать проект вроде Tuist или XcodeGen. Это тот же Xcode project model, просто в более удобном формате.
Совместимость:
Новый формат поддерживается всеми версиями Xcode 27 и новее. Для перехода не обязательно одновременно обновлять всю команду до 27.2.
Если что-то пошло не так, миграция обратима через git: вернуть project.pbxproj и удалить .xcproj.
Apple наконец-то избавилась от legacy-формата, который годами раздражал разработчиков. .pbxproj был неудобен для чтения, плохо переносил слияния и почти не поддавался ручному редактированию. Новый .xcproj решает эти проблемы.
Для людей это означает более понятные сравнения изменений и меньше конфликтов. Для агентов - возможность безопасно менять настройки проекта. Для инструментов - типизированный доступ к структуре через библиотеку.
Миграция не обязательна, но если вы уже на Xcode 27, стоит попробовать. Особенно если работаете в команде, где merge-конфликты стали постоянной болью.
Подписаться на канал:
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍6❤2🤯2🙏1
This media is not supported in your browser
VIEW IN TELEGRAM
В бета-версии Xcode 27.1 появился симулятор iPhone Duo. В Device Hub можно проверить, как приложение ведет себя в разных состояниях складного устройства: открытом, закрытом, повернутом и сложенном. Это позволяет оценить адаптацию интерфейса к внутреннему и внешнему экрану до официального старта продаж.
Подписаться на канал:
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13 7👍4❤1🙏1
Swift 6.4 вышел. Это обновление получилось насыщеннее, чем обычно. Язык продолжает выходить за пределы разработки под Apple: серверы, Android, WebAssembly, embedded и системный код.
Упрощение повседневного кода:
Несколько изменений делают код чище и понятнее:
@diagnose, который позволяет управлять предупреждениями компилятора прямо в коде: подавлять, повышать до ошибок или включать.Новые API для работы с памятью:
Swift 6.4 продолжает развивать тему владения и производительности:
Инструменты и сборка:
Интероп и платформы:
swift.org.Swift 6.4 - насыщенное обновление. Язык становится удобнее для повседневной работы и одновременно расширяет границы: серверы, Android, WebAssembly, embedded. Embedded Swift получил поддержку any типов, untyped throws, метатипов и парсинга чисел с плавающей точкой. Новые API для работы с памятью позволяют писать быстрый код без потери безопасности. Инструменты сборки и отладки становятся лучше.
Подписаться на канал:
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Кот Денисова
Всем привет! Сегодня хочу разобрать статью, в которой автор честно говорит про вечную боль отношений между разработчиками и менеджерами. И что особенно важно - ему довелось испытать на себе обе роли: больше десяти лет он был инженером, а потом перешел в менеджмент.
Причины возникновения ненависти к менеджерам:
Автор статьи рассказывает о пяти вещах, которые могут убить мотивацию разработчиков и привести к возникновению ненависти к менеджерам:
Бесконечные созвоны и прерывания:
Ты наконец в рабочем процессе, разбираешься с багом, который давно наблюдается в проде. Наушники на голове, ничего не отвлекает. И тут: «Привет, давай созвонимся на пару минут?». И все. Потом нужен минимум час, чтобы вспомнить, где ты был и о чем думал. Плохие менеджеры не понимают, что программирование требует глубокого фокуса. Они относятся к разработчикам как к работягам на конвейере - поставили на паузу, сняли с паузы, поехали дальше.
Это же просто кнопка:
Менеджеры, которые никогда не писали код, принимают технические решения. Обещают заказчику то, что невозможно реализовать. Назначают дедлайны без консультации с командой. А когда разработчик пытается объяснить, почему задача не на час, а на три дня - его называют душным и не командным игроком, который замедляет команду.
Синдром невидимого инженера:
Ты ночами и в выходные делаешь невозможное. Пишешь элегантное решение сложной проблемы. А на общем собрании менеджер рассказывает, «каких успехов я добился в этом квартале», хотя всю работу выполнил не он. Менеджер может и не хотеть украсть чужой успех - он просто привык выступать лицом проекта. Но разработчику, который реально сделал работу, от этого не легче.
Воронка бесконечных встреч:
Стендап на 45 минут. Созвон, чтобы запланировать другие созвоны. Ретроспектива, где ничего не меняется. Календарь превращается в кладбище продуктивности. Разработчики любят строить, а не сидеть на совещаниях. Каждая лишняя встреча крадет время у того, зачем они вообще пришли в профессию.
Театр обратной связи:
Годовое ревью от менеджера, которого ты почти не видел. Шаблонные фразы из HR-методичек. «Соответствует ожиданиям» - хотя ты в одиночку предотвратил три аварии. Повышение? «Может в конце года». А тот новый сотрудник с половиной твоего опыта, но вдвое большими коммуникативными навыками, только что получил повышение.
Неудобная правда:
Перейдя в менеджмент, автор обнаружил, что сам начал демонстрировать те же паттерны, на которые жаловался как разработчик. Управление - это одиночество. Ты принимаешь решения с неполной информацией, балансируешь между требованиями начальства и выгоревшей командой. Тебя оценивают по метрикам, которые ты не контролируешь напрямую.
Большинство менеджеров не злодеи. Они так же фрустрированы, как и их команды. Их прерывают - они прерывают. Их давят принять любое решение - они принимают плохие. А привычку присваивать чужие успехи они подхватили потому, что в корпоративной среде без этого не выжить: если не покажешь, что именно ты приносишь результат, тебя заменят как бесполезного.
Разработчики ненавидят не менеджеров. Они ненавидят плохой менеджмент. При этом сам переход из инженера в управленца - это смена профессии, а не просто еще одна роль. И если менеджер, читая это, узнал себя в антипаттернах, пора задуматься. А если инженер узнал своего менеджера - может, стоит просто честно поговорить о том, что нужно обеим сторонам, чтобы работать эффективно. Лучшие команды - не те, где все друзья, а те, где понимают роль друг друга, уважают чужие сложности и вместе движутся к общей цели.
Подписаться на канал:
Закрытый канал:
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13💯5❤4👀2🙏1🗿1
Swift автоматически создает memberwise инициализатор для структуры, если мы не объявили его вручную. Это работает, пока в структуре нет приватных свойств. Добавление одного приватного свойства ломает инициализатор для всей структуры. В Swift 6.4 это наконец-то было исправлено.
В чем была проблема:
Рассмотрим простую структуру:
struct Post {
var title: String
var body: String
}
Memberwise инициализатор создается автоматически, и мы можем инициализировать объем нашей структуры: Post(title: "Hello", body: "Hello, World!"). Но стоит добавить приватное свойство:
struct Post {
var title: String
var body: String
private var id = UUID()
}
И инициализатор становится приватным. Потому что синтезированный memberwise инициализатор включает все хранимые свойства и его уровень доступа не может быть выше, чем у самого недоступного свойства, которое он затрагивает.
То есть id приватный, значит и инициализатор приватный. Вызвать его извне нельзя. Одно приватное свойство отнимает инициализатор у всей структуры.
Что изменилось в Swift 6.4:
Теперь свойства, которые менее доступны, чем максимально возможный уровень доступа инициализатора, исключаются из него.
struct Post {
var title: String
var body: String
private var id = UUID()
// Создается автоматически в Swift 6.4:
// internal init(title: String, body: String) { ... }
}
let post = Post(title: "Hello", body: "Hello, World!") // Теперь работает
id сохраняет свое значение по умолчанию, а инициализатор остается internal.
Когда это работает:
Свойство исключается из memberwise инициализатора, когда выполняются два условия. Оно менее доступно, чем максимальный уровень доступа инициализатора. И оно имеет значение по умолчанию.
Максимальный уровень доступа - это наивысший уровень среди свойств, которые могут быть включены в memberwise инициализатор, но не выше internal.
Значение по умолчанию - это либо явно указанное значение, либо значение, которое Swift присваивает автоматически. Например опциональное свойство получает nil по умолчанию.
Когда поведение не меняется:
Есть несколько случаев, когда все работает как раньше:
В Swift 6.4 свойство исключается из синтезированного memberwise инициализатора, когда оно менее доступно, чем максимальный уровень доступа инициализатора и имеет значение по умолчанию.
На практике это значит, что добавление приватного идентификатора или внутреннего состояния в структуру больше не отнимает memberwise инициализатор. Рефакторинг упрощается: можно добавлять приватные свойства без ручного написания инициализатора.
Полного контроля над memberwise инициализатором пока нет. Явное указание, какие свойства включать или исключать заявлено как направление будущего развития. Но основная проблема была решена.
Подписаться на канал:
Please open Telegram to view this post
VIEW IN TELEGRAM
В Swift 6.4 добавили Hashable для нескольких типов стандартной библиотеки. Раньше их можно было сравнивать, но нельзя было использовать как ключи словаря или элементы в Set. Изменения небольшие, но убирают лишние преобразования и упрощают несколько паттернов.
Dictionary.Keys стал Hashable:
Свойство keys у словаря возвращает представление Dictionary.Keys. Раньше его можно было перебирать и сравнивать, но не использовать в Set или как ключ словаря.
Теперь это работает напрямую:
var knownSchemas: Set<[String: Any].Keys> = []
knownSchemas.insert(payload.keys)
Тип значения словаря не обязан быть Hashable. Ключи словаря уже имеют это требование, поэтому [String: Any].Keys получает соответствие.
Семантика равенства:
Два Dictionary.Keys равны, когда содержат одинаковые ключи. Значения словаря и порядок обхода не влияют на результат.
let first = ["id": 1, "name": 10]
let second = ["name": 20, "id": 2]
print(first.keys == second.keys) // true
Оба словаря содержат ключи id и name, поэтому их представления ключей равны.
Хеширование следует той же логике. Перестановка ключей не меняет хеш. Это работает, потому что порядок обхода словаря не является частью его идентичности.
Когда порядок важен, нужно использовать упорядоченную коллекцию:
let orderedKeys = dictionary.keys.sorted()
Когда это полезно:
Новое соответствие пригодится, когда набор полей важнее, чем значения под ними. Например приложение может отслеживать схемы динамических данных без создания отдельного Set для каждого словаря:
struct PayloadSchemaRegistry<Value> {
private var schemas: Set<Dictionary<String, Value>.Keys> = []
mutating func register(_ payload: [String: Value]) {
schemas.insert(payload.keys)
}
func contains(_ payload: [String: Value]) -> Bool {
schemas.contains(payload.keys)
}
}
Возможные сценарии: удаление повторяющихся структур данных, кеширование результатов по доступным полям, группировка метаданных по набору ключей, передача представлений ключей в обобщенные API, требующие Hashable.
Dictionary.Keys: Hashable - самое полезное изменение. Оно позволяет представлениям ключей напрямую участвовать в Set, словарях и обобщенных API без промежуточных преобразований.
CollectionOfOne и EmptyCollection закрывают недостающие части обобщенной модели стандартной библиотеки.
UnownedTaskExecutor: Hashable решает более узкую задачу, но дает инфраструктуре конкурентности эффективный способ связывать ресурсы с идентификаторами исполнителей.
Главное правило не изменилось: если вы храните невладеющую ссылку на исполнителе, вы должны сами следить за тем, чтобы она не осталась висеть после того, как исполнитель завершил работу.
Подписаться на канал:
Please open Telegram to view this post
VIEW IN TELEGRAM
На iPhone Duo элементы управления навигацией, действия тулбара и вкладки могут перемещаться в общую вертикальную панель, расположенную по краю экрана. Это освобождает больше пространства для контента. Приложения, собранные с iOS 27.1 SDK, получают эту адаптацию через стандартные контейнеры: NavigationStack, NavigationSplitView и TabView. Мы по-прежнему объявляем действия тулбара в привычных местах, а SwiftUI решает, как их показать в текущем контексте.
Управление осью элемента:
SwiftUI использует содержимое элемента, чтобы решить, может ли он переместиться в вертикальную панель. Стандартные элементы с символами участвуют автоматически. Текстовые элементы и сложное кастомное содержимое по умолчанию остаются горизонтальными. Модификатор axisBehavior(_:) позволяет переопределить это поведение для отдельных элементов тулбара.
Например можно создать меню с кастомной меткой, которая объединяет фигуру и текст. С автоматическим поведением SwiftUI оставит это меню в горизонтальной панели. Если метка достаточно маленькая, чтобы поместиться в вертикальную панель, можно применить .axisBehavior(.verticalPreferred) к элементу тулбара. Тогда меню присоединится к другим элементам вдоль правого края.
Для кастомного содержимого, которому нужно больше горизонтального пространства, можно использовать .horizontalOnly, чтобы оставить элемент в горизонтальной панели. Это также полезно, когда содержимое элемента меняется и мы хотим, чтобы его ось оставалась стабильной.
Адаптация содержимого под расположение панели:
Иногда нужно, чтобы кастомное содержимое тулбара подстраивалось под расположение панели. Для этого есть новое значение окружения toolbarVerticalEdge. Оно говорит, с какой стороны система разместит вертикальную панель: слева или справа. Если вертикальная панель не используется, значение равно nil - и тогда можно выбрать горизонтальную компоновку.
Допустим, у нас есть элемент тулбара с настройкой .axisBehavior(.verticalPreferred), то есть он может переместиться в вертикальную панель. Его метка состоит из фигуры и текста. Мы хотим, чтобы в горизонтальной панели они стояли рядом, а в вертикальной - друг под другом.
Для этого проверяем toolbarVerticalEdge. Если он равен nil, располагаем элементы горизонтально. Если нет - вертикально.
Отключение вертикальных панелей:
Для интерфейсов, которым нужно больше горизонтального пространства, можно отказаться от вертикальных панелей с помощью модификатора toolbarVerticalBehavior(_:). Установка в disabled возвращает содержимое панели в стандартные горизонтальные верхнюю и нижнюю панели и восстанавливает горизонтальное расположение статус-бара.
Например в списке, где единственное действие тулбара - кнопка закрытия, вертикальная панель оставляет меньше ширины для контента. Если применить модификатор внутри списка, он управляет панелями списка независимо от представляющего представления.
Внутри окна SwiftUI использует поведение панели, указанное самым верхним представлением в NavigationStack, выбранной вкладкой в TabView или самой правой колонкой в NavigationSplitView.
Установка разного поведения панели на представлениях в одном стеке навигации может заставить панели переключаться между горизонтальным и вертикальным расположением при навигации. Apple рекомендует сохранять поведение согласованным, а не менять его часто во время навигации или в ответ на временное состояние представления.
iPhone Duo приносит новые API для работы с тулбарами. axisBehavior(_:) управляет осью отдельного элемента. toolbarVerticalEdge показывает, используется ли вертикальная панель. toolbarVerticalCompressionBehavior(_:) задает приоритет между вкладками и действиями. toolbarVerticalBehavior(_:) позволяет отключить вертикальные панели там, где они мешают. Эти инструменты дают контроль над тем, как интерфейс адаптируется к складному устройству. Но Apple рекомендует не менять поведение слишком часто. Лучше один раз определить, как должны выглядеть панели, и придерживаться этого решения.
Подписаться на канал:
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13 6🔥3❤2🙏1👀1