Mac विंडो के लेबल और स्थिति वाले कॉलम को स्थिर रखते हुए विवरण को फैलने देने के लिए, बाहरी कॉलम की स्पष्ट चौड़ाई तय करें और विवरण को लचीला फ़्रेम दें। जब साथ वाले व्यू जगह के लिए प्रतिस्पर्धा करें, तो लेआउट प्राथमिकता का उपयोग करें और केवल उन्हीं दिशाओं में आदर्श आकार बनाए रखें जहाँ इसकी ज़रूरत हो।

यह ट्यूटोरियल एक छोटी, आकार बदल सकने वाली विंडो बनाता है, जिसमें उदाहरण के लिए आइटम लेबल और विवरण हैं। काम यह है कि कॉलम संरेखित रहें और विंडो के संकरी होने पर लंबे विवरण अगली पंक्तियों में लिपट सकें। सब कुछ उदाहरण ऐप का हिस्सा है; लेआउट में सामान्य SwiftUI व्यू इस्तेमाल होते हैं।

हर सबव्यू के लिए आकार नियंत्रित करने का कौन-सा तरीका चुनें?

SwiftUI लेआउट की शुरुआत पैरेंट द्वारा आकार प्रस्तावित करने से होती है। हर चाइल्ड अपने पसंदीदा आकार के साथ जवाब देता है और कंटेनर उन नतीजों को व्यवस्थित करता है। शुरुआत के लिए यह तय करना उपयोगी है कि हर चाइल्ड के कौन-से आयाम बदल सकते हैं। Apple इस प्रस्ताव और जवाब की प्रक्रिया को SwiftUI में लेआउट की मार्गदर्शिका में समझाता है।

इस विंडो के लिए तीन भूमिकाएँ तय करें: चुनी हुई चौड़ाई वाला लेबल कॉलम, चौड़ाई में बदलाव को समेटने वाला विवरण कॉलम और चुनी हुई चौड़ाई वाला स्थिति कॉलम। इस संख्यात्मक स्थिर चौड़ाई को व्यू के आदर्श आकार से अलग समझें: दोनों अलग-अलग आवश्यकताएँ दर्शाते हैं।

आवश्यकता नियंत्रण व्यावहारिक परिणाम
कॉलम की एक खास चौड़ाई तय करना .frame(width: 96) परिणामी फ़्रेम की चौड़ाई उतनी ही होती है।
विवरण को उपलब्ध चौड़ाई समेटने देना .frame(minWidth: 160, maxWidth: .infinity, alignment: .leading) फ़्रेम न्यूनतम सीमा के अधीन प्रस्तावित चौड़ाई स्वीकार करता है।
चुनी हुई दिशाओं में सामग्री का आदर्श आकार बनाए रखना .fixedSize(horizontal: false, vertical: true) चौड़ाई लेआउट के अनुसार बदल सकती है, जबकि ऊँचाई आदर्श आकार बनाए रखती है।
जगह बाँटते समय किसी एक साथ वाले व्यू को प्राथमिकता देना .layoutPriority(1) पैरेंट उस चाइल्ड को कम प्राथमिकता वाले चाइल्ड पर वरीयता देता है।

Apple संख्यात्मक आयामों का वर्णन स्थिर फ़्रेम मॉडिफ़ायर में, न्यूनतम और अधिकतम सीमाओं का लचीले फ़्रेम मॉडिफ़ायर में, दिशा के अनुसार आदर्श आकार का fixedSize(horizontal:vertical:) में और साथ वाले व्यू को वरीयता देने का layoutPriority(_:) में करता है।

अनंत अधिकतम का मतलब है कि प्रस्तावित आकार के भीतर फैलने की अनुमति; इसका मतलब अनंत चौड़ाई वाली विंडो का अनुरोध नहीं है। न्यूनतम और अधिकतम दोनों सीमाएँ देने पर फ़्रेम प्रस्तावित आयाम अपनाता है, जिसे इन सीमाओं के भीतर रखा जाता है। alignment पैरामीटर उस फ़्रेम के भीतर चाइल्ड की स्थिति तय करता है। ये बातें तब मायने रखती हैं जब टेक्स्ट खुद अपने कॉलम को दी गई जगह से संकरा हो। Apple का लचीले फ़्रेम का दस्तावेज़

आकार बदल सकने वाला पूरा macOS उदाहरण बनाएँ

Xcode में SwiftUI का उपयोग करके macOS ऐप प्रोजेक्ट बनाएँ और उसका डिप्लॉयमेंट लक्ष्य macOS 13 या उसके बाद का संस्करण रखें। बनाई गई app और content-view घोषणाओं की जगह यह एक फ़ाइल रखें और ऐप का केवल एक एंट्री पॉइंट रहने दें। इस उदाहरण में macOS 13 का विंडो आकार बदलने का नियंत्रण इस्तेमाल होता है। Apple का WindowResizability दस्तावेज़

यह पूरा ऐप उदाहरण है। इसमें नमूना स्ट्रिंग और छोटे तथा लंबे विवरणों के बीच स्विच करने का टॉगल शामिल है। शोध परिवेश में Swift टूलचेन उपलब्ध न होने के कारण SwiftUI ऐप को संकलित नहीं किया जा सका; इसे मौजूदा प्रोजेक्ट में जोड़ने से पहले Xcode में इसका व्यवहार देखें।

import SwiftUI

@main
struct ColumnAllocationApp: App {
    var body: some Scene {
        WindowGroup {
            AllocationView()
                .frame(minWidth: 420, minHeight: 260)
        }
        .windowResizability(.contentMinSize)
    }
}

struct AllocationView: View {
    @State private var showLongDescriptions = true

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            Text("Item overview")
                .font(.title2)

            Toggle(
                "Show longer descriptions",
                isOn: $showLongDescriptions
            )

            ScrollView {
                VStack(alignment: .leading, spacing: 16) {
                    AllocationRow(
                        label: "Item A",
                        summary: showLongDescriptions
                            ? "A blue folder with several sample notes and a longer descriptive label."
                            : "Blue folder",
                        status: "Ready"
                    )

                    AllocationRow(
                        label: "Item B",
                        summary: showLongDescriptions
                            ? "A green notebook containing a short list of synthetic example entries."
                            : "Green notebook",
                        status: "Draft"
                    )
                }
                .frame(maxWidth: .infinity, alignment: .leading)
            }
        }
        .padding(16)
    }
}

struct AllocationRow: View {
    let label: String
    let summary: String
    let status: String

    var body: some View {
        HStack(alignment: .top, spacing: 12) {
            Text(label)
                .frame(width: 96, alignment: .leading)

            Text(summary)
                .fixedSize(horizontal: false, vertical: true)
                .frame(
                    minWidth: 160,
                    maxWidth: .infinity,
                    alignment: .leading
                )

            Text(status)
                .fixedSize(horizontal: true, vertical: false)
                .frame(width: 72, alignment: .trailing)
        }
    }
}

विवरण ही एकमात्र ऐसा कॉलम है जिसकी क्षैतिज दिशा में लचीलापन है। इसका fixedSize कॉल क्षैतिज आकार को प्रतिक्रिया के लिए खुला रखता है और लिपटे हुए टेक्स्ट के लिए ज़रूरी ऊर्ध्वाधर जगह बनाए रखता है। फिर इसका लचीला फ़्रेम आवंटित कॉलम को भरता है। स्थिति वाले टेक्स्ट की आदर्श चौड़ाई एक अलग 72-पॉइंट फ़्रेम के भीतर बनी रहती है। Apple चेतावनी देता है कि आदर्श आकार वाली सामग्री अपने पैरेंट की सीमाओं से बाहर जा सकती है, इसलिए स्थिति के लिए यह तरीका दिए गए छोटे मानों Ready और Draft पर निर्भर करता है। Apple का fixedSize दस्तावेज़

पंक्तियों की ऊँचाई तय नहीं है। यह जानबूझकर किया गया है: संकरे विवरणों को ज़्यादा पंक्तियों की ज़रूरत पड़ सकती है। जब पंक्तियों की कुल ऊँचाई उपलब्ध जगह से बढ़ जाए, तो स्क्रोल व्यू उन तक पहुँचने का तरीका देता है। शुरुआती व्यवस्था को एकसमान दिखाने के लिए पंक्ति की ऊँचाई पर कड़ी सीमा लगाने से बचें।

