Gunakan sheet(item:onDismiss:content:) dengan satu item terpilih pilihan, dan bina helaian daripada item yang diterima oleh penutupnya. Ini memberikan app Mac satu nilai yang menentukan sama ada helaian dipaparkan dan kandungan yang dipaparkannya.

Tutorial ini melaksanakan tugas desktop kecil: klik item sampel setempat dan periksa butirannya dengan serta-merta. Ia juga menyediakan urutan diagnostik untuk helaian yang terbuka tanpa kandungan, memaparkan pilihan terdahulu atau menunjukkan teks lapuk dalam paparan AppKit.

Mengapa menggunakan helaian berasaskan item?

SwiftUI menawarkan dua kaedah persembahan yang berkaitan. Overload Boolean memaparkan helaian apabila bindingnya menjadi true. Overload item menerima nilai boleh dikenal pasti yang pilihan dan memberikan nilai itu kepada penutup kandungan. Pilih bentuk Boolean untuk panel tetap; pilih bentuk item apabila kandungan panel bergantung pada pilihan. Lihat dokumentasi Apple untuk helaian berasaskan Boolean dan helaian berasaskan item.

Reka bentuk dengan sifat pemilihan dan persembahan yang berasingan membenarkan gabungan seperti permintaan untuk memaparkan helaian tanpa pilihan. Menggabungkannya menjadi satu nilai pilihan menghapuskan gabungan itu daripada model keadaan anda: nil mewakili tiada item yang diminta, manakala nilai yang terisi mewakili item untuk diperiksa. Ini ialah kesimpulan reka bentuk berdasarkan kedua-dua API, bukannya dakwaan tentang kecacatan penjadualan SwiftUI yang tidak didokumenkan.

Jika pelaksanaan sedia ada menetapkan pilihan kemudian menogol Boolean, kedua-dua pernyataan itu sahaja tidak membuktikan sebab paparan pertamanya gagal. Periksa laluan data kandungan sebelum mengaitkan gejala itu dengan pemasaan. Soalan yang berguna ialah sama ada helaian memaparkan input yang dibekalkan kepadanya, membaca sifat lain atau memaparkan salinan yang disimpan secara berasingan.

Bina contoh macOS yang lengkap

Cipta projek app macOS dalam Xcode dengan antara muka SwiftUI. Gunakan sasaran penggunaan macOS 12 atau lebih baharu untuk contoh ini. API helaian berasaskan item tersedia sejak macOS 10.15, manakala tindakan persekitaran untuk menutup yang digunakan di bawah memerlukan macOS 12. Had ketersediaan ini didokumenkan oleh Apple untuk helaian berasaskan item dan nilai persekitaran untuk menutup.

Gantikan pengisytiharan app dan paparan kandungan yang dijana dengan program lengkap ini. Kekalkan hanya satu titik masuk app dalam sasaran. Semua label dan perihalan di bawah ialah data sampel setempat sintetik.

import SwiftUI

struct SampleItem: Identifiable {
    let id: String
    let title: String
    let detail: String
}

@main
struct FirstSheetDemoApp: App {
    var body: some Scene {
        WindowGroup {
            ItemListView()
        }
    }
}

struct ItemListView: View {
    private let items = [
        SampleItem(
            id: "tile-a",
            title: "Amber Tile",
            detail: "A square sample with an amber finish."
        ),
        SampleItem(
            id: "tile-b",
            title: "Blue Tile",
            detail: "A rectangular sample with a blue finish."
        )
    ]

    @State private var presentedItem: SampleItem? = nil

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            Text("Sample Items")
                .font(.title2)

            ForEach(items) { item in
                Button("Inspect \(item.title)") {
                    presentedItem = item
                }
            }
        }
        .padding(24)
        .frame(minWidth: 360, minHeight: 200)
        .sheet(item: $presentedItem) { item in
            ItemDetailView(item: item)
        }
    }
}

struct ItemDetailView: View {
    let item: SampleItem
    @Environment(\.dismiss) private var dismiss

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            Text(item.title)
                .font(.title)

            Text(item.detail)

            Text("Item ID: \(item.id)")
                .font(.caption)

            HStack {
                Spacer()
                Button("Done") {
                    dismiss()
                }
            }
        }
        .padding(24)
        .frame(width: 380, height: 220)
    }
}

