@Publishedがテキストを更新するのにリストを更新しないのはなぜですか?

Dec 15 2020

Text更新の理由はわかりListませんが、わかりません。

@Published日付の配列であるaを持つモデルがあります。日付からテキストを生成する方法もあります。

簡略化したバージョンは次のとおりです。

class DataModel: NSObject, ObservableObject {
    
    @Published var selectedDates: [Date] = []

    func summary() -> String {
        var lines: [String] = []
        for date in selectedDates.sorted().reversed() {
            let l = "\(someOtherStuff) \(date.dateFormatted)"
            lines.append(l)
        }
        return lines.joined(separator: "\n")
    }

}

そして、私はこのテキストを私の見解に示しています。簡略化したバージョンは次のとおりです。

struct DataView: View {

    @ObservedObject var model: DataModel

    var body: some View {
        ScrollView {
            Text(model.summary())
        }
    }

}

これは機能します。ユーザーがビューのUIから日付をmodel.selectedDatesに追加すると、要約テキストが適切に更新されます。


ここで、テキストを行のリストに置き換えたいと思います。

私は方法を変更します:

    func summary() -> [String] {
        var lines: [String] = []
        for date in selectedDates.sorted().reversed() {
            let l = "\(someOtherStuff) \(date.dateFormatted)"
            lines.append(l)
        }
        return lines
    }

そして、ビューを変更します。

    var body: some View {
        ScrollView {
            List {
                ForEach(model.summary(), id: \.self) { line in
                    Text(line)
                }
            }
        }
    }

ただし、これは機能しません。リストにテキストがまったくないため、ユーザーがに日付を追加してもテキストが更新されることはありませんmodel.selectedDates

私は何が間違っているのですか?

回答

2 Nate Dec 15 2020 at 08:34

私はあなたの問題の解決策かもしれないSOに関する以前の投稿へのこの答えを見つけることができました。リストにテキストがまったくないという場合、それを確認するためにデバッグしましたか、それとも単に画面にデータが表示されていませんでしたか?

コードスニペットのコピーを作成し、それをいじったところ、リストが画面に表示しようとしているデータが実際にリストにあるように見えましたが、リストのフレームはScrollviewによって上書きされていました。GeometryReader内にすべてをネストし、リストにフレームサイズを指定すると、プログラムは探しているように聞こえる機能を利用できます。

1 nicksarno Dec 15 2020 at 10:22

データにはScrollViewまたはListを使用してください。リストに複数の値がある場合、リストは自動的にスクロール可能なリストに変わります。したがって、ScrollViewを完全に削除できると思います。

1 Asperi Dec 15 2020 at 10:53

これは修正された動作バリアントです(いくつかの複製があるため、プロジェクトに戻す必要があります)。

Xcode 12.1 / iOS14.1でテスト済み

class DataModel: NSObject, ObservableObject {
    
    @Published var selectedDates: [Date] = []
    
    func summary() -> [String] {
        var lines: [String] = []
        for date in selectedDates.sorted().reversed() {
            let l = "someOtherStuff \(date)"
            lines.append(l)
        }
        return lines
    }
    
}

struct DataView: View {
    
    @ObservedObject var model: DateDataModel = DataModel()
    
    var body: some View {
        VStack {
            Button("Add") { model.selectedDates.append(Date())}
            List {
                ForEach(model.summary(), id: \.self) { line in
                    Text(line)
                }
            }
        }
    }
    
}