จะสร้างเอฟเฟกต์ภาพเคลื่อนไหว SwiftUI จาก Model ได้อย่างไร

ฉันมีวัตถุโมเดลซึ่งมีคุณสมบัติที่เผยแพร่ displayMode ซึ่งได้รับการอัปเดตแบบอะซิงโครนัสผ่านเหตุการณ์จากเซิร์ฟเวอร์

class RoomState: NSObject, ObservableObject  {
    public enum DisplayMode: Int {
        case modeA = 0
        case modeB = 1
        case modeC = 2
    }
    @Published var displayMode = DisplayMode.modeA

    func processEventFromServer(newValue: DisplayMode) {
        DispatchQueue.main.async {
            self.displayMode = newValue
        }
    }
}

จากนั้นฉันมีมุมมองซึ่งแสดงโหมดนี้โดยการวางภาพบางภาพในตำแหน่งที่แน่นอนขึ้นอยู่กับค่า

struct RoomView: View {
    @ObservedObject var state: RoomState
    var body: some View {
       VStack {
           ...
           Image(systemName: "something")
               .offset(x: state.displayMode.rawValue * 80, y:0)
       }
    }
}

รหัสนี้ใช้งานได้ดี แต่ฉันต้องการทำให้การเคลื่อนไหวเคลื่อนไหวเมื่อค่าเปลี่ยนแปลง หากฉันเปลี่ยนค่าในบล็อคโค้ดภายใน View ฉันสามารถใช้ withAnimation {..} เพื่อสร้างเอฟเฟกต์ภาพเคลื่อนไหวได้ แต่ฉันไม่สามารถทราบวิธีทำจากโมเดลได้


person Satoshi Nakajima    schedule 30.04.2021    source แหล่งที่มา
comment
คุณควรจะสามารถใช้ภาพเคลื่อนไหวโดยนัยได้: .offset(x: state.displayMode.rawValue * 80, y:0).animation()   -  person aheze    schedule 01.05.2021
comment
คุณไม่สามารถทำ DispatchQueue.main.async { withAnimation { self.displayMode = newValue } } ได้เหรอ?   -  person George_E    schedule 01.05.2021
comment
@aheze แนวทางของคุณใช้ได้ผล! ขอบคุณมาก.   -  person Satoshi Nakajima    schedule 01.05.2021
comment
@George_E คุณไม่สามารถใช้ withAnimation จาก Model ได้ withAnimation ใช้ได้เฉพาะภายใน View เท่านั้น   -  person Satoshi Nakajima    schedule 01.05.2021
comment
@SatoshiNakajima คุณสามารถใช้ได้ทุกที่โดยสมมติว่าคุณนำเข้า SwiftUI   -  person George_E    schedule 01.05.2021


คำตอบ (1)


นี่คือคำตอบ ขอบคุณ @aheze ด้วย .animation() มุมมองรูปภาพนี้จะเคลื่อนไหวเสมอเมื่อ state.displayMode เปลี่ยนแปลง

struct RoomView: View {
    @ObservedObject var state: RoomState
    var body: some View {
       VStack {
           ...
           Image(systemName: "something")
               .offset(x: state.displayMode.rawValue * 80, y:0)
               .animation(.easeInOut)
       }
    }
}
person Satoshi Nakajima    schedule 01.05.2021