विंडो .contentMinSize का उपयोग करती है, जो न्यूनतम आयाम सामग्री से निकालता है और अधिकतम आकार की कोई सीमा नहीं लगाता। यहाँ रूट की 420-पॉइंट न्यूनतम चौड़ाई उदाहरण के लिए एक व्यावहारिक निचली सीमा तय करती है। यह नियंत्रण ऐप के सीन द्वारा बनाई गई विंडो पर लागू होता है। Apple का contentMinSize दस्तावेज़

some View लौटाने वाली घोषणाएँ Swift के opaque result type का उपयोग करती हैं: उनका ठोस प्रकार छिपा रहता है, जबकि View के अनुरूप होना उपलब्ध रहता है। आप नेस्टेड रिटर्न प्रकारों को लिखे बिना मॉडिफ़ायर चेन बदल सकते हैं। The Swift Programming Language: Opaque and Boxed Protocol Types

प्राथमिकताएँ बदलने से पहले चौड़ाई का बजट निकालें

चौड़ाई का बजट लेआउट की सीमाएँ स्पष्ट करता है। इस उदाहरण में विंडो की सामग्री की चौड़ाई में से क्षैतिज पैडिंग, दोनों अंतराल और दो स्थिर कॉलम घटाएँ। बची हुई जगह विवरण को मिलती है। ये डिज़ाइन के उदाहरणात्मक आयाम हैं, नेटिव कंट्रोल के माप नहीं।

विवरण की चौड़ाई
    = सामग्री की चौड़ाई - क्षैतिज पैडिंग - अंतराल - स्थिर कॉलम
    = सामग्री की चौड़ाई - (2 × 16) - (2 × 12) - 96 - 72
    = सामग्री की चौड़ाई - 224

640 पॉइंट पर: विवरण के लिए 416 पॉइंट बचते हैं।
420 पॉइंट पर: विवरण के लिए 196 पॉइंट बचते हैं।

पंक्ति का न्यूनतम बजट:
    32 + 24 + 96 + 160 + 72 = 384 पॉइंट।

इस गणना को एक नियतात्मक स्थानीय गणना से जाँचा गया। यह उस पंक्ति का वर्णन करती है जब उसे बताई गई पैडिंग घटाकर सामग्री की चौड़ाई मिलती है; इसमें विंडो की सजावट शामिल नहीं है। चुनी गई 420-पॉइंट न्यूनतम विंडो चौड़ाई पंक्ति की गणना की गई 384-पॉइंट न्यूनतम चौड़ाई से अधिक जगह देती है। अगर आसपास का कंटेनर इनसेट जोड़ता है, तो उन्हें भी बजट में शामिल करें।

यह गणना एक असंभव अनुरोध की पहचान भी करती है। कुल न्यूनतम बजट से कम जगह होने पर तीनों कॉलम एक साथ अपनी चौड़ाई और अंतराल बनाए नहीं रख सकते। विंडो की न्यूनतम चौड़ाई बढ़ाएँ, न्यूनतम आयाम घटाएँ या दूसरी व्यवस्था चुनें। प्राथमिकता बढ़ाने से अतिरिक्त जगह नहीं बनती।

लेआउट प्राथमिकता कब मदद करती है?

जब दो साथ वाले व्यू छोटे हो सकते हों और आप चाहते हों कि उनमें से एक ज़्यादा जगह बनाए रखे, तब प्राथमिकता उपयोगी होती है। उदाहरण के लिए, कोई वर्णनात्मक शीर्षक दूसरे दर्जे की टिप्पणी से अधिक वरीयता पाने योग्य हो सकता है। पैरेंट के जगह बाँटने के निर्णय में शामिल चाइल्ड पर .layoutPriority(1) लगाएँ। Apple के अनुसार, अधिक प्राथमिकता वाले व्यू बाद में सिकुड़ते हैं और पहले फैलते हैं; साथ ही कम प्राथमिकता वाले चाइल्ड की न्यूनतम आवश्यकताओं के लिए जगह रखी जाती है। Apple का layoutPriority दस्तावेज़

पूरे उदाहरण को प्राथमिकता मॉडिफ़ायर की ज़रूरत नहीं है: इसकी जगह बाँटने की नीति पहले से ही दो स्थिर कॉलम और एक लचीले कॉलम के ज़रिए व्यक्त होती है। प्राथमिकता का मान अनुपातिक भार भी नहीं होता। 2 और 1 की प्राथमिकताएँ देने से चौड़ाई का अनुपात दो-से-एक तय नहीं होता; दस्तावेज़ के अनुसार इसका उद्देश्य जगह बाँटते समय वरीयता देना है। Apple का layoutPriority दस्तावेज़

विवरण और स्थिति के बीच क्षैतिज Spacer जोड़ने से बचें, जब तक कि आप अलग से लचीला अंतराल न चाहते हों। स्पेसर अपनी स्टैक की मुख्य दिशा में फैलता है और साथ वाले व्यू को एक-दूसरे से दूर धकेलता है। चूँकि विवरण का फ़्रेम पहले से ही चौड़ाई के बदलाव को समेटता है, इसलिए यहाँ इस अतिरिक्त हिस्से की ज़रूरत नहीं है। Apple का Spacer दस्तावेज़

टेक्स्ट के फिट न होने पर क्या होना चाहिए?

हर टेक्स्ट फ़ील्ड के लिए अलग से तय करें कि वह अगली पंक्तियों में लिपटे, कट जाए या उसके लिए दूसरी व्यवस्था चाहिए। उदाहरण के विवरण बिना पंक्ति सीमा के लिपट सकते हैं। .lineLimit(1) लगाने से हर प्रभावित टेक्स्ट तत्व एक पंक्ति तक सीमित हो जाएगा और आवश्यकता बदल जाएगी। nil की पंक्ति सीमा यह रोक हटाती है, लेकिन आसपास के फ़्रेम की सीमाएँ बनी रहती हैं। Apple का lineLimit दस्तावेज़

लंबे स्थिति मानों के लिए 72-पॉइंट कॉलम पर फिर से विचार करें। अगर टेक्स्ट लिपटना स्वीकार्य हो, तो क्षैतिज दिशा में आदर्श आकार बनाए रखना हटाएँ, कॉलम की चौड़ाई बढ़ाएँ या स्थिति को विवरण के नीचे रखें। .fixedSize(horizontal: true, vertical: false) को बनाए रखते हुए उसके आसपास का फ़्रेम संकरा करने पर टेक्स्ट उस फ़्रेम से बाहर जा सकता है। Apple का fixedSize दस्तावेज़

अगर छोटी विंडो में सामग्री की व्यवस्था बदलनी चाहिए, तो macOS 13 और उसके बाद के संस्करण ViewThatFits उपलब्ध कराते हैं। पहले क्षैतिज व्यवस्था और फिर स्टैक की हुई व्यवस्था दें। यह चुनी हुई दिशाओं में आदर्श आकार फिट होने वाला पहला चाइल्ड चुनता है, इसलिए अगर निर्णायक बात चौड़ाई है, तो ViewThatFits(in: .horizontal) के साथ क्षैतिज जगह का आकलन करें। अंतिम विकल्प आपकी समर्थित न्यूनतम चौड़ाई पर उपयोग करने योग्य होना चाहिए। Apple का ViewThatFits दस्तावेज़

इसे वैकल्पिक लेआउट नीति मानें। मौजूदा उदाहरण जानबूझकर कॉलम बनाए रखता है और विंडो की न्यूनतम चौड़ाई तय करता है। जब क्षैतिज व्यवस्था बनाए रखने से ज़्यादा ज़रूरी संकरी विंडो की अनुमति देना हो, तब स्टैक की हुई वैकल्पिक व्यवस्था का उपयोग करें।

एम्बेड किए गए AppKit और TextKit व्यू से तरीका कैसे बदलता है?

अगर बाद में विवरण AppKit टेक्स्ट कंपोनेंट बन जाता है, तो उस व्यू को जोड़ने के लिए NSViewRepresentable का उपयोग करें। Apple स्पष्ट रूप से कहता है कि SwiftUI प्रस्तुत किए गए व्यू के frame और bounds को नियंत्रित करता है; अपने कोड से इन गुणों को सीधे बदलना SwiftUI लेआउट के साथ टकराता है। सामग्री को representable के जीवनचक्र के ज़रिए कॉन्फ़िगर करें और बाहरी आकार SwiftUI में व्यक्त करें। Apple का NSViewRepresentable दस्तावेज़

macOS 13 और उसके बाद के संस्करणों में, representable का sizeThatFits(_:nsView:context:) मेथड किसी प्रस्तावित आकार के लिए पसंदीदा आकार लौटा सकता है। एक लेआउट पास में इसे अलग-अलग प्रस्तावों के साथ कई बार बुलाया जा सकता है। nil लौटाने पर डिफ़ॉल्ट आकार निर्धारण एल्गोरिदम का अनुरोध होता है। लपेटने वाले कंपोनेंट का माप हमेशा बिना लिपटे टेक्स्ट की चौड़ाई लौटाने के बजाय प्रस्तावित चौड़ाई को ध्यान में रखे। Apple का representable आकार निर्धारण दस्तावेज़

अनिर्दिष्ट आयामों को शून्य से अलग रखें: SwiftUI आदर्श आकार पूछने के लिए अनिर्दिष्ट प्रस्ताव का उपयोग करता है, जबकि शून्य से न्यूनतम आकार जाँचा जा सकता है। कस्टम मापन रूटीन को इन स्थितियों को सोच-समझकर संभालना चाहिए। Apple का ProposedViewSize दस्तावेज़

AppKit लेआउट के भीतर, कंप्रेशन रेज़िस्टेंस नियंत्रित करता है कि कोई NSView अपने अंतर्निहित आकार से छोटा होने का कितना प्रतिरोध करता है। अगर लिपटा हुआ कंपोनेंट संकुचन का प्रतिरोध करता है, तो उसके SwiftUI आकार निर्धारण व्यवहार के साथ इस सेटिंग को भी देखें। Apple का setContentCompressionResistancePriority दस्तावेज़

TextKit 2 का उपयोग करने वाले NSTextView के लिए आधुनिक textLayoutManager पथ अपनाएँ। Apple का मौजूदा TextKit अवलोकन इसे पुराने layoutManager से अलग बताता है, और माइग्रेशन मार्गदर्शन समझाता है कि पुराने गुण को एक्सेस करने से उस इंस्टेंस के लिए TextKit 1 पर एकतरफ़ा संगतता स्विच शुरू हो सकता है। साथ वाले कॉलम को जगह देने के लिए टेक्स्ट इंजन बदलना ज़रूरी नहीं है। Apple का TextKit अवलोकन, TextKit और टेक्स्ट व्यू में नया क्या है

विंडो की सीमाओं पर नतीजा जाँचें

उदाहरण चलाएँ और इस तरीके को बड़े इंटरफ़ेस पर लागू करने से पहले इन स्थितियों को देखें:

  1. विंडो चौड़ी करें: विवरण कॉलम फैलना चाहिए, जबकि लेबल और स्थिति वाले फ़्रेम अपनी चौड़ाई बनाए रखें।
  2. विंडो को समर्थित न्यूनतम तक संकरा करें: लंबे विवरण लिपटने चाहिए और पंक्तियों की ऊँचाई बढ़नी चाहिए।
  3. Show longer descriptions को बंद और चालू करें: छोटे विवरण उन्हीं कॉलम में संरेखित रहने चाहिए।
  4. लंबा उदाहरणात्मक स्थिति मान रखें: तय करें कि उस फ़ील्ड को चौड़ा करना है, लपेटना है या दूसरी जगह रखना है।
  5. उपलब्ध ऊँचाई घटाएँ: पुष्टि करें कि सभी पंक्तियों तक पहुँचा जा सकता है।

यह देखने के लिए कि जगह किस स्तर को मिल रही है, विवरण के लचीले फ़्रेम के ठीक पहले और बाद में अस्थायी रूप से बॉर्डर जोड़ें। अंदर वाला बॉर्डर टेक्स्ट की सीमाएँ दिखाता है; बाहर वाला बॉर्डर आवंटित कॉलम दिखाता है। Apple स्टैक के आकार और पैडिंग की जाँच के व्यावहारिक तरीके के रूप में रंगीन बॉर्डर सुझाता है। SwiftUI में लेआउट की मार्गदर्शिका

इंटरफ़ेस के बढ़ने पर आकार निर्धारण नीति स्पष्ट रखें: जहाँ संरेखण के लिए ज़रूरी हो वहाँ चौड़ाई तय करें, बदलती सामग्री को एक निर्धारित लचीला क्षेत्र दें और न्यूनतम चौड़ाई पर हर फ़ील्ड का व्यवहार तय करें। इस नीति और चौड़ाई के बजट के साथ, आप यह अनुमान लगाए बिना लेबल बदल सकते हैं या सामग्री जोड़ सकते हैं कि किस मॉडिफ़ायर को अधिक प्राथमिकता देनी चाहिए।

स्रोत