İçindekiler
Problem
iOS 26 ve macOS 26 uzun bir yeni SwiftUI API listesiyle geldi: Liquid Glass, küçülen tab bar,
toolbar spacer'lar, scroll edge efektleri, rich text destekli TextEditor, native WebView,
Chart3D, SF Symbol draw efektleri, @Animatable macro'su ve cihaz üzerinde çalışan Foundation
Models framework'ü. Dokümantasyon size imzaları söyler. Ama Glass.clear'ın Glass.regular'ın
yanında nasıl göründüğünü ya da tab bar küçüldüğünde alttaki accessory'nin ne yaptığını göstermez.
SwiftUI iOS 26 Showcase, her biri bu
API'lerden bir grubun etrafında kurulmuş on altı küçük ekrandan oluşan bir Swift paketi. Her
ekranda API'nin seçeneklerini denemek için kontroller var ve ekran kullandığı SDK sembollerini
listeliyor. Galerinin tamamını çalıştırabilir ya da tek bir ekranı kendi uygulamanıza
koyabilirsiniz.
Paket bu hâlde başlamadı. Repo Şubat 2026'da açıldı. 2.0.0 changelog'u yeniden kurulumdan önceki
durumu açıkça yazıyor: Haziran 2026'dan itibaren paket yalnız placeholder içeriyordu. SwiftUI ile
ilgisi olmayan "enterprise" yardımcılar (circuit breaker, retry policy, event bus), tek davranışı
bir print çağrısı olan bir galeri ve pakette olmayan tiplere referans veren bir test dosyası
vardı; bu yüzden testler hiç derlenmiyordu. Eski CI workflow'u test hatalarını yok saydığı için
yine de yeşil görünüyordu. 14 Ekim 2026'da
PR #3 ile yayınlanan 2.0.0
sürümü bunların hepsini değiştirdi. Eski public tipler kaldırıldığı için yeni bir major sürüm oldu.
Bu geçmiş, yeniden kurulumun ana hedefini belirledi: bir showcase ancak söyledikleri doğruysa işe
yarar ve bu iddiaları yazarın hafızası değil, otomatik bir kontrol doğrulamalı.
Tasarım kararları ve alternatifler
Tek doğruluk kaynağı olarak bir enum. Her demo, metadata'sıyla birlikte ShowcaseDemo'nun bir
case'i: başlık, özet, SF Symbol, kategori, gösterdiği API'ler ve çalıştığı platformlar. Galeri
satırları, arama ve README'deki demo tablosu hep bu metadata'dan geliyor. ShowcaseDemoView
view'ı seçmek için enum üzerinde switch yapıyor; view'ı olmayan bir case eklemek derlemeyi
kırıyor. Alternatif, her view'ın kendini kaydettiği bir Demo protocol'ü ve registry'ydi. Bu,
metadata'yı view'ın yanına koyar ama unutulan bir kayıt runtime'da sessizce eksik kalır; enum ile
bunu compiler yakalıyor.
SwiftUI'ı import etmeyen bir katalog. ShowcaseCatalog demoları platforma göre filtreliyor,
arıyor, kategoriye göre grupluyor ve kimlikle buluyor. Yalnız Foundation'ı import ediyor; galeri
onun üzerinde ince bir view. Böylece davranış düz unit testlerle test ediliyor. Arama kuralı
bilerek basit tutuldu: sorgudaki her kelime demonun başlığında, özetinde ya da API listesinde
geçiyorsa eşleşme var; büyük-küçük harf ve aksan farkı yok sayılıyor. Akla gelen alternatif fuzzy
eşleşmeydi, ama on altı öğe için tek cümleyle anlatılabilen bir kuralı test etmek ve öngörmek daha
kolay.
Platform farkı iki katmanda. İki demo macOS'ta olmayan API'ler kullanıyor:
tabBarMinimizeBehavior(_:) ve listSectionIndexVisibility(_:). View'ları #if os(iOS) ile
sarılı; macOS'ta ShowcaseDemoView bunların yerine bir ContentUnavailableView gösteriyor.
Metadata onları yalnız iOS olarak işaretliyor; bu yüzden macOS kataloğu kalan on dördünü
listeliyor ve demo(withID:) katalogun platformunda olmayan bir demo için nil döndürüyor. Bir
deep link, çalışmayacak bir ekranı açamıyor.
Küçük bir public yüzey. Public API galeri, ShowcaseDemoView, katalog tipleri ve README'de
belgelenen üç yardımcıdan oluşuyor: WebAddress, RichTextFormatter ve SurfaceFunction. On
altı demo view'ı internal; bu yüzden major sürüm gerektirmeden değişebiliyorlar. View gerektirmeyen
mantık, testlerin erişebilmesi için bu yardımcı tiplerde duruyor. Örneğin WebAddress yalnız host'u
olan ve kullanıcı adı içermeyen http ve https adreslerini kabul ediyor. Kaynaktaki bir yorum,
kullanıcı adı kontrolünün neden önemli olduğunu anlatıyor: o kontrol olmasa mailto:a@b.com,
başına https:// eklendiğinde b.com host'unda mailto kullanıcısı olarak ayrıştırılırdı.
Gerçek bir minimum toolchain. tabViewBottomAccessory(isEnabled:content:)
@available(iOS 26.1) ile işaretli. Tab bar demosu runtime'da #available(iOS 26.1, *) kontrolü
yapıyor, ama sembol SDK'da yoksa #available işe yaramıyor; bu yüzden Xcode 26.0 paketi derleyemiyor.
Getting Started makalesi minimum olarak Xcode 26.1'i yazacak şekilde değiştirildi (commit
7ec13b4); README ve changelog da aynı şeyi söylüyor.
Gerçek bir hata: kırılamayan render testi
Bu repodaki en faydalı ders, yanlış nedenle geçen bir testten çıktı.
İlk render testi everyAvailableDemoRenders, her demoyu ImageRenderer ile çizip görüntünün
boyutunu kontrol ediyordu. Boyut testin kendi verdiği frame'den geldiği için kontrol başarısız
olamazdı. Commit
`b5d727a` daha yakından
bakınca bulunanı kaydediyor: 14 demo görüntüsünün 11'i boştu. ImageRenderer bir ScrollView'ın
içeriğini çizmiyor ve demo sayfaları bir ScrollView içinde yerleşiyordu.
Düzeltmenin iki parçası vardı. Önce ba4c342 commit'i bir seam ekledi: scroll'u kapatan bir
environment değeri ve ona uyan küçük bir view.
swift
1/// A vertical scroll view, or just its content when `demoPagesScroll` is off.2struct DemoScrollView<Content: View>: View {3 @Environment(\.demoPagesScroll) private var scrolls4 @ViewBuilder let content: Content5 6 var body: some View {7 if scrolls {8 ScrollView { content }9 } else {10 content11 }12 }13}Varsayılan değer true kalıyor, yani uygulama eskisi gibi davranıyor. Üretim kodunda yalnız test
için var olan bir değer bu; kaynakta tek satırlık bir yorumla gerekçesi yazılı. Alternatifler bir
snapshot test kütüphanesi ya da UI testleriydi; ikisi de daha fazla bağımlılık ve daha yavaş koşu
demekti.
İkinci parça testin yeniden yazılmasıydı. Her demo artık scroll kapalıyken 390 point genişlikte ve
doğal yüksekliğinde çiziliyor, sonra yalnız aynı özet ve API listesine sahip boş bir DemoPage ile
karşılaştırılıyor. Demo daha uzun olmalı ve şeffaf olmayan daha fazla piksel çizmeli. Bir kontrol
testi ölçümün kendisini doğruluyor: Color.clear sıfır piksel çiziyor, bir satır metin sıfırdan
fazla. Commit mesajı, DemoPage'den içerik silindiğinde testin sayfa tabanlı her demo için
kırıldığını not ediyor.
Ardından aynı soru yeni teste de soruldu ve ikinci bir boşluk çıktı. Scroll edge demosu hâlâ düz bir
ScrollView kullanıyordu ve segmented picker'ı sayfa içeriğinin dışındaki bir safe area bar'da
duruyordu. Test yalnız picker'ı görüyordu: 30 satırın hepsini silmek piksel sayısını değiştirmiyordu
(2b30b15). Demo DemoScrollView'a taşındı, satır sayısı static bir sabit oldu ve ayrı bir test
artık sayfanın boş sayfadan en az rowCount × 44 point daha uzun olmasını istiyor. Satırlar
ForEach(0..<0) ile değiştirildiğinde sayfa 1.482 point'lik minimuma karşı 186 point kalıyor ve test
kırılıyor; 30 satırla sayfa 1.866 point (d35fd7f).
Son adım, testin göremediğini yazmaktı. ImageRenderer List ve WebView çizmiyor. List
tabanlı iki demo render testinin dışında bırakıldı. Web view demosundan WebView'ı silmek çizilen
yüksekliği ve piksel sayısını değiştirmiyor (205 point, 17.890 piksel), çünkü adres ve durum
çubukları tek başına sayfayı büyütmeye yetiyor (c713b8c). Bu not testin yanında duruyor; README de
aynı sınırları yazıyor.
Ders basit: yeşil bir kontrol, yakalayabildiği kadar değerlidir. Bunu öğrenmenin yolu, kodu bilerek
bozup testin kırıldığını görmek.
Kullanım
Xcode'da File › Add Package Dependencies… ile
https://github.com/muhittincamdali/SwiftUI-iOS26-Showcase.git adresini girin ve varsayılan kuralı
2.0.0'dan itibaren bırakın. Sonra uygulamanızın ana dosyasının içeriğini şununla değiştirin:
swift
1import SwiftUI2import SwiftUIiOS26Showcase3 4@main5struct DemoApp: App {6 var body: some Scene {7 WindowGroup {8 ShowcaseGallery()9 }10 }11}Tek bir demoyu kendi navigasyonunuzda göstermek için:
swift
1struct ChartScreen: View {2 var body: some View {3 NavigationStack {4 ShowcaseDemoView(.chart3D)5 }6 }7}Galerinin arkasındaki katalog doğrudan da kullanılabiliyor; örneğin kendi demo tarayıcınızı kurmak
için:
swift
1let catalog = ShowcaseCatalog(platform: .iOS)2let matches = catalog.demos(matching: "glass button") // [.glassButtons]3let sections = catalog.sections(matching: "symbol") // one section: Charts, Symbols & Animation4let demo = catalog.demo(withID: "webView") // .webViewBu bloklar ReadmeExamplesTests.swift dosyasına birebir kopyalı; orada derleniyor ve sonuçları
#expect ile kontrol ediliyor. Parametreli ayrı bir test README'yi okuyor ve demo tablosundaki bir
satır metadata ile uyuşmazsa kırılıyor. 2.0.0 tag'inde macOS'ta swift test 9 suite'te 39 test
koşuyor; CI testleri iOS Simulator'da da koşuyor ve örnek uygulamayı iOS ve macOS için derliyor.
Sınırlar
- Snapshot ya da UI testi yok. Render testi yalnız "bu demo kendi içeriğini çizdi mi" sorusuna
cevap veriyor; iki List demosu ve WebView içeriği bunun dışında.
- Scroll edge testi yalnız yüksekliğe bakıyor; hiçbir şey çizmeyen ama 44 point yüksekliğini koruyan
satırlar da geçer.
- Foundation Models demosu prompt gönderebilmek için Apple Intelligence'ı açık bir cihaz istiyor;
web view demosu ağ bağlantısı istiyor. Ne model çağrısı ne de sayfa yüklemesi otomatik test
ediliyor.
- Minimum toolchain Xcode 26.1 olarak yazılı, ama CI
macos-26runner image'ında sürüm matrisi
olmadan koşuyor; bu alt sınır ayrıca test edilmiyor.
- Demo metinleri yalnız İngilizce. README'nin dokuz çevirisi var, uygulamanın yok.
- 2.0.0 tag'inde README'nin Installation bölümündeki
Package.swiftörneği hâlâbranch: "main"
kullanıyor; quick start ve Getting Started makalesi ise 2.0.0 kullanıyor.
- README'deki yol haritasında tek madde var: sonraki iOS 26 güncellemeleriyle gelen SwiftUI
API'leri için yeni demolar.
Kod, changelog ve testler repoda, API
referansı GitHub Pages'te.

