@ScaledMetric — यह क्या है, SwiftUI property wrapper और Dynamic Type

लेखक: IT Sectr प्रकाशित: 2026-06-27 पढ़ने का समय: 10 मिनट

@ScaledMetric एक SwiftUI property wrapper है जो उपयोगकर्ता की Dynamic Type सेटिंग्स के अनुसार स्वचालित रूप से एक संख्यात्मक मान को स्केल करता है। मान को @ScaledMetric में लपेटा जाता है और सिस्टम फ़ॉन्ट आकार बदलने पर पुनर्गणना किया जाता है, जिससे दृश्य हानि वाले लोगों के लिए इंटरफ़ेस की पहुँच सुनिश्चित होती है। Apple Developer Documentation (2026) के अनुसार, @ScaledMetric preferred content size category के आधार पर सापेक्ष स्केल की गणना करने के लिए UIFontMetrics स्केल का उपयोग करता है। पहुँच के बारे में अधिक जानकारी के लिए SwiftUI पहुँच लेख देखें।

मुख्य बातें

  • @ScaledMetric — Dynamic Type के अनुसार मान स्केल करने के लिए SwiftUI property wrapper।
  • Dynamic Type — iOS सिस्टम सेटिंग जो UIFontTextStyle से फ़ॉन्ट आकार बदलती है।
  • स्केलिंग — @ScaledMetric एक आधार मान और relativeTo गुणक लेता है।
  • स्वचालित अपडेट — Dynamic Type बदलने पर @ScaledMetric पुनर्गणना करता है और UI अपडेट होता है।
  • पहुँच — @ScaledMetric का उपयोग बिना अतिरिक्त कोड के इंटरफ़ेस पहुँच में सुधार करता है।

@ScaledMetric क्या है?

@ScaledMetric एक SwiftUI property wrapper है, जो iOS 14 में जोड़ा गया, जो स्वचालित रूप से एक संख्यात्मक मान (CGFloat, Int, Double) को वर्तमान Dynamic Type फ़ॉन्ट आकार में स्केल करता है। फ़ॉन्ट के लिए .font(.body) के विपरीत, @ScaledMetric किसी भी संख्यात्मक पैरामीटर को स्केल करता है: padding, spacing, cornerRadius, iconSize — वह सब कुछ जो बड़े टेक्स्ट के साथ आनुपातिक रूप से बढ़ना चाहिए।

@ScaledMetric का मुख्य उद्देश्य गैर-पाठ इंटरफ़ेस तत्वों के लिए पहुँच स्केलिंग प्रदान करना है। जब उपयोगकर्ता iOS सेटिंग्स में फ़ॉन्ट आकार बढ़ाता है, तो बटन, आइकन और स्पेसिंग को इंटरफ़ेस को संतुलित रखने के लिए आनुपातिक रूप से स्केल होना चाहिए। @ScaledMetric मैन्युअल गुणक गणना के बिना, स्वचालित रूप से इसे संभालता है।

@ScaledMetric सिंटैक्स

मूल सिंटैक्स @ScaledMetric एक डिफ़ॉल्ट मान और एक वैकल्पिक relativeTo पैरामीटर का उपयोग करता है। यदि relativeTo निर्दिष्ट किया गया है, तो स्केलिंग एक विशिष्ट टेक्स्ट शैली (UIFontTextStyle) से बंधी होती है। यदि नहीं, तो .body स्केल का उपयोग किया जाता है।

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

padding .body (डिफ़ॉल्ट) के सापेक्ष स्केल होगा, iconSize .title के सापेक्ष। बड़े टेक्स्ट के साथ, स्पेसिंग और आइकन आनुपातिक रूप से स्केल होंगे। @ScaledMetric के बिना, padding फ़ॉन्ट आकार की परवाह किए बिना 12 pt पर रहेगा, जिससे दृश्य असंतुलन होगा।

@ScaledMetric कैसे काम करता है

@ScaledMetric तंत्र UIKit से UIFontMetrics पर आधारित है। जब SwiftUI एक @ScaledMetric इंस्टेंस बनाता है, तो यह वर्तमान preferred content size category (UIContentSizeCategory) के आधार पर एक गुणक की गणना करता है। आधार मान को निर्दिष्ट टेक्स्ट शैली के लिए UIFontMetrics से scaledValue से गुणा किया जाता है।

गणितीय रूप से: ScaledMetricValue = baseValue × UIFontMetrics.scaledValue(for: relativeTo)। यदि relativeTo निर्दिष्ट नहीं है, तो UIFontMetrics.default का उपयोग किया जाता है, जो .body से बंधा होता है। जब Dynamic Type बदलता है, SwiftUI View बॉडी को फिर से बनाता है, @ScaledMetric एक नया scaledValue की गणना करता है, और UI @State-जैसे PropertyWrappers तंत्र के माध्यम से स्वचालित रूप से अपडेट होता है।

Dynamic Type स्केलिंग पैमाना

iOS पैमाना में 11 आकार शामिल हैं: .extraSmall (5 pt) से .accessibilityExtraExtraExtraLarge (77 pt for .body) तक। .body के लिए स्केलिंग कारक आधार मान के सापेक्ष 0.85 (XS) से 1.71 (XXXL) तक होता है। @ScaledMetric बिल्कुल इसी पैमाने का उपयोग करता है, इसलिए 12 pt का padding मान अधिकतम पहुँच आकार पर ~20 pt हो सकता है।

सामग्री आकार श्रेणीकारक (body)उदाहरण @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 चुनना: बॉडी टेक्स्ट से संबंधित मानों (padding, spacing in lists) के लिए .body का उपयोग करें, बड़े तत्वों (iconSize, imageSize) के लिए .title, छोटे तत्वों (badge size) के लिए .caption। यह सुनिश्चित करता है कि तत्व आसपास के टेक्स्ट के साथ तालमेल में स्केल हों।

@ScaledMetric और Dynamic Type

Dynamic Type एक iOS सुविधा है जो उपयोगकर्ताओं को सेटिंग्स → डिस्प्ले और ब्राइटनेस → टेक्स्ट आकार में सिस्टम फ़ॉन्ट आकार समायोजित करने देती है। परिवर्तन सभी ऐप्स पर वैश्विक रूप से लागू होता है। @ScaledMetric इस परिवर्तन पर स्वचालित रूप से प्रतिक्रिया करता है: SwiftUI UIContentSizeCategory बदलने पर सभी @ScaledMetric वेरिएबल्स को अपडेट करता है।

महत्वपूर्ण: @ScaledMetric केवल संख्यात्मक मानों को स्केल करता है, यह सीधे फ़ॉन्ट प्रबंधित नहीं करता है। फ़ॉन्ट के लिए, एक टेक्स्ट शैली (.body, .title, .headline) के साथ .font() का उपयोग करें — SwiftUI स्वचालित रूप से फ़ॉन्ट को स्केल करता है। @ScaledMetric padding, spacing और तत्व आकारों के लिए फ़ॉन्ट स्केलिंग का पूरक है।

Canvas के माध्यम से पहुँच परीक्षण

Canvas Preview Dynamic Type का समर्थन करता है: Canvas टूलबार में विभिन्न फ़ॉन्ट आकारों पर UI परीक्षण करने के लिए एक टेक्स्ट आकार स्लाइडर (A–A) है। यह सुनिश्चित करने के लिए @ScaledMetric के साथ इसका उपयोग करें कि स्पेसिंग और आकार सही ढंग से स्केल हों।

swift
struct CardView: View {
    @ScaledMetric private var cornerRadius: CGFloat = 16
    @ScaledMetric private var spacing: CGFloat = 8
    
    var body: some View {
        VStack(spacing: spacing) {
            Text("Card Title")
                .font(.headline)
            Text("Description with dynamic type support")
                .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 से ~27 pt तक स्केल होता है। spacing — 8 से ~14 pt तक। यह सुनिश्चित करता है कि कार्ड किसी भी फ़ॉन्ट आकार पर दृश्य रूप से संतुलित रहे।

@ScaledMetric उदाहरण

उदाहरण: Dynamic Type समर्थित आइकन. Image(systemName:) आइकन आकार डिफ़ॉल्ट रूप से Dynamic Type के अनुसार स्केल नहीं होते हैं। @ScaledMetric वर्तमान स्केल कारक के आधार पर imageScale या फ्रेम आकार बदलकर इस समस्या को हल करता है।

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)
        }
    }
}

उदाहरण: सुलभ बैज घटक. एक क्रमांकित बैज को टेक्स्ट के अनुपात में स्केल होना चाहिए। न्यूनतम बैज आकार के लिए @ScaledMetric यह सुनिश्चित करता है कि गोलाकार बैज बड़े टेक्स्ट के साथ दृश्यमान रहे।

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 बढ़े हुए badgeSize से मेल खाने के लिए Circle सामग्री को अतिरिक्त रूप से स्केल करता है। fontScale के बिना, बैज के अंदर का टेक्स्ट बड़े टेक्स्ट के साथ फ़िट नहीं हो सकता है।

@ScaledMetric बनाम @State — अंतर

@ScaledMetric और @State दोनों property wrappers हैं जो परिवर्तनों को ट्रैक करते हैं, लेकिन अलग-अलग अपडेट स्रोतों के साथ। @State प्रोग्रामेटिक परिवर्तन पर मान अपडेट करता है ($stateBinding के माध्यम से)। @ScaledMetric सिस्टम Dynamic Type बदलने पर स्वचालित रूप से मान अपडेट करता है, लेकिन कोड से सीधे मान बदलने की अनुमति नहीं देता है।

मुख्य अंतर: @ScaledMetric डेवलपर के लिए केवल-पठनीय और सिस्टम के लिए केवल-लेखनीय है। आप setter के माध्यम से scaledValue नहीं बदल सकते — यह SwiftUI द्वारा आधार मान और वर्तमान Dynamic Type के आधार पर गणना किया जाता है। @State, दूसरी ओर, पूरी तरह से डेवलपर-नियंत्रित है। यदि आपको एक ऐसे मान की आवश्यकता है जो Dynamic Type के अनुसार स्केल भी हो और प्रोग्रामेटिक रूप से बदले भी — @ScaledMetric को @State के साथ combine करें या एक गणना की गई प्रॉपर्टी का उपयोग करें।

विशेषता@ScaledMetric@State
अपडेट स्रोतDynamic Type (सिस्टम)प्रोग्रामेटिक (डेवलपर)
मान प्रकारCGFloat, Int, Doubleकोई भी
कोड से बदलावअनुमत नहींbinding के माध्यम से अनुमत
View पुनर्चित्रणDynamic Type बदलने परमान बदलने पर
iOS संस्करणiOS 14+iOS 13+

संयुक्त पैटर्न: यदि आपको Dynamic Type के अनुसार स्केलिंग करते हुए प्रोग्रामेटिक रूप से padding बदलने की आवश्यकता है (जैसे, टैप एनिमेशन), तो आधार स्केल किए गए मान के लिए @ScaledMetric और एनिमेशन गुणक के लिए @State बनाएँ। अंतिम मान = scaledValue × animationMultiplier।

@ScaledMetric के साथ सामान्य गलतियाँ

गलती 1: फ़ॉन्ट के लिए @ScaledMetric का उपयोग करना। @ScaledMetric संख्याओं को स्केल करता है, फ़ॉन्ट को नहीं। फ़ॉन्ट के लिए, .font(.body) का उपयोग करें — SwiftUI स्वचालित रूप से Dynamic Type लागू करता है। @ScaledMetric को font(.system(size: scaledSize)) के साथ कभी उपयोग न करें — यह सिस्टम पहुँच को तोड़ता है।

गलती 2: विषम तत्वों के लिए relativeTo की कमी। यदि आपके पास padding (.body से बंधा) और iconSize (.title से बंधा) है, तो प्रत्येक के लिए सही relativeTo निर्दिष्ट करें। relativeTo के बिना, दोनों .body द्वारा स्केल होंगे, जिससे इसके टेक्स्ट संदर्भ के सापेक्ष आइकन का अनुपातहीन स्केलिंग होगा।

गलती 3: ViewModel/@ObservableObject में @ScaledMetric। @ScaledMetric एक SwiftUI property wrapper है जो केवल View के अंदर काम करता है। इसका उपयोग ViewModels या सेवाओं में नहीं किया जा सकता है। ViewModel में स्केलिंग के लिए, View से स्केल किए गए मान को पैरामीटर के रूप में पास करें या View में @Environment(\.sizeCategory) का उपयोग करें।

कोड में वर्तमान आकार श्रेणी प्राप्त करना

@Environment(\.sizeCategory) View में वर्तमान Dynamic Type प्राप्त करने का एक वैकल्पिक तरीका है। इसका उपयोग तब करें जब आपको अधिक नियंत्रण की आवश्यकता हो: एक कस्टम गुणक की गणना करना, sizeCategory को ViewModel में पास करना, या लचीले स्केलिंग के लिए @ScaledMetric के साथ संयोजित करना।

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("Custom scaled content")
            .font(.body)
            .padding(basePadding + extraPadding)
    }
}

अतिरिक्त padding extraPadding केवल पहुँच आकारों पर जोड़ा जाता है, जो आधार @ScaledMetric तर्क को बदले बिना बड़े टेक्स्ट के लिए अधिक स्थान प्रदान करता है।

अक्सर पूछे जाने वाले प्रश्न

@ScaledMetric, @ScaledFont से कैसे भिन्न है?

@ScaledMetric संख्याओं को स्केल करने के लिए एक आधिकारिक SwiftUI property wrapper है। @ScaledFont एक मानक API के रूप में मौजूद नहीं है — यह समुदाय द्वारा कार्यान्वित एक कस्टम wrapper है। फ़ॉन्ट के लिए, हमेशा टेक्स्ट शैलियों (.body, .title) के साथ अंतर्निहित .font() का उपयोग करें, और padding, spacing और आकारों के लिए @ScaledMetric का उपयोग करें।

क्या @ScaledMetric watchOS और tvOS पर काम करता है?

@ScaledMetric iOS 14+, watchOS 7+, tvOS 14+ और macOS 11+ पर उपलब्ध है। watchOS पर, Dynamic Type एक छोटी सीमा तक सीमित है — पहुँच आकारों के बिना .extraSmall से .extraLarge तक के आकार उपलब्ध हैं। tvOS पर, Dynamic Type उपलब्ध नहीं है — @ScaledMetric हमेशा आधार मान लौटाता है।

क्या @ScaledMetric का यूनिट परीक्षणों में परीक्षण किया जा सकता है?

हाँ, @ScaledMetric का परीक्षण करने के लिए @ScaledMetric के साथ एक View बनाएँ और .environment(\.sizeCategory, .extraExtraLarge) के माध्यम से पर्यावरण .sizeCategory मान पास करें। फिर GeometryReader या SwiftUI Inspector के माध्यम से तत्व का आकार प्राप्त करें। वैकल्पिक रूप से, एक अलग मॉड्यूल में UIFontMetrics के माध्यम से स्केलिंग तर्क का परीक्षण करें।

@ScaledMetric .dynamicTypeSize के साथ कैसे इंटरैक्ट करता है?

.dynamicTypeSize एक View संशोधक है जो एक पदानुक्रम के लिए अधिकतम Dynamic Type को सीमित करता है (जैसे, .dynamicTypeSize(...large))। @ScaledMetric इस सीमा का सम्मान करता है: यदि .dynamicTypeSize सेट किया गया है, तो स्केल किया गया मान संबंधित आकार से अधिक नहीं होगा। सटीक नियंत्रण के लिए दोनों APIs को मिलाएँ।

यदि @ScaledMetric UI अपडेट नहीं करता है तो क्या करें?

सुनिश्चित करें कि View आंतरिक रूप से @ScaledMetric का उपयोग करता है (ViewModel में नहीं)। जाँचें कि View Dynamic Type की सदस्यता लेता है: @ScaledMetric स्वचालित रूप से body रिफ्रेश को ट्रिगर करता है, लेकिन यदि View .equatable() या .id() का उपयोग करता है, तो तंत्र टूट सकता है। फ़ॉलबैक के रूप में @Environment(\.sizeCategory) का उपयोग करें।

सारांश

  • @ScaledMetric — Dynamic Type के अनुसार स्वचालित संख्या स्केलिंग के लिए SwiftUI property wrapper।
  • बंधन — relativeTo स्केल को एक विशिष्ट टेक्स्ट शैली (body, title, caption) से बाँधता है।
  • पहुँच — @ScaledMetric बिना मैन्युअल कोड के इंटरफ़ेस पहुँच में सुधार करता है।
  • केवल संख्याएँ — wrapper CGFloat, Int, Double को स्केल करता है, लेकिन फ़ॉन्ट को नहीं।
  • सीमा — आधार मान के सापेक्ष 0.85 (XS) से 1.71 (XXXL) तक।
  • केवल-पठनीय — @ScaledMetric को कोड से नहीं बदला जा सकता, केवल सिस्टम के माध्यम से।

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें