簡體   English   中英

如何在 SwiftUI 中同時移動文本並更改其值?

[英]How to move text and change it's value at the same time in SwiftUI?

例如,這就是現在發生的事情

struct ContentView: View {
    @State var titleLable = "This is basic text"
    @State var isTextAnimated: Bool = false
    var body: some View {
        VStack {
            Text(titleLable)
                .offset(y: isTextAnimated ? 300 : 0)
                .animation(.linear)
            Button {
                isTextAnimated.toggle()
                if isTextAnimated {
                    titleLable = "New text appeared"
                } else {
                    titleLable = "This is basic text"
                }
            } label: {
                Text("Press")
            }
        }
        .padding()
    }

上面的代碼在實時預覽中導致了這一點:點擊那里

如果文本沒有改變它的值(我需要這種改變的行為),就會發生這種情況:點擊那里

實現此 animation 的最簡單方法之一是在ZStack中嵌入兩個Text並修改它們的不透明度,並修改 ZStack 的偏移量而不是單個文本。 通過這種方式,兩個文本之間的偏移量和變化都將被動畫化。 這是我的代碼:

struct HomeScreen: View {
    @State var isTextAnimated: Bool = false
    
    var body: some View {
        ZStack{
            Text("Hello")
                .opacity(isTextAnimated ? 1 : 0)
            Text("World")
                .opacity(isTextAnimated ? 0 : 1)
        }
        .offset(y: isTextAnimated ? 150 : 0)
        
        
        Button(action: {withAnimation{isTextAnimated.toggle()}}){
            Text("Press")
        }
        
    }
}

編輯:我忘了為文本更改設置動畫

struct AnimationsView: View {
    @State private var buttonWasToggled = false
    @Namespace private var titleAnimationNamespace

    var body: some View {
        VStack {
            if !buttonWasToggled {
                Text("This is some text")
                    .matchedGeometryEffect(id: "text", in: titleAnimationNamespace)
                    .transition(.opacity)
            } else {
                Text("Another text")
                    .matchedGeometryEffect(id: "text", in: titleAnimationNamespace)
                    .transition(.opacity)
                    .offset(y: 300)
            }

            Button("Press me") {
                withAnimation {
                    buttonWasToggled.toggle()
                }
            }
        }
    }
}

動畫這種變化的一個好方法是動畫偏移值而不是切換 boolean:

struct AnimationsView: View {
    @State private var title = "This is basic text"
    @State private var offset: CGFloat = 0

    var body: some View {
        VStack {
            Text("Some text")
                .offset(y: offset)

            Button("Press me") {
                withAnimation {
                    // If we already have an offset, jump back to the previous position
                    offset = offset == 0 ? 300 : 0
                }
            }
        }
    }
}

或者使用 boolean 值:

struct AnimationsView: View {
    @State private var title = "This is basic text"
    @State private var animated = false

    var body: some View {
        VStack {
            Text("Some text")
                .offset(y: animated ? 300 : 0)

            Button("Press me") {
                withAnimation {
                    animated.toggle()
                }
            }
        }
    }
}

請注意重要的withAnimation ,它向 SwiftUI 指示您要為塊中所做的更改設置動畫。 您可以在此處找到文檔

.animation(...)是可選的,如果您想更改 animation 的行為,例如使用 spring、更改速度、添加延遲等...如果您不指定,SwiftUI 將使用默認值。 以類似的方式,如果您不想讓視圖動畫化,您可以使用添加.animation(nil)修飾符來防止 SwiftUI 為所述視圖設置動畫。

提供的兩種解決方案都會導致以下行為: https://imgur.com/sOOsFJ0

要為 positionText label 的內容設置動畫,您可以使用matchedGeometryEffect ,如下所示:

struct ContentView: View {
    @State var isTextAnimated: Bool = false
    @Namespace var namespace
    
    var body: some View {
        VStack {
            if isTextAnimated {
                Text("New text appeared")
                    .matchedGeometryEffect(id: "title", in: namespace)
                    .offset(y: 300)
            } else {
                Text("This is basic text")
                    .matchedGeometryEffect(id: "title", in: namespace)
            }
            Button {
                withAnimation {
                    isTextAnimated.toggle()
                }
            } label: {
                Text("Press")
            }
        }
        .padding()
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM