Published on

matchedGeometryEffect β€” mos geometriya effekti

Authors

Ilovalarni ko'rdingizmi β€” kichik rasmga tappingida rasm to'liq ekranga kengayadi va o'sha rasm o'zi tafsilot ko'rinishiga aylanadi? Bu β€” "hero" animatsiyasi deb ataladi va bu kabi effektni yaratish odatda anchagina murakkab. SwiftUI-da esa buning uchun matchedGeometryEffect mavjud.

G'oya quyidagicha: ikkita turli ko'rinish bor β€” biri kichik (ro'yxatdagi karta) va biri katta (kengaytirilgan tafsilot) β€” va siz ular o'rtasida animatsiya ko'rinishini xohlaysiz. matchedGeometryEffect ikkalasini bir xil ID va nom maydoni orqali bog'laydi. Biri olib tashlanib boshqasi paydo bo'lganda, SwiftUI o'lcham va joylashuvni avtomatik interpolatsiya qiladi.

Buning uchun ikki narsa kerak: umumiy animatsiya maydonini yaratuvchi @Namespace xususiyati va kichik hamda katta versiyaga .matchedGeometryEffect(id:in:) biriktirilishi.

Swift
ContentView.swift
import SwiftUI struct ContentView: View { // @Namespace umumiy animatsiya kontekstini yaratadi @Namespace private var animatsiya @State private var kengaytirilganmi = false var body: some View { VStack { if !kengaytirilganmi { // Kichik holat β€” tap qilinishini kutadi RoundedRectangle(cornerRadius: 12) .fill(Color.blue) .frame(width: 100, height: 100) // Bu modifikator kichik versiyani belgilaydi .matchedGeometryEffect(id: "karta", in: animatsiya) .onTapGesture { withAnimation(.spring(duration: 0.5)) { kengaytirilganmi = true } } } else { // Katta holat β€” ko'lami kengaytirilgan RoundedRectangle(cornerRadius: 20) .fill(Color.blue) .frame(maxWidth: .infinity, maxHeight: 300) // Bir xil ID va namespace β€” SwiftUI ularni bog'laydi .matchedGeometryEffect(id: "karta", in: animatsiya) .onTapGesture { withAnimation(.spring(duration: 0.5)) { kengaytirilganmi = false } } .padding() } } .frame(maxWidth: .infinity, maxHeight: .infinity) } }
QatorVazifasi
@Namespace private var animatsiyaNom maydonini yaratadi β€” umumiy animatsiya konteksti. Bu ikki ko'rinishni bog'lovchi kanal sifatida ishlaydi. Ikkala ko'rinish ham bu nom maydoniga murojaat qilishi kerak.
.matchedGeometryEffect(id: "karta", in: animatsiya)Kichik va katta versiyaga bir xil ID bilan biriktiriladi. Biri olib tashlanib boshqasi paydo bo'lganda withAnimation chaqiruvi ichida SwiftUI o'lcham va joylashuvni animatsiya orqali o'tkazadi.
withAnimation(.spring(duration: 0.5)) { kengaytirilganmi = true }Holat o'zgarishi bu yerda sodir bo'ladi. SwiftUI oldingi va yangi holatni suratga oladi va animatsiya qiladi.

Matn o'tishi

// Matn ham matchedGeometryEffect bilan ishlaydi
if !tanlangami {
    Text(element.nomi)
        .font(.caption)
        .matchedGeometryEffect(id: "sarlavha-\(element.id)", in: animatsiya)
} else {
    Text(element.nomi)
        .font(.title)
        .matchedGeometryEffect(id: "sarlavha-\(element.id)", in: animatsiya)
}

Ro'yxat β†’ tafsilot o'tishi patterni

struct KartaRoyxat: View {
    @Namespace private var animatsiya
    @State private var tanlanganElement: Element? = nil

    var body: some View {
        ZStack {
            // Ro'yxat ko'rinishi
            ScrollView {
                ForEach(elementlar) { element in
                    KichikKarta(element: element)
                        .matchedGeometryEffect(id: element.id, in: animatsiya)
                        .onTapGesture {
                            withAnimation(.spring()) {
                                tanlanganElement = element
                            }
                        }
                }
            }

            // Tanlangan bo'lsa kengaytirilgan ko'rinish
            if let tanlangan = tanlanganElement {
                KattaKarta(element: tanlangan)
                    .matchedGeometryEffect(id: tanlangan.id, in: animatsiya)
                    .onTapGesture {
                        withAnimation(.spring()) {
                            tanlanganElement = nil
                        }
                    }
                    .zIndex(1)
            }
        }
    }
}

Tezkor ma'lumotnoma

SintaksisVazifasi
@Namespace var animatsiyaUmumiy nom maydonini yaratadi β€” bir marta e'lon qilinadi
.matchedGeometryEffect(id: "kalit", in: animatsiya)Ikkala ko'rinishni bir xil ID va nom maydoni bilan bog'laydi
.matchedGeometryEffect(id: element.id, in: animatsiya)Noyob ID uchun Identifiable elementni ishlatish
isSource: falseGeometriya beruvchi emas β€” qabul qiluvchi deb belgilaydi
properties: .positionFaqat joylashuvni o'tkazadi (o'lchamni emas)

🎯 Topshiriq: kengayuvchi karta

Bir ro'yxat kartasi ustiga bosinganda to'liq ekran tafsilotiga kengayadigan ko'rinish yarating. Kartada rasm (yoki rangli to'rtburchak), sarlavha va qisqa tavsif bo'lsin. Kengaytirilganda bir xil rasm/shakl va sarlavha kengaygan ko'rinishda ko'rinishi kerak β€” matchedGeometryEffect bilan ikkalasi uchun. Qaytish uchun kengaytirilgan ko'rinishga tapping qiling.

Buy mea coffee