@ScaledMetric ایک SwiftUI property wrapper ہے جو صارف کی Dynamic Type ترتیبات کے مطابق خود بخود ایک عددی قدر کو پیمائش کرتا ہے۔ قدر کو @ScaledMetric میں لپیٹا جاتا ہے اور سسٹم فونٹ سائز تبدیل ہونے پر دوبارہ شمار کیا جاتا ہے، جو بصارت سے محروم افراد کے لیے انٹرفیس کی رسائی کو یقینی بناتا ہے۔ Apple Developer Documentation (2026) کے مطابق، @ScaledMetric preferred content size category کی بنیاد پر نسبتاً پیمانہ شمار کرنے کے لیے UIFontMetrics پیمانہ استعمال کرتا ہے۔ رسائی کے بارے میں مزید معلومات کے لیے SwiftUI رسائی مضمون دیکھیں۔
اہم نکات
@ScaledMetric ایک SwiftUI property wrapper ہے، جو iOS 14 میں شامل کیا گیا، جو خود بخود ایک عددی قدر (CGFloat, Int, Double) کو موجودہ Dynamic Type فونٹ سائز میں پیمائش کرتا ہے۔ فونٹس کے لیے .font(.body) کے برعکس، @ScaledMetric کسی بھی عددی پیرامیٹر کو پیمائش کرتا ہے: padding, spacing, cornerRadius, iconSize — ہر وہ چیز جو بڑے متن کے ساتھ متناسب طور پر بڑھنی چاہیے۔
@ScaledMetric کا بنیادی مقصد غیر متنی انٹرفیس عناصر کے لیے رسائی کی پیمائش فراہم کرنا ہے۔ جب صارف iOS ترتیبات میں فونٹ سائز بڑھاتا ہے، تو بٹن، آئیکن اور فاصلے انٹرفیس کو متوازن رکھنے کے لیے متناسب طور پر پیمائش ہونے چاہئیں۔ @ScaledMetric دستی ضارب شمار کے بغیر خود بخود اسے سنبھالتا ہے۔
بنیادی نحو @ScaledMetric ایک ڈیفالٹ قدر اور ایک اختیاری relativeTo پیرامیٹر استعمال کرتا ہے۔ اگر relativeTo متعین کیا جاتا ہے، تو پیمائش ایک مخصوص متن کے اسٹائل (UIFontTextStyle) سے منسلک ہوتی ہے۔ اگر نہیں، تو .body پیمانہ استعمال ہوتا ہے۔
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 میکانزم 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 میکانزم کے ذریعے خود بخود اپ ڈیٹ ہوتا ہے۔
iOS پیمانہ 11 سائز پر مشتمل ہے: .extraSmall (5 pt) سے .accessibilityExtraExtraExtraLarge (.body کے لیے 77 pt) تک۔ .body کے لیے پیمائش کا عنصر بنیادی قدر کے نسبت 0.85 (XS) سے 1.71 (XXXL) تک ہوتا ہے۔ @ScaledMetric بالکل اسی پیمانے کا استعمال کرتا ہے، لہذا 12 pt کی padding قدر زیادہ سے زیادہ رسائی سائز پر ~20 pt ہو سکتی ہے۔
| مواد کے سائز کا زمرہ | عنصر (body) | مثال @ScaledMetric(12) |
|---|---|---|
| extraSmall | 0.85 | ~10 pt |
| small | 0.93 | ~11 pt |
| medium (default) | 1.00 | 12 pt |
| large | 1.07 | ~13 pt |
| extraLarge | 1.15 | ~14 pt |
| extraExtraLarge | 1.28 | ~15 pt |
| accessibilityExtraLarge | 1.47 | ~18 pt |
| accessibilityXXXL | 1.71 | ~20 pt |
relativeTo کا انتخاب: باڈی ٹیکسٹ سے متعلق قدروں (فہرستوں میں padding, spacing) کے لیے .body، بڑے عناصر (iconSize, imageSize) کے لیے .title، چھوٹے عناصر (بیج سائز) کے لیے .caption استعمال کریں۔ یہ یقینی بناتا ہے کہ عناصر اردگرد کے متن کے ساتھ ہم آہنگی میں پیمائش ہوں۔
Dynamic Type ایک iOS خصوصیت ہے جو صارفین کو ترتیبات → ڈسپلے اور چمک → متن کا سائز میں سسٹم فونٹ سائز ایڈجسٹ کرنے دیتی ہے۔ تبدیلی تمام ایپس پر عالمی طور پر لاگو ہوتی ہے۔ @ScaledMetric اس تبدیلی پر خود بخود رد عمل ظاہر کرتا ہے: SwiftUI UIContentSizeCategory تبدیل ہونے پر تمام @ScaledMetric متغیرات کو اپ ڈیٹ کرتا ہے۔
اہم: @ScaledMetric صرف عددی قدروں کو پیمائش کرتا ہے، فونٹس کو براہ راست منظم نہیں کرتا۔ فونٹس کے لیے، متن کے اسٹائل (.body, .title, .headline) کے ساتھ .font() استعمال کریں — SwiftUI خود بخود فونٹ کو پیمائش کرتا ہے۔ @ScaledMetric padding, spacing اور عناصر کے سائز کے لیے فونٹ پیمائش کی تکمیل کرتا ہے۔
Canvas Preview Dynamic Type کو سپورٹ کرتا ہے: Canvas ٹول بار میں مختلف فونٹ سائز پر انٹرفیس جانچنے کے لیے ایک متن کے سائز کا سلائیڈر (A–A) ہے۔ اسے @ScaledMetric کے ساتھ استعمال کریں تاکہ یہ یقینی بنایا جا سکے کہ فاصلے اور سائز درست طریقے سے پیمائش ہو رہے ہیں۔
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 تک۔ یہ یقینی بناتا ہے کہ کارڈ کسی بھی فونٹ سائز پر بصری طور پر متوازن رہے۔
مثال: Dynamic Type معاون آئیکن. Image(systemName:) آئیکن سائز ڈیفالٹ طور پر Dynamic Type کے مطابق پیمائش نہیں ہوتے۔ @ScaledMetric موجودہ پیمائش عنصر کی بنیاد پر imageScale یا فریم سائز تبدیل کرکے اس مسئلے کو حل کرتا ہے۔
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 یقینی بناتا ہے کہ گول بیج بڑے متن کے ساتھ نظر آتا رہے۔
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 دونوں property wrappers ہیں جو تبدیلیوں کو ٹریک کرتے ہیں، لیکن مختلف اپ ڈیٹ ذرائع کے ساتھ۔ @State پروگرامی تبدیلی ($stateBinding کے ذریعے) پر قدر اپ ڈیٹ کرتا ہے۔ @ScaledMetric سسٹم Dynamic Type تبدیل ہونے پر خود بخود قدر اپ ڈیٹ کرتا ہے، لیکن کوڈ سے براہ راست قدر تبدیل کرنے کی اجازت نہیں دیتا۔
کلیدی فرق: @ScaledMetric ڈویلپر کے لیے صرف پڑھنے کے قابل اور سسٹم کے لیے صرف لکھنے کے قابل ہے۔ آپ setter کے ذریعے scaledValue تبدیل نہیں کر سکتے — یہ SwiftUI کے ذریعے بنیادی قدر اور موجودہ Dynamic Type کی بنیاد پر شمار کیا جاتا ہے۔ @State، دوسری طرف، مکمل طور پر ڈویلپر کے کنٹرول میں ہے۔ اگر آپ کو ایک ایسی قدر کی ضرورت ہے جو Dynamic Type کے مطابق پیمائش بھی ہو اور پروگرامی طور پر بھی تبدیل ہو — @ScaledMetric کو @State کے ساتھ ملائیں یا ایک شمار شدہ پراپرٹی استعمال کریں۔
| خصوصیت | @ScaledMetric | @State |
|---|---|---|
| اپ ڈیٹ ماخذ | Dynamic Type (سسٹم) | پروگرامی (ڈویلپر) |
| قسم قدر | CGFloat, Int, Double | کوئی بھی |
| کوڈ سے تبدیلی | اجازت نہیں | binding کے ذریعے اجازت ہے |
| View دوبارہ ڈرائنگ | Dynamic Type تبدیلی پر | قدر تبدیلی پر |
| iOS ورژن | iOS 14+ | iOS 13+ |
مشترکہ نمونہ: اگر آپ کو Dynamic Type کے مطابق پیمائش کرتے ہوئے پروگرامی طور پر padding تبدیل کرنے کی ضرورت ہے (مثال کے طور پر، ٹیپ اینیمیشن)، بنیاد پیمائش شدہ قدر کے لیے @ScaledMetric اور اینیمیشن ضارب کے لیے @State بنائیں۔ حتمی قدر = scaledValue × animationMultiplier۔
غلطی 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 کے ساتھ ملانا۔
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 اعداد کو پیمائش کرنے کے لیے ایک سرکاری SwiftUI property wrapper ہے۔ @ScaledFont ایک معیاری API کے طور پر موجود نہیں ہے — یہ کمیونٹی کے ذریعے نافذ کردہ ایک حسب ضرورت wrapper ہے۔ فونٹس کے لیے، ہمیشہ متن کے اسٹائل (.body, .title) کے ساتھ بلٹ ان .font() استعمال کریں، اور padding, spacing اور سائز کے لیے @ScaledMetric استعمال کریں۔
@ScaledMetric iOS 14+, watchOS 7+, tvOS 14+ اور macOS 11+ پر دستیاب ہے۔ watchOS پر، Dynamic Type ایک چھوٹی حد تک محدود ہے — .extraSmall سے .extraLarge تک کے سائز رسائی کے سائز کے بغیر دستیاب ہیں۔ tvOS پر، Dynamic Type دستیاب نہیں ہے — @ScaledMetric ہمیشہ بنیادی قدر لوٹاتا ہے۔
ہاں، @ScaledMetric کو جانچنے کے لیے @ScaledMetric کے ساتھ ایک View بنائیں اور .environment(\.sizeCategory, .extraExtraLarge) کے ذریعے ماحول .sizeCategory قدر پاس کریں۔ پھر GeometryReader یا SwiftUI Inspector کے ذریعے عنصر کا سائز حاصل کریں۔ متبادل طور پر، علیحدہ ماڈیول میں UIFontMetrics کے ذریعے پیمائش کی منطق کو جانچیں۔
.dynamicTypeSize ایک View موڈیفائر ہے جو ایک درجہ بندی کے لیے زیادہ سے زیادہ Dynamic Type کو محدود کرتا ہے (مثلاً، .dynamicTypeSize(...large))۔ @ScaledMetric اس حد کا احترام کرتا ہے: اگر .dynamicTypeSize سیٹ کیا گیا ہے، تو پیمائش شدہ قدر متعلقہ سائز سے تجاوز نہیں کرے گی۔ عین مطابق کنٹرول کے لیے دونوں APIs کو ملائیں۔
یقینی بنائیں کہ View @ScaledMetric کو اندرونی طور پر استعمال کرتی ہے (ViewModel میں نہیں)۔ چیک کریں کہ View Dynamic Type کو سبسکرائب کرتی ہے: @ScaledMetric خود بخود body ریفریش کو متحرک کرتا ہے، لیکن اگر View .equatable() یا .id() استعمال کرتی ہے، تو میکانزم ٹوٹ سکتا ہے۔ فال بیک کے طور پر @Environment(\.sizeCategory) استعمال کریں۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں