วิธีการปิดการใช้งานภาพเคลื่อนไหวในรายการเมื่อวัตถุที่สังเกตเห็นการเปลี่ยนแปลงใน SwiftUI?


15

ฉันจะปิดการใช้งานภาพเคลื่อนไหวเมื่อดูข้อมูลโมเดลเปลี่ยนแปลงได้อย่างไร

ฉันมีรหัสต่อไปนี้:

struct FormView: View {

    @ObservedObject var viewModel: FormViewModel

    var body: some View {
        List {
            ForEach(viewModel.options) { option in
                Text(option.displayValue)
            }
        }
    }
}

การเปลี่ยนแปลงรูปแบบมุมมองทุกครั้งListจะได้รับการอัพเดตด้วยภาพเคลื่อนไหว
ฉันจะปิดการใช้งานได้อย่างไร
ฉันพยายามเพิ่ม.animation(nil)แต่มันก็ไม่ได้ช่วย

คำตอบ:


1

วิธีแก้ปัญหาจนกระทั่ง Apple ให้การเปลี่ยนแปลงที่เราทำใน List คือการเรียก List.id (_ :) มันเปลี่ยนสถานะภายในของ List และบังคับ List ให้สร้างใหม่โดยไม่ต้องเคลื่อนไหวใด ๆ ดูรายละเอียดที่รายการโหลดการเคลื่อนไหวบกพร่อง

สิ่งเดียวกันสามารถทำได้ใน View (func id () ใด ๆ เป็นส่วนหนึ่งของ View protocol) แต่คุณต้องรู้ว่าตัวแปรสถานะทั้งหมดจะมีสถานะ "default" เริ่มต้นดังนั้นให้ใช้อย่างระมัดระวัง มันเหมือนกับ "สร้าง" มุมมองใหม่

เพื่อให้สามารถเข้าใจวิธีการทำงานให้ดูที่https://swiftui-lab.com/swiftui-id/


1

วิธีแก้ปัญหาที่ฉันพบคือการเพิ่มตัวระบุเฉพาะที่เปลี่ยนแปลงทุกครั้งดังนั้นมันจะสร้างรายการใหม่ทุกครั้งโดยไม่มีภาพเคลื่อนไหว ตรวจสอบแล้วบน iOS 13.4

var body: some View {
    List {
        ForEach(viewModel.options) { option in
            Text(option.displayValue)
        }
    }
    .id(UUID()) // no animation
}

-3
  1. ไม่มีความจำเป็นต้องใช้ ForEach ภายในของรายการในกรณีที่คุณไม่ได้ใช้เป็นSection's ดังนั้นแทนที่จะ:

    List {
        ForEach(viewModel.options) { option in
            Text(option.displayValue)
        })
    }

    รหัสต่อไปนี้เพียงพอที่จะเขียน:

    List(viewModel.options) { option in
        Text(option.displayValue)
    }

    และยังดีกว่าที่จะรู้ว่าการใช้ ForEach สามารถสร้างปัญหาบางอย่างเช่นSwiftUI: เป็นไปได้ไหมที่จะใช้ ForEach + ContextMenu

  2. ในกรณีที่คุณจะใช้เฉพาะForEach()หรือเฉพาะList()+ .animation(nil)- ต้องแก้ไขปัญหาของคุณ:

    ตัวอย่างที่ 1:

    ForEach(viewModel.options) { option in
        Text(option.displayValue)
    }.animation(nil)

    ตัวอย่างที่ 2:

    List(viewModel.options) { option in
        Text(option.displayValue)
    }.animation(nil)

    ฉันได้รับการทดสอบทั้งใน macOS 10.15.2 (19C57) และทำงานได้อย่างสมบูรณ์

  3. นอกจากนี้คุณสามารถพยายามที่จะใช้.animation(nil)บนListและForEachทั้งสอง ฉันไม่ได้ลอง ... แต่ฉันคิดว่ามันจะให้ผลตามที่คุณต้องการด้วย

    List {
        ForEach(viewModel.options) { option in
            Text(option.displayValue)
        }.animation(nil)
    }.animation(nil)

.animation(nil)ดูเหมือนว่าจะไม่มีผลกับ 13.3 แต่น่าเสียดายที่
Fabian Streitel

@FabianStreitel ฉันได้รับการทดสอบตอนที่ 2 บน macOS 10.15.2 (19C57) และมันทำงานได้อย่างสมบูรณ์แบบ
แอนดรู

และฉันได้ทำการทดสอบทั้งสามรุ่นใน iOS 13.3 (ตามที่ระบุในความคิดเห็นของฉันด้านบน) และไม่มีใครเปลี่ยนพฤติกรรมของรายการเลย OP ไม่ได้ระบุว่าพวกเขากำลังสร้างแอพ iOS หรือ macOS แต่น่าเสียดายที่ แต่ฉันคิดว่าข้อมูลที่ใช้ไม่ได้กับ iOS นั้นเกี่ยวข้องกับผู้อื่นเช่นกัน
Fabian Streitel

ฉันเพิ่งทดสอบ.animation(nil)โดยใช้ Xcode 11.4 กับ iOS 13.4 และใช้งานได้สำหรับฉัน
Simen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.