@ScaledMetric — bu nədir, SwiftUI property wrapper və Dynamic Type

Müəllif: IT Sectr Dərc olunub: 2026-06-27 Oxuma vaxtı: 10 dəq

@ScaledMetric — SwiftUI property wrapper-i, istifadəçinin Dynamic Type parametrlərinə uyğun olaraq ədədi dəyəri avtomatik miqyaslayır. Dəyər @ScaledMetric-ə bükülür və sistem şrift ölçüsü dəyişdikdə yenidən hesablanır ki, bu da görmə qüsuru olan insanlar üçün interfeysin əlçatanlığını təmin edir. Apple Developer Documentation (2026) məlumatına görə, @ScaledMetric preferred content size category əsasında nisbi miqyası hesablamaq üçün UIFontMetrics şkalasından istifadə edir. Əlçatanlıq haqqında daha ətraflı SwiftUI accessibility materialında oxuyun.

Əsas məqamlar

  • @ScaledMetric — Dynamic Type altında dəyərləri miqyaslamaq üçün SwiftUI property wrapper-i.
  • Dynamic Type — iOS-un sistem parametri, şrift ölçüsünü UIFontTextStyle-dən dəyişir.
  • Miqyaslama — @ScaledMetric əsas dəyər və relativeTo çarpanını qəbul edir.
  • Avtomatik yenilənmə — Dynamic Type dəyişdikdə @ScaledMetric yenidən hesablanır və UI yenilənir.
  • Accessibility — @ScaledMetric istifadəsi əlavə kod olmadan interfeysin əlçatanlığını yaxşılaşdırır.

@ScaledMetric nədir?

@ScaledMetric — iOS 14-də əlavə edilmiş SwiftUI property wrapper-i, ədədi dəyəri (CGFloat, Int, Double) cari Dynamic Type şrift ölçüsünə avtomatik miqyaslayır. Şriftlər üçün .font(.body)-dən fərqli olaraq, @ScaledMetric istənilən ədədi parametrləri miqyaslayır: padding, spacing, cornerRadius, iconSize — böyük məndə proporsional artmalı olan hər şey.

@ScaledMetric-in əsas vəzifəsi interfeysin qeyri-mətn elementlərinin əlçatanlıq miqyaslanmasını təmin etməkdir. İstifadəçi iOS parametrlərində şrifti böyütdükdə, düymələr, ikonlar və boşluqlar proporsional artmalıdır ki, interfeys balanslı qalsın. @ScaledMetric bu vəzifəni əl ilə çarpan hesablamadan avtomatik həll edir.

@ScaledMetric sintaksisi

Əsas sintaksis @ScaledMetric standart dəyər və isteğe bağlı relativeTo parametrindən istifadə edir. Əgər relativeTo göstərilibsə, miqyaslama konkret mətn stilinə (UIFontTextStyle) bağlanır. Göstərilməyibsə — .body şkalası istifadə olunur.

swift
struct AccessibleButton: View {
    @ScaledMetric private var padding: CGFloat = 12
    @ScaledMetric(relativeTo: .title) private var iconSize: CGFloat = 24
    
    var body: some View {
        Label("Göndər", systemImage: "checkmark.circle.fill")
            .font(.body)
            .padding(padding)
            .imageScale(.init(rawValue: iconSize / 24) ?? .medium)
    }
}

padding .body-yə nisbətən (standart), iconSize isə .title-ə nisbətən miqyaslanacaq. Böyük məndə boşluqlar və ikon proporsional artacaq. @ScaledMetric olmadan boşluqlar istənilən şrift ölçüsündə 12 pt qalacaq ki, bu da vizual balanssızlığa səbəb olardı.

@ScaledMetric necə işləyir

@ScaledMetric mexanizmi UIKit-dən UIFontMetrics-ə əsaslanır. SwiftUI @ScaledMetric nümunəsi yaratdıqda, cari preferred content size category (UIContentSizeCategory) əsasında çarpan hesablayır. Əsas dəyər göstərilən mətn stili üçün UIFontMetrics-dən scaledValue-ə vurulur.

Riyazi olaraq: ScaledMetricValue = baseValue × UIFontMetrics.scaledValue(for: relativeTo). Əgər relativeTo göstərilməyibsə, .body-yə bağlı UIFontMetrics.default istifadə olunur. Dynamic Type dəyişdikdə SwiftUI View-in gövdəsini yenidən yaradır, @ScaledMetric yeni scaledValue hesablayır və UI @State bənzəri PropertyWrappers mexanizmi ilə avtomatik yenilənir.

Dynamic Type miqyaslama şkalası

iOS şkalası 11 ölçü əhatə edir: .extraSmall (5 pt)-dən .accessibilityExtraExtraExtraLarge (77 pt .body üçün). .body üçün miqyaslama əmsalı 0.85 (XS) ilə 1.71 (XXXL) arasında dəyişir. @ScaledMetric məhz bu şkaladan istifadə edir, ona görə də padding üçün 12 pt dəyəri maksimum əlçatanlıq ölçüsündə ~20 pt ola bilər.

Content Size CategoryƏmsal (body)Nümunə @ScaledMetric(12)
extraSmall0.85~10 pt
small0.93~11 pt
medium (default)1.0012 pt
large1.07~13 pt
extraLarge1.15~14 pt
extraExtraLarge1.28~15 pt
accessibilityExtraLarge1.47~18 pt
accessibilityXXXL1.71~20 pt

relativeTo seçimi: əsas mətnlə bağlı dəyərlər üçün .body (padding, spacing siyahılarda), böyük elementlər üçün .title (iconSize, imageSize), kiçik elementlər üçün .caption (badge ölçüsü) istifadə edin. Bu, elementlərin ətrafdakı mətnlə uyğun miqyaslanmasını təmin edir.

@ScaledMetric və Dynamic Type

Dynamic Type — iOS funksiyası, istifadəçiyə sistem şrift ölçüsünü Settings → Display & Brightness → Text Size bölməsində tənzimləməyə imkan verir. Dəyişiklik bütün tətbiqlərə qlobal tətbiq olunur. @ScaledMetric bu dəyişikliyə avtomatik reaksiya verir: SwiftUI UIContentSizeCategory dəyişdikdə bütün @ScaledMetric dəyişənlərini yeniləyir.

Vacib: @ScaledMetric yalnız ədədi dəyərləri miqyaslayır, şriftləri birbaşa idarə etmir. Şriftlər üçün .font() mətn stili ilə (.body, .title, .headline) istifadə edin — SwiftUI şrifti avtomatik miqyaslayır. @ScaledMetric padding, spacing və element ölçüləri üçün şrift miqyaslanmasını tamamlayır.

Canvas vasitəsilə əlçatanlığın yoxlanılması

Canvas Preview Dynamic Type-i dəstəkləyir: Canvas alətlər panelində müxtəlif şrift ölçülərində UI-ni yoxlamaq üçün Text Size (A–A) sürgüsü var. @ScaledMetric ilə istifadə edərək, boşluqların və ölçülərin düzgün miqyaslandığına əmin olun.

swift
struct CardView: View {
    @ScaledMetric private var cornerRadius: CGFloat = 16
    @ScaledMetric private var spacing: CGFloat = 8
    
    var body: some View {
        VStack(spacing: spacing) {
            Text("Kart başlığı")
                .font(.headline)
            Text("Dynamic type dəstəyi olan təsvir")
                .font(.body)
        }
        .padding(spacing * 2)
        .background(.regularMaterial)
        .cornerRadius(cornerRadius)
    }
}

struct CardView_Previews: PreviewProvider {
    static var previews: some View {
        CardView()
            .dynamicTypeSize(.large)
            .previewDisplayName("Large")
        CardView()
            .dynamicTypeSize(.accessibility5)
            .previewDisplayName("Accessibility 5")
    }
}

cornerRadius 16 pt-dən maksimum əlçatanlıq ölçüsündə ~27 pt-ə qədər miqyaslanır. spacing — 8-dən ~14 pt-ə qədər. Bu, kartın istənilən şrift ölçüsündə vizual balanslı qalmasını təmin edir.

@ScaledMetric nümunələri

Nümunə: Dynamic Type dəstəyi olan ikon. Image(systemName:) ikonlarının ölçüsü standart olaraq Dynamic Type altında miqyaslanmır. @ScaledMetric bu problemi həll edir: cari miqyas faktoruna əsasən imageScale və ya frame ölçüsünü dəyişərək.

swift
struct IconLabel: View {
    let title: String
    let icon: String
    
    @ScaledMetric private var iconDimension: CGFloat = 28
    @ScaledMetric(relativeTo: .body) private var spacing: CGFloat = 6
    
    var body: some View {
        HStack(spacing: spacing) {
            Image(systemName: icon)
                .resizable()
                .frame(width: iconDimension, height: iconDimension)
            Text(title)
                .font(.body)
        }
    }
}

Nümunə: əlçatan badge-komponenti. Rəqəm olan badge mətnə proporsional miqyaslanmalıdır. Badge-in minimum ölçüsü üçün @ScaledMetric dairəvi badge-in böyük şriftdə görünən qalmasını təmin edir.

swift
struct BadgeView: View {
    let count: Int
    
    @ScaledMetric(relativeTo: .caption) private var badgeSize: CGFloat = 20
    @ScaledMetric(relativeTo: .caption) private var fontScale: CGFloat = 1
    
    var body: some View {
        ZStack {
            Circle()
                .fill(.red)
                .frame(width: badgeSize, height: badgeSize)
            
            Text("\(count)")
                .font(.caption)
                .foregroundColor(.white)
                .scaleEffect(fontScale)
        }
        .fixedSize()
    }
}

fontScale əlavə olaraq Circle məzmununu artırılmış badgeSize-ə uyğun miqyaslayır. fontScale olmadan badge daxilindəki mətn böyük şriftdə sığmaya bilər.

@ScaledMetric vs @State — fərqlər

@ScaledMetric@State — hər ikisi dəyişiklikləri izləyən property wrapper-lardır, lakin fərqli yeniləmə mənbələri ilə. @State proqram dəyişikliyində ($stateBinding vasitəsilə) dəyəri yeniləyir. @ScaledMetric sistem Dynamic Type dəyişdikdə dəyəri avtomatik yeniləyir, lakin dəyəri birbaşa koddan dəyişməyə imkan vermir.

Əsas fərq: @ScaledMetric — proqramçı üçün read-only, sistem üçün write-only. Siz scaledValue dəyərini setter vasitəsilə dəyişə bilməzsiniz — o, SwiftUI tərəfindən əsas dəyər və cari Dynamic Type əsasında hesablanır. @State isə tamamilə proqramçı tərəfindən idarə olunur. Əgər həm Dynamic Type altında miqyaslanan, həm də proqram dəyişdirilə bilən dəyər lazımdırsa — @ScaledMetric-i @State ilə birləşdirin və ya hesablanmış xassədən istifadə edin.

Xüsusiyyət@ScaledMetric@State
Yeniləmə mənbəyiDynamic Type (sistem)Proqram (proqramçı)
Dəyər tipiCGFloat, Int, Doubleİstənilən
Koddan dəyişməMümkün deyilBinding vasitəsilə mümkündür
View-in yenidən çəkilməsiDynamic Type dəyişdikdəDəyər dəyişdikdə
iOS versiyasıiOS 14+iOS 13+

Birləşmiş nümunə: padding-i proqram dəyişmək (məsələn, klik animasiyası) və eyni zamanda Dynamic Type altında miqyaslamaq lazımdırsa, əsas miqyaslı dəyər üçün @ScaledMetric və animasiya çarpanı üçün @State yaradın. Yekun dəyər = scaledValue × animationMultiplier.

@ScaledMetric ilə tipik səhvlər

Səhv 1: @ScaledMetric-in şriftlər üçün istifadəsi. @ScaledMetric ədədləri miqyaslayır, şriftləri yox. Şriftlər üçün .font(.body) istifadə edin — SwiftUI avtomatik Dynamic Type tətbiq edir. Heç vaxt @ScaledMetric-i font(.system(size: scaledSize)) ilə istifadə etməyin — bu sistem əlçatanlığını pozur.

Səhv 2: müxtəlif elementlər üçün relativeTo-nun olmaması. Əgər padding (.body ilə bağlı) və iconSize (.title ilə bağlı) varsa, hər biri üçün düzgün relativeTo göstərin. relativeTo olmadan hər ikisi .body-yə görə miqyaslanacaq ki, bu da ikonun mətn kontekstinə nisbətən qeyri-proporsional artmasına səbəb olacaq.

Səhv 3: ViewModel/@ObservableObject-da @ScaledMetric. @ScaledMetric yalnız View daxilində işləyən SwiftUI property wrapper-idir. Onu ViewModel və ya xidmətlərdə istifadə etmək olmaz. ViewModel-də miqyaslama üçün View-dən miqyaslı dəyəri parametr kimi ötürün və ya View-də @Environment(\.sizeCategory) istifadə edin.

