FabBar — точная копия таб бара Liquid Glass из iOS 26 с тонированной плавающей кнопкой действия.
Во многих приложениях есть основное действие, которое пользователи выполняют часто: создание публикации в социальных сетях, запись приема пищи, создание задачи. Размещение этого действия в нижней части экрана позволяет держать его в зоне большого пальца и постоянно видеть, уменьшая неудобства для наиболее распространенного пользовательского сценария.
В iOS 26 с панелью вкладок разработчики могут объявить вкладку с ролью .search и использовать ее в качестве основного действия, но у этого подхода есть несколько проблем:
- Вы обманываете систему, это на самом деле не вкладка поиска.
- VoiceOver читает ее как вкладку, а не как кнопку.
- Требуется слушатель изменений вкладок и их отмена в SwiftUI, что подвержено состояниям гонки.
- Отсутствует возможность изменения цвета, поэтому это выглядит как вкладка поиска, а не как основное действие.
У разработчиков есть еще один вариант: размещение пользовательской плавающей кнопки действия над панелью вкладок. Обычно она размещается в правой части экрана. Однако в iOS 26 с центрированной панелью вкладок это создает неудобную компоновку. При наличии менее четырех вкладок по обе стороны панели остается пустое пространство, а размещение кнопки FAB на крае создает несбалансированное пустое пространство. При этом нет возможности настроить расположение или размер стандартной панели вкладок, чтобы обойти это.
FabBar предлагает одно решение: полностью пересоздать панель вкладок для полного контроля.
Как это работает
FabBar предоставляет API SwiftUI, но внутри использует UIKit.
Ключевая проблема в точном воссоздании панели вкладок — это эффект «пузырькового» интерактивного стекла при касании. Этот эффект доступен только для панелей вкладок и еще одного компонента: сегментированных элементов управления. FabBar использует UISegmentedControl в качестве основы, скрывая стандартные метки и накладывая пользовательские представления элементов вкладок.
Почему UIKit? FabBar манипулирует внутренней иерархией представлений UISegmentedControl, чтобы скрыть собственные метки и наложить пользовательские представления. Это невозможно с помощью Picker из SwiftUI. Кроме того, смешивание пользовательских элементов управления UIKit с методом .glassEffect() из SwiftUI вызывает проблемы с частотой кадров во время сенсорного взаимодействия.
Этот подход по своей природе ненадежен и может перестать работать после обновлений ОС.