Butang itu menetapkan nilai yang diklik kepada presentedItem. Kemudian, penutup persembahan menghantar parameter item miliknya kepada ItemDetailView. Perhatikan bahawa paparan butiran mempunyai sifat input biasa, let item, bukannya sifat keadaan item terpilih yang kedua. Apple mengesyorkan agar satu sumber kebenaran dikekalkan dan nilai baca sahaja dikongsi melalui sifat, dengan binding digunakan apabila paparan anak memerlukan akses tulis. Lihat State.

Tindakan untuk menutup perlu diletakkan dalam ItemDetailView, tempat ia membaca persekitaran helaian. Apple secara jelas memberi amaran bahawa membaca tindakan itu dalam paparan yang membentangkan helaian lalu memanggilnya daripada kandungan helaian akan menggunakan persekitaran paparan yang membentangkannya. Letakkan pengisytiharan itu bersebelahan kandungan helaian sendiri, seperti yang ditunjukkan. Lihat dismiss.

Program ini telah diperiksa untuk memastikan input dan rujukannya konsisten; program ini belum dikompil atau dijalankan di sini kerana toolchain Swift tidak tersedia dalam persekitaran ini. Jalankan semakan berikut dalam Xcode pada versi macOS sasaran anda.

Sahkan paparan pertama dengan urutan klik yang terancang

Mulakan setiap semakan paparan pertama dengan pelancaran baharu. Ujian yang hanya dilakukan selepas membuka item lain boleh menyembunyikan gejala asal. Jangkaan berikut berdasarkan label dan tugasan data yang dinyatakan secara jelas dalam sampel; ini kriteria penerimaan, bukannya keputusan ujian yang dilaporkan.

Tindakan Kandungan helaian yang dijangka Perkara yang disemak
Lancarkan dan klik Inspect Blue Tile dahulu Blue Tile, perihalan segi empat tepatnya dan tile-b Paparan pertama menggunakan item yang diklik
Klik Done, kemudian periksa Amber Tile Amber Tile, perihalan segi empat samanya dan tile-a Pilihan seterusnya sampai kepada kandungan
Tutup helaian dan periksa Amber Tile sekali lagi Butiran ambar yang sama Membuka semula item kekal konsisten
Lancarkan semula dan periksa Amber Tile dahulu Butiran ambar serta-merta Ketepatan tidak bergantung pada sampel yang dibuka dahulu

Memaparkan tajuk dan ID menjadikan semakan ini lebih berguna daripada menyemak tajuk sahaja. Jika antara muka sebenar anda membenarkan nama paparan pendua, gunakan dua item sintetik dengan tajuk yang sama tetapi ID dan perihalan berbeza semasa pembangunan. Ini mendedahkan pemilihan tidak sengaja berdasarkan teks paparan.

Diagnosis kandungan lapuk dari butang hingga paparan akhir

Ikuti semakan ini mengikut turutan. Setiap langkah mengecilkan lokasi ketidakpadanan, supaya anda boleh mengubah lapisan yang bertanggungjawab tanpa menambah penyelesaian sementara persembahan yang tidak berkaitan.

  1. Semak input tindakan. Tetapkan titik henti dalam tindakan butang yang diklik dan periksa item.id. Pastikan tindakan itu menerima rekod yang dikehendaki.
  2. Semak input persembahan. Periksa parameter item di dalam penutup helaian. Hantar parameter itu kepada paparan butiran dan bukannya membuat carian semula berdasarkan pilihan yang berasingan.
  3. Semak sifat yang dipaparkan pada akhirnya. Pastikan tajuk dan perihalan dibaca daripada input paparan butiran. Cari sifat cache atau draf setempat yang mengandungi nilai terdahulu.
  4. Semak sebarang jambatan AppKit. Jika teks SwiftUI biasa betul tetapi teks dalam paparan berbalut sudah lapuk, periksa kaedah kemas kini representable.

Kekalkan identiti yang stabil

API berasaskan item memerlukan Identifiable. Swift mentakrifkan protokol itu berdasarkan identiti yang stabil dan menyerahkan tempoh serta skopnya kepada jenis yang mematuhinya dan pengguna jenis itu. Sampel ini menggunakan ID rentetan tersimpan yang membezakan kedua-dua rekod. Lihat Identifiable.

Untuk senarai sebenar, pilih pengecam yang terus mengenal pasti rekod sama sepanjang kemas kini yang disokong oleh antara muka anda. Elakkan daripada mendapatkan identiti daripada tajuk yang boleh berubah atau dikongsi oleh beberapa item. Elakkan juga id terhitung yang menghasilkan UUID baharu setiap kali dibaca; itu tidak memberikan identiti yang stabil.

Asingkan input paparan daripada draf yang boleh diedit