Koddan cari size category-nin alınması

@Environment(\.sizeCategory) — View-də cari Dynamic Type-i əldə etməyin alternativ yolu. Daha çox nəzarət lazım olduqda istifadə edin: fərdi çarpan hesablamaq, sizeCategory-ni ViewModel-ə ötürmək və ya çevik miqyaslama üçün @ScaledMetric ilə birləşdirmək.

swift
struct CustomScaledView: View {
    @Environment(\.sizeCategory) private var sizeCategory
    @ScaledMetric private var basePadding: CGFloat = 12
    
    private var extraPadding: CGFloat {
        if sizeCategory >= .accessibilityLarge {
            return basePadding * 0.5
        }
        return 0
    }
    
    var body: some View {
        Text("Fərdi miqyaslı məzmun")
            .font(.body)
            .padding(basePadding + extraPadding)
    }
}

Əlavə boşluq extraPadding yalnız əlçatanlıq ölçülərində əlavə olunur, əsas @ScaledMetric məntiqini dəyişmədən böyük mətn üçün daha çox hava verir.

Tez-tez verilən suallar

@ScaledMetric @ScaledFont-dan nə ilə fərqlənir?

@ScaledMetric — ədədləri miqyaslamaq üçün rəsmi SwiftUI property wrapper-i. @ScaledFont standart API kimi mövcud deyil — bu, icma tərəfindən həyata keçirilmiş fərdi wrapper-dir. Şriftlər üçün həmişə daxili .font() mətn stilləri ilə (.body, .title) istifadə edin, @ScaledMetric isə padding, spacing və ölçülər üçündür.

@ScaledMetric watchOS və tvOS-da işləyir?

@ScaledMetric iOS 14+, watchOS 7+, tvOS 14+ və macOS 11+-da mövcuddur. watchOS-da Dynamic Type daha kiçik diapazonla məhduddur — .extraSmall-dan .extraLarge-a qədər ölçülər əlçatanlıq ölçüləri olmadan. tvOS-da Dynamic Type yoxdur — @ScaledMetric həmişə əsas dəyəri qaytarır.

@ScaledMetric-i unit-testlərdə test etmək olar?

Bəli, @ScaledMetric-i test etmək üçün @ScaledMetric olan View yaradın və .environment(\.sizeCategory, .extraExtraLarge) vasitəsilə .sizeCategory environment dəyərini ötürün. Sonra elementin ölçüsünü GeometryReader və ya SwiftUI Inspector vasitəsilə əldə edin. Alternativ olaraq, ayrı modulda UIFontMetrics vasitəsilə miqyaslama məntiqini yoxlayın.

@ScaledMetric .dynamicTypeSize ilə necə qarşılıqlı əlaqədədir?

.dynamicTypeSize — iyerarxiya üçün maksimum Dynamic Type-i məhdudlaşdıran View modifier-i (məsələn, .dynamicTypeSize(...large)). @ScaledMetric bu məhdudiyyəti nəzərə alır: əgər .dynamicTypeSize təyin edilibsə, miqyaslı dəyər müvafiq ölçüdən artıq olmayacaq. Dəqiq nəzarət üçün hər iki API-i birləşdirin.

@ScaledMetric UI-ni yeniləmirsə nə etməli?

View-in @ScaledMetric-i öz daxilində istifadə etdiyinə əmin olun (ViewModel-də yox). View-in Dynamic Type-i abunə etdiyini yoxlayın: @ScaledMetric avtomatik body yeniləməsini çağırır, lakin View .equatable() və ya .id() istifadə edirsə, mexanizm poza bilər. Fallback olaraq @Environment(\.sizeCategory) istifadə edin.

Nəticə

  • @ScaledMetric — Dynamic Type altında ədədləri avtomatik miqyaslamaq üçün SwiftUI property wrapper-i.
  • Bağlama — relativeTo miqyası konkret mətn stilinə (body, title, caption) bağlayır.
  • Accessibility — @ScaledMetric əl ilə kod yazmadan interfeysin əlçatanlığını yaxşılaşdırır.
  • Yalnız ədədlər — wrapper CGFloat, Int, Double miqyaslayır, şriftləri yox.
  • Diapazon — 0.85 (XS) ilə 1.71 (XXXL) arasında əsas dəyərə nisbətən.
  • Read-only — @ScaledMetric-i koddan dəyişmək olmaz, yalnız sistem vasitəsilə.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun