Ответ
matchedGeometryEffect — это модификатор в SwiftUI, который создает плавную анимацию плавного перемещения и изменения размера view между разными позициями в иерархии.
Принцип работы: Вы помечаете две (или более) view как «совпадающие», указывая одинаковые пространство имен (namespace) и идентификатор (id). При изменении условий (например, в if или switch) SwiftUI автоматически анимирует переход одной view в другую, а не простое появление/исчезновение.
Базовый пример (анимация переключения размера):
struct ContentView: View {
@Namespace private var namespace // 1. Создаем пространство имен
@State private var isExpanded = false
var body: some View {
VStack {
if isExpanded {
// 2. View в большом состоянии
RoundedRectangle(cornerRadius: 16)
.matchedGeometryEffect(id: "shape", in: namespace) // Совпадающий ID
.frame(width: 200, height: 200)
.foregroundColor(.blue)
} else {
// 3. View в маленьком состоянии (может быть в другом месте VStack)
RoundedRectangle(cornerRadius: 16)
.matchedGeometryEffect(id: "shape", in: namespace) // Тот же ID
.frame(width: 100, height: 100)
.foregroundColor(.blue)
}
Button("Анимировать") { isExpanded.toggle() }
}
.animation(.spring(), value: isExpanded)
}
}
Ключевые параметры:
id: Hashable— уникальный идентификатор для связи view.in: Namespace.ID— пространство имен, ограничивающее область связи.properties: MatchedGeometryProperties— какие свойства анимировать (.frame,.positionи др.).anchor: UnitPoint— точка привязки для совмещения view.
Важные ограничения:
- Работает только внутри одного
ViewBuilder(например, внутри одногоbody). - Если view с совпадающим
idисчезает из иерархии, анимация прерывается. - Часто комбинируется с
transitionдля более сложных эффектов.