SwiftUI:更新数组项不会立即更新子 UI [英] SwiftUI: Updating an array item does not update the child UI immediately

查看:48
本文介绍了SwiftUI:更新数组项不会立即更新子 UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组项目(数字)要使用 NavigationView、List 和叶子页面呈现给用户.

I have an array of items (numbers) to be presented to the user using NavigationView, List and a leaf page.

当我更新叶子页面上的项目 (numbers[index] = ...) 时,它会正确更新列表(当我返回列表时会看到),但不会立即更新叶子页面本身.如果我返回列表并重新打开同一个叶子页面,我会看到变化.

When I update an item (numbers[index] = ...) on a leaf page, it updates the list correctly (which I see when I go back to the list), but not the leaf page itself immediately. I see the change if I go back to the list and re-open the same leaf page.

我想了解它为什么不立即更新 UI,以及如何修复它.以下是重现此行为的简化代码.

I would like to understand why it does not update the UI immediately, and how to fix it. Here is the simplified code to re-produce this behavior.

附加信息此代码在 Xcode 12 上运行良好.它仅在 Xcode 12.1 (RC1) 和 Xcode 12.2 (beta3) 上失败.

ADDITIONAL INFORMATION This code works fine on Xcode 12. It fails only on Xcode 12.1 (RC1) and Xcode 12.2 (beta3).

import SwiftUI

struct NumberHolder: Identifiable {
    let id = UUID()
    let value:Int
}

struct Playground: View {
    @State var numbers:[NumberHolder] = [
        NumberHolder(value:1),
        NumberHolder(value:2),
        NumberHolder(value:3),
        NumberHolder(value:4),
    ]
    var body: some View {
        NavigationView {
            List(numbers.indices) { index in
                let number = numbers[index]
                NavigationLink(destination: VStack {
                    Text("Number: \(number.value)")
                    Button("Increment") {
                        numbers[index] = NumberHolder(value: number.value + 1)
                    }
                } ) {
                    Text("Number: \(number.value)")
                }
            }
        }
    }
}

struct Playground_Previews: PreviewProvider {
    static var previews: some View {
        Playground()
    }
}

推荐答案

这让我花了几个星期来抓狂.

This had me scratching my day for a few weeks.

看起来 SwiftUI 中有许多功能在 Views 中不起作用,它们直接放置在 Lists 中,但是如果您添加 ForEach> 里面的 List 表示功能(例如 WatchOS 上的 .listRowPlatterColor(.green))开始工作.

It appears there are many features within SwiftUI that do not work in Views that are placed in Lists directly, however if you add a ForEach inside the List said features (such as .listRowPlatterColor(.green) on WatchOS) start to work.

解决方案

在 iOS 14.2 上,如果您将 NavigationLink 包装在 ForEach 中,NavigationLink 目标(叶页)将在数据模型时立即更新已更新.

On iOS 14.2 if you wrap the NavigationLink inside a ForEach the NavigationLink destination (leaf page) will update right away when the data model is updated.

因此将您的代码更改为

var body: some View {
        NavigationView {
            List {
                ForEach(numbers.indices) { index in
                    let number = numbers[index]
                    NavigationLink(destination: VStack {
                        Text("Number: \(number.value)")
                        Button("Increment") {
                            numbers[index] = NumberHolder(value: number.value + 1)
                        }
                    } ) {
                        Text("Number: \(number.value)")
                    }
                }
            }
        }
    }

令人沮丧的是,这并没有解决使用 WatchOS 时的问题,在 WatchOS 7.0 中更新了叶子页面,但是在 WatchOS 7.1(版本与遭受此问题"的 iOS 14.2 齐头并进)所以我有一个问题用苹果 FB8892330 打开

Frustratingly, this does not solve the issue when using WatchOS, in WatchOS 7.0 the leaf page is updated, however in WatchOS 7.1 (version goes hand in hand with iOS 14.2 that suffered this "issue") so I have an issue open with Apple FB8892330

更令人沮丧的是,我仍然不知道这是 SwiftUI 中的错误还是功能,没有任何文档说明 ForEach 中的要求>列表

Further frustratingly, I still don't know if this is a bug or a feature in SwiftUI, none of the documentation state the requirement for ForEach inside of Lists

这篇关于SwiftUI:更新数组项不会立即更新子 UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