
Tugas umum dalam pengembangan iOS adalah bagian yang dapat diperluas / lipat dalam UITableView. Hari ini kami menyadari tugas ini menggunakan SwiftUI. Sebagai twist kecil, tambahkan segitiga animasi di bagian header dan buat sel-selnya juga mengembang.
Pengembangan berlangsung pada Xcode 11.2 untuk macOS Catalina 10.15.1
Mulai proyek
Luncurkan Xcode, File - Proyek Baru - Aplikasi Tampilan Tunggal. Di kotak dialog, tentukan bahasa pengembangan Swift, kami akan membentuk UI menggunakan SwiftUI.

Data
Sebagai data demonstrasi, kami akan menggunakan beberapa ekspresi bersayap lucu dalam bahasa Latin dengan terjemahannya ke dalam bahasa Rusia.
Tambahkan file Swift baru ke proyek, sebut saja
Data.swift dan tulis yang berikut di sini:
struct QuoteDataModel : Identifiable { var id: String { return latin } var latin : String var russian : String var expanded = false } struct SectionDataModel : Identifiable { var id: Character { return letter } var letter : Character var quotes : [QuoteDataModel] var expanded = false }
QuoteDataModel adalah model ekspresi tunggal, di masa depan itu akan menjadi konten setiap sel individu. Di dalamnya kita menyimpan teks asli ekspresi, terjemahannya dan tanda sel "diperluas" (secara default itu "diperkecil")
SectionDataModel adalah model dari masing-masing bagian yang terpisah, di sini kita menyimpan "surat" bagian tersebut, sebuah array kutipan yang dimulai dengan surat ini dan juga tanda bagian "diperluas" (secara default juga "runtuh")
Di masa mendatang, kami akan menampilkan semua ini dalam tampilan Daftar, yang mengharuskan data untuk itu mematuhi protokol yang Dapat
Diidentifikasi . Untuk melakukan ini, kami mendefinisikan properti
id , yang harus unik untuk setiap item dalam Daftar.
Selanjutnya, dalam file Data.swift yang sama, kami membentuk data kami:
var latinities : [SectionDataModel] = [ SectionDataModel(letter: "C", quotes: [ QuoteDataModel(latin: "Calvitium non est vitium, sed prudentiae indicium.", russian: " , ."), QuoteDataModel(latin: "Conjecturalem artem esse medicinam.", russian: " ."), QuoteDataModel(latin: "Crede firmiter et pecca fortiter!", russian: " !")]), SectionDataModel(letter: "H", quotes: [ QuoteDataModel(latin: "Homo sine religione sicut equus sine freno.", russian: " ."), QuoteDataModel(latin: "Habet et musca splenem.", russian: " .")]), SectionDataModel(letter: "M", quotes: [ QuoteDataModel(latin: "Malum est mulier, sed necessarium malum.", russian: " , ."), QuoteDataModel(latin: "Mulierem ornat silentium.", russian: " .")])]
Mari kita berurusan dengan antarmuka
Sekarang kita akan menentukan bagaimana judul bagian dan setiap sel akan terlihat.
Pilih File - Baru - File - Tampilan SwiftUI dari menu. Beri nama file
HeaderView.swift dan ganti isinya dengan yang berikut:
import SwiftUI struct HeaderView : View { var section : SectionDataModel var body: some View { HStack() { Spacer() Text(String(section.letter)) .font(.largeTitle) .foregroundColor(Color.black) Spacer() } .background(Color.yellow) } } struct HeaderView_Previews: PreviewProvider { static var previews: some View { HeaderView(section: latinities[0]) } }

Sekarang lagi File - Baru - File - Tampilan SwiftUI. Beri nama file
QuoteView.swift dan ganti isinya dengan yang berikut:
import SwiftUI struct QuoteView: View { var quote : QuoteDataModel var body: some View { VStack(alignment: .leading, spacing: 5) { Text(quote.latin) .font(.title) if quote.expanded { Group() { Divider() Text(quote.russian).font(.body) }.transition(.move(edge: .top)).animation(.default) } } } } struct QuoteView_Previews: PreviewProvider { static var previews: some View { QuoteView(quote: latinities[0].quotes[0]) } }

Sekarang buka file ContentView.swift dan ubah struktur ContentView sebagai berikut:
struct ContentView: View { var body: some View { List { ForEach(latinities) { section in Section(header: HeaderView(section: section), footer: EmptyView()) { if section.expanded { ForEach(section.quotes) { quote in QuoteView(quote: quote) } } } } } .listStyle(GroupedListStyle()) } }
Selamat, Anda baru saja mengisi Daftar dengan data terbaru! Untuk setiap elemen array
latinities, kami membuat bagian dengan header berdasarkan
HeaderView dan dengan footer kosong. Jika bagian "diperluas", maka untuk setiap ekspresi dalam array kutipan kami membentuk sel berdasarkan pada
QuoteView . Dalam data kami, semua bagian dan semua sel "diciutkan", jadi jika Anda membuat Canvas terlihat, Anda hanya akan melihat header bagian:

