Matched Geometry Effects
Если у вас имеется представление, которое может отображаться в разных частях экрана, и при этом смену положения представления необходимо делать анимировано, то для этого можно использовать модификатор matchedGeometryEffect
, который позволит сделать это очень плавно.
В iOS 13, что бы поменять два представления местами мы могли сделать это следующим образом:
struct ContentView: View {
@State private var isFlipped = false
var body: some View {
VStack {
if isFlipped {
Circle()
.fill(Color.red)
.frame(width: 44, height: 44)
Text("Taylor Swift")
.font(.headline)
} else {
Text("Taylor Swift")
.font(.headline)
Circle()
.fill(Color.red)
.frame(width: 44, height: 44)
}
}
.onTapGesture {
withAnimation {
self.isFlipped.toggle()
}
}
}
}
При таком подходе два представления меняются местами, но при это смена позиций происходит не плавно:
С новым модификатором можно добиться большего. Для этого его нужно вызвать у тех представлений, которые нужно поменять местами, но для начала нужно объявить еще одно свойство с оберткой @Namespace
, которое определит глобальное пространство имен для наших представлений. Данное свойство объединяет представления в один общий сценарий для анимации:
@Namespace private var animation
Теперь мы можем вызвать модификатор .matchedGeometryEffect
у тех представлений, которые нам необходимо задействовать в анимированной смене своего местоположения. В параметр YourIdentifierHere
необходимо передать уникальный идентификатор, который будет использоваться каждой парой наших представлений:
.matchedGeometryEffect(id: "Circle", in: animation)
И соответственно для текста:
.matchedGeometryEffect(id: "Name", in: animation)
В итоге это позволит менять представления местами очень плавно:
Весь код выглядит так:
struct ContentView: View {
@Namespace private var animation
@State private var isFlipped = false
var body: some View {
VStack {
if isFlipped {
Circle()
.fill(Color.red)
.frame(width: 44, height: 44)
.matchedGeometryEffect(id: "Circle", in: animation)
Text("Taylor Swift")
.font(.headline)
.matchedGeometryEffect(id: "Name", in: animation)
} else {
Text("Taylor Swift")
.font(.headline)
.matchedGeometryEffect(id: "Name", in: animation)
Circle()
.fill(Color.red)
.frame(width: 44, height: 44)
.matchedGeometryEffect(id: "Circle", in: animation)
}
}
.onTapGesture {
withAnimation {
self.isFlipped.toggle()
}
}
}
}
Курсы по языку Swift, доступные каждому: learnmetoo.info