Pemeriksa boleh memaparkan item.title secara langsung. Editor mungkin sengaja mencipta draf setempat, tetapi draf menambah satu lagi nilai yang jangka hayatnya perlu ditentukan. Tentukan masa draf itu dicipta, sama ada perubahan model yang berlaku kemudian patut menggantikannya dan perkara yang berlaku apabila pengguna selesai atau membatalkannya.

Apple menerangkan bahawa SwiftUI mengekalkan storan keadaan untuk identiti paparan dan memulakannya pada awal jangka hayat identiti itu. Mencipta semula nilai paparan tidak dengan sendirinya menghasilkan keadaan baharu. Oleh itu, memulakan keadaan setempat daripada input bukan cara umum untuk memastikan keadaan itu disegerakkan dengan input yang berubah kemudian. Lihat Demystify SwiftUI.

Untuk tugas baca sahaja ini, kekalkan sifat input biasa. Jika anda mengembangkannya menjadi fungsi suntingan, pilih reka bentuk draf dan komit yang jelas atau binding kepada nilai model yang dimaksudkan. Elakkan menambah identiti paparan yang berubah semata-mata untuk menyegar semula teks: menukar identiti menggantikan keadaan yang berkaitan dan boleh membuang draf yang belum selesai. Kesan ini berasaskan model jangka hayat keadaan yang didokumenkan oleh Apple.

Apakah yang berubah apabila helaian mengandungi paparan teks AppKit?

Helaian yang mengandungi NSTextView masih memerlukan laluan data item terpilih yang sama. Helaian itu juga memerlukan jambatan yang dilaksanakan dengan betul. Protokol NSViewRepresentable Apple memisahkan penciptaan awal dalam makeNSView(context:) daripada konfigurasi seterusnya dalam updateNSView(_:context:). Pembalut yang menetapkan teksnya hanya semasa penciptaan tidak mempunyai pelaksanaan untuk menggunakan input teks yang diterima kemudian. Lihat NSViewRepresentable.

Untuk pembalut baca sahaja, mulakan paparan natif dengan teks yang dibekalkan dan pastikan kaedah kemas kininya menyelaraskan teks yang dipaparkan dengan input semasa apabila perlu. Apple mendokumenkan bahawa SwiftUI memanggil kaedah kemas kini bagi perubahan yang mempengaruhi paparan AppKit yang berkenaan. Lihat updateNSView(_:context:).

Pembalut boleh diedit memerlukan dasar tambahan: jangan gantikan teksnya secara membuta tuli pada setiap kemas kini sehingga menimpa suntingan yang sedang dibuat. Gunakan penyelaras untuk menyampaikan perubahan perwakilan natif atau tindakan sasaran kembali kepada SwiftUI, seperti yang diterangkan oleh Apple dalam dokumentasi representable. Biarkan SwiftUI mengawal bingkai dan sempadan paparan yang diwakili; Apple memberi amaran supaya sifat reka letak itu tidak ditetapkan secara langsung.

TextKit mengendalikan storan teks, reka letak dan pemaparan. Apple mendokumenkan kedua-dua laluan moden NSTextLayoutManager dan laluan lama NSLayoutManager yang didedahkan oleh NSTextView. Kemudahan itu tidak membekalkan rekod terpilih untuk helaian. Pastikan jambatan menerima teks item yang betul sebelum menyiasat reka letak teks, dan semak ketersediaan secara berasingan sebelum memperkenalkan API TextKit tambahan. Lihat TextKit.

Pilih model persembahan yang sepadan dengan tugas

Gunakan overload Boolean apabila kandungannya tetap dan keterlihatan ialah satu-satunya input yang berubah. Gunakan overload item untuk tugas pemeriksa ini. Apple mendokumenkan bahawa perubahan pada item yang dibekalkan boleh menutup helaian sedia ada dan menggantikannya, jadi jangan anggap penggantian item menjanjikan suntingan berterusan dalam persembahan yang sama. Lihat sheet(item:onDismiss:content:).

Untuk memastikan paparan pertama betul, mudahkan penjejakan rekod terpilih: satu tugasan dalam tindakan butang, satu parameter item dalam penutup helaian dan satu input dalam paparan butiran. Sahkan kedua-dua item sampel selepas pelancaran baharu. Jika hasilnya masih berbeza, urutan diagnostik itu mengenal pasti sama ada ketidakpadanan berpunca daripada pemilihan, keadaan yang dikekalkan atau laluan kemas kini paparan natif.

Sumber