Seperti yang Anda pahami, sekarang aplikasi benar-benar "mati" dan masih jauh dari tujuan akhir kami. Tapi segera kami akan memperbaikinya!
Ubah sedikit bagian tajuk
Kembali ke file HeaderView.swift. Di dalam struktur HeaderView, segera setelah tubuh, tambahkan ini:
struct Triangle : Shape { func path(in rect: CGRect) -> Path { var path = Path() path.move(to: CGPoint(x: 0, y: 0)) path.addLine(to: CGPoint(x: 0, y: rect.height - 1)) path.addLine(to: CGPoint(x: sqrt(3)*(rect.height)/2, y: rect.height/2)) path.closeSubpath() return path } }
Struktur ini mengembalikan segitiga sama sisi. Sekarang tambahkan segitiga kami ke header. Di dalam
HStack , sebelum
Spacer pertama tambahkan ini:
Triangle() .fill(Color.black) .overlay( Triangle() .stroke(Color.red, lineWidth: 5) ) .frame(width : 50, height : 50) .padding() .rotationEffect(.degrees(section.expanded ? 90 : 0), anchor: .init(x: 0.5, y: 0.5)).animation(.default))

Ubah data
Kembali ke data kami. Buka Data.swift dan
Bungkus array
latinities kami di kelas UserData baru, seperti ini:
class UserData : ObservableObject { @Published var latinities : [SectionDataModel] = [ SectionDataModel(letter: "C", quotes: [ QuoteDataModel(latin: "Calvitium non est vitium, sed prudentiae indicium.", russian: " , ."), QuoteDataModel(latin: "Conjecturalem artem esse medicinam.", russian: " ."), QuoteDataModel(latin: "Crede firmiter et pecca fortiter!", russian: " !")]), SectionDataModel(letter: "H", quotes: [ QuoteDataModel(latin: "Homo sine religione sicut equus sine freno.", russian: " ."), QuoteDataModel(latin: "Habet et musca splenem.", russian: " .")]), SectionDataModel(letter: "M", quotes: [ QuoteDataModel(latin: "Malum est mulier, sed necessarium malum.", russian: " , ."), QuoteDataModel(latin: "Mulierem ornat silentium.", russian: " .")])] }
Ingatlah untuk juga menandai latinities sebagai
@Diterbitkan .
Apa yang telah kita lakukanObservableObject adalah objek khusus untuk data kami yang dapat "terikat" ke beberapa Tampilan. SwiftUI "memantau" semua perubahan yang dapat memengaruhi Tampilan dan, setelah data berubah, mengubah Tampilan.
Setelah "membungkus" bahasa latin, kami memiliki banyak kesalahan, kami akan memperbaikinya. Buka
HeaderView.swift dan koreksi struktur
HeaderView_Preview sebagai berikut:
struct HeaderView_Previews: PreviewProvider { static var previews: some View { HeaderView(section: UserData().latinities[0]) } }
Sekarang buat perubahan serupa dengan
QuoteView.swift :
struct QuoteView_Previews: PreviewProvider { static var previews: some View { QuoteView(quote: UserData().latinities[0].quotes[0]) } }
Buka file ContentView.swift dan tambahkan ini sebelum deklarasi
body @ObservedObject var userData = UserData()
Bangkit kembali lanskap
Kembali ke file ContentView.swift. Di dalam struktur ContenView, segera setelah definisi userData, tambahkan dua fungsi:
func sectionIndex(section : SectionDataModel) -> Int { userData.latinities.firstIndex(where: {$0.letter == section.letter})! } func quoteIndex(section : Int, quote : QuoteDataModel) -> Int { return userData.latinities[section].quotes.firstIndex(where: {$0.latin == quote.latin})! }
Tambahkan pengubah
onTapGesture ke header bagian dan sel yang kita
buat . Tampilan akhir konten
tubuh :
var body: some View { List { ForEach(userData.latinities) { section in Section(header: HeaderView(section: section) .onTapGesture { self.userData.latinities[self.sectionIndex(section: section)].expanded.toggle() }, footer: EmptyView()) { if section.expanded { ForEach(section.quotes) { quote in QuoteView(quote: quote) .onTapGesture { let sectionIndex = self.sectionIndex(section: section) let quoteIndex = self.quoteIndex(section: sectionIndex, quote: quote) self.userData.latinities[sectionIndex].quotes[quoteIndex].expanded.toggle() } } } } } } .listStyle(GroupedListStyle()) }
Fungsi
sectionIndex dan
quoteUndex mengembalikan indeks bagian dan ekspresi yang diberikan kepada mereka. Setelah menerima indeks ini, kami mengubah nilai properti yang
diperluas dalam susunan
latinity kami , yang mengarah pada pelipatan /
pembukaan bagian atau ekspresi.

Kesimpulan
Proyek yang sudah selesai dapat
diunduh di sini .
Beberapa tautan bermanfaat:
Saya harap publikasi ini bermanfaat bagi Anda!