#swiftui
#swiftui
Вопрос:
Здесь я получил 2 фигуры, один прямоугольник и один круг, которые при нажатии кнопки только одна из них стала видна пользователю, я попытался использовать @Namespace для этого преобразования, но ничего не получилось!
МОЯ цель: иметь красивую и плавную анимацию преобразования из одной формы в другую.
struct ContentView: View {
@State var action: Bool = false
@Namespace var sameShape
var body: some View {
ZStack
{
Group
{
if action
{
Circle()
.fill(Color.blue).frame(width: 150, height: 150, alignment: .center)
.matchedGeometryEffect(id: "Dakota148Zero", in: sameShape)
}
else
{
Rectangle()
.fill(Color.red).frame(width: 150, height: 150, alignment: .center)
.matchedGeometryEffect(id: "Dakota148Zero", in: sameShape)
}
}
.animation(.easeInOut)
VStack
{
Spacer()
Button("transform") { action.toggle() }.font(Font.largeTitle).padding()
}
}
}
}
Комментарии:
1. Проверьте это, это действительно круто — swiftui-lab.com/swiftui-animations-part1
Ответ №1:
Вот способ сделать это, представив круг и квадрат как a RoundedRectangle
с разными cornerRadius
значениями:
struct ContentView: View {
@State var action = false
var body: some View {
ZStack
{
RoundedRectangle(cornerRadius: action ? 0 : 75)
.fill(action ? Color.red : .blue)
.frame(width: 150, height: 150, alignment: .center)
.animation(.easeInOut)
VStack
{
Spacer()
Button("transform") {
action.toggle()
}
.font(Font.largeTitle)
.padding()
}
}
}
}
Комментарии:
1. большое спасибо, это было первое, что я подумал об этом! ЛоЛ, но я ищу достойную анимацию преобразования
2. Учитывая, что мое решение и это здесь, мне интересно, что такое «достойная анимация преобразования», которой не являются эти два решения? @Omar
3. @IiroAlhonen, да, это создает иллюзию преобразования, но я не могу использовать этот cornerRadios для преобразования в другую форму, такую как звезда, суть моего вопроса — анимация преобразования, а не решение ее примера
Ответ №2:
Group
это не настоящий контейнер, поэтому не сохраняйте анимацию. Group
Замените некоторым стеком, например
VStack
{
if action
// ... other code no change
Комментарии:
1. Согласен. Замените Group на ZStack, и это должно сработать.
2. Я уже внес изменения, которые не увенчались успехом! даже используется с анимацией в кнопке, ничего
Ответ №3:
При выходе iOS14 вы можете использовать matchedGeometryEffect() . Если вы используете iOS14, я бы рекомендовал этот подход.
Итак, в вашем решении, если вы замените action.toggle()
на withAnimation{self.action.toggle()}
в своем коде кнопки, он будет анимироваться.
Button("transform") {
withAnimation{self.action.toggle()}
}
.font(Font.largeTitle).padding()
Это решение работает на симуляторе для меня (Xcode 12.1, iPhone 11 iOS 14.1):
import SwiftUI
struct ContentView: View {
@State var action: Bool = false
@Namespace var transition
var body: some View {
ZStack {
Group {
if action {
Circle()
.fill(Color.blue).frame(width: 150, height: 150, alignment: .center)
.matchedGeometryEffect(id: "shape", in: transition)
} else {
Rectangle()
.fill(Color.red).frame(width: 150, height: 150, alignment: .center)
.matchedGeometryEffect(id: "shape", in: transition)
}
}
.animation(.easeInOut)
VStack {
Spacer()
Button("transform") { withAnimation{self.action.toggle()} }.font(Font.largeTitle).padding()
}
}
}
}
matchedGeometryEffect() не хочет так красиво анимировать разные формы (включая cornerRadius) или цвета, не уверен, является ли это ошибкой, которая будет исправлена в будущих патчах, или просто функцией, которую нужно обойти с помощью обычной анимации. Когда я играю с matchedGeometryEffect(), кажется, он отлично справляется с увеличением и уменьшением размеров, как показано в этом коде:
import SwiftUI
struct ContentView: View {
@State private var animate: Bool = false
@Namespace private var transition
var body: some View {
VStack {
if animate {
RoundedRectangle(cornerRadius: 75.0)
.matchedGeometryEffect(id: "shape", in: transition)
.frame(width: 250, height: 250, alignment: .center)
.foregroundColor(Color.blue)
.animation(.easeInOut)
.onTapGesture {
animate.toggle()
}
} else {
// Circle
RoundedRectangle(cornerRadius: 75.0)
.matchedGeometryEffect(id: "shape", in: transition)
.frame(width: 150, height: 150, alignment: .center)
.foregroundColor(Color.red)
.animation(.easeInOut)
.onTapGesture {
animate.toggle()
}
}
}
}
}
Комментарии:
1. @Omar вставил весь код, который работает для меня в симуляторе без проблем.
2. У меня был тот же результат, прежде чем задавать этот вопрос, посмотрите код и анимацию @vacawama, он получил правильный эффект, но это не анимация преобразования или что-то в этом роде, он работает с cornerRadius
3. @Omar теперь я действительно заинтересовался, поэтому проведу еще несколько исследований.
4. Да! Эта тема очень сложная, я хотел создать пользовательскую анимацию, но она будет работать только и только для преобразования из круга в прямоугольник или из прямоугольника в круг! но как насчет других фигур! например, преобразовать из прямоугольника в пятиугольник или в звезду! У меня есть идея для работы, и она работает над path of shape, на самом деле это очень сложный и большой проект, я считаю, что было бы лучше работать с Metal или SpritKit для общего использования анимации. Но, конечно, путь, возможно, это путь и основная графика
5. Определенно, этот вопрос может стать причиной для перехода на pool of Metal и посмотреть, что там происходит.