SwiftUI में स्क्रीन की चौड़ाई भरने के लिए VStack बनाएं


119

इस कोड को दिया:

import SwiftUI

struct ContentView : View {
    var body: some View {
        VStack(alignment: .leading) {
            Text("Title")
                .font(.title)

            Text("Content")
                .lineLimit(nil)
                .font(.body)

            Spacer()
        }
        .background(Color.red)
    }
}

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

यह इस अंतर में परिणत होता है:

पूर्वावलोकन

VStackयदि लेबल / पाठ घटकों को पूरी चौड़ाई की आवश्यकता नहीं है, तो भी मैं स्क्रीन की चौड़ाई कैसे भर सकता हूं ?

एक चाल मैंने पाया है कि संरचना में एक खाली सम्मिलित HStackकरना है जैसे:

VStack(alignment: .leading) {
    HStack {
        Spacer()
    }
    Text("Title")
        .font(.title)

    Text("Content")
        .lineLimit(nil)
        .font(.body)

    Spacer()
}

जो वांछित डिज़ाइन देता है:

वांछित उत्पादन

क्या कोई बेहतर तरीका है?


1
मेरे उत्तरदाता को देखें जो समान परिणाम के लिए 5 वैकल्पिक तरीके दिखाता है।
इमानो पेटिट

जवाबों:


196

निम्न विकल्पों के साथ .frame संशोधक का उपयोग करने का प्रयास करें:

.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
struct ContentView: View {
    var body: some View {
        VStack(alignment: .leading) {
            Text("Hello World").font(.title)
            Text("Another").font(.body)
            Spacer()
        }.frame(minWidth: 0,
                maxWidth: .infinity,
                minHeight: 0,
                maxHeight: .infinity,
                alignment: .topLeading
        ).background(Color.red)
    }
}

इसे एक लचीली फ्रेम ( प्रलेखन देखें ) के रूप में वर्णित किया गया है , जो पूरी स्क्रीन को भरने के लिए खिंचाव करेगा, और जब इसमें अतिरिक्त स्थान होगा तो यह इसके अंदर अपनी सामग्री को केंद्र में रखेगा।


Subviews छोड़ दिया करने के लिए संरेखित नहीं करते हैं ( .leading)। पूर्ण चौड़ाई लेता है अगर पहले रखा.background(Color.red)
ielyamani

साथ ही बाईं ओर संरेखित करने के लिए कोड जोड़ा गया। अब बिल्कुल मेल खाना चाहिए
svarrall

12
ये गलत है। .backgound(Color.red)फ्रेम के दृश्य की पृष्ठभूमि, लेकिन नहीं की पृष्ठभूमि है VStackफ्रेम को ध्यान में रखते है। (इसका कारण डब्ल्यूडब्ल्यूडीसी वीडियो: पी) में बताया गया है। यदि आप डालते हैं .background(Color.green)तो .frameआप देखेंगे कि VStackअभी भी एक चौड़ाई है जो इसकी सामग्री को फिट करती है जबकि फ्रेम में एक लाल पृष्ठभूमि है ... जब आप डालते हैं .frame(...), तो यह संपादन नहीं कर रहा है VStack, यह वास्तव में एक और दृश्य बना रहा है।
जेक

2
@ जेक एक आपदा के लिए एक नुस्खा की तरह लगता है
सुदरा

1
एक सवाल है: संरेखण का उपयोग क्यों करें: .Leading के बाद से हम VStack (संरेखण। भरण) कर रहे हैं? साझा करने के लिए धन्यवाद
UIChris

36

एक वैकल्पिक स्टैकिंग व्यवस्था जो काम करती है और शायद थोड़ी अधिक सहज है, निम्नलिखित है:

struct ContentView: View {
    var body: some View {
        HStack() {
            VStack(alignment: .leading) {
                Text("Hello World")
                    .font(.title)
                Text("Another")
                    .font(.body)
                Spacer()
            }
            Spacer()
        }.background(Color.red)
    }
}

Spacer()यदि आवश्यक हो तो सामग्री को आसानी से हटाकर फिर से तैनात किया जा सकता है।

स्थिति बदलने के लिए Spacers जोड़ना / निकालना


4
अच्छा विकल्प alternative लाइक किया गया जिफ़
इलियामनी

1
मुझे ओपी के प्रश्न के साथ यह और अधिक सहज और अधिक संरेखित लगता है, जो मुझे इस बारे में होना था कि स्टैक तत्व अपने कंटेनर को कैसे भरें, बजाय तत्व के चारों ओर एक कंटेनर को कैसे रखा जाए।
ब्रोत्सयडॉटकॉम

1
मुझे यह सबसे अच्छा जवाब लगता है जो SwiftUI
krummens

1
इस तरह के एक सामान्य लेआउट के लिए निश्चित रूप से यहाँ पर सबसे अधिक स्विफ्टयूआई-वाई उत्तर है।
dead_can_dance

30

एक बेहतर रास्ता है!

इसे VStackभरने की चौड़ाई बनाने के लिए आप इसका उपयोग कर सकते हैं GeometryReaderऔर फ्रेम सेट कर सकते हैं । ( .relativeWidth(1.0)काम करना चाहिए, लेकिन जाहिर है अभी नहीं)

struct ContentView : View {
    var body: some View {
        GeometryReader { geometry in
            VStack {
                Text("test")
            }
                .frame(width: geometry.size.width,
                       height: nil,
                       alignment: .topLeading)
        }
    }
}

VStackवास्तविक स्क्रीन की चौड़ाई बनाने के लिए आप UIScreen.main.bounds.widthएक का उपयोग करने के बजाय फ्रेम सेट करते समय उपयोग कर सकते हैं GeometryReader, लेकिन मुझे लगता है कि आप मूल दृश्य की चौड़ाई चाहते थे।

इसके अलावा, इस तरह से अपने में रिक्ति नहीं जोड़ने के अतिरिक्त लाभ है VStackजो हो सकता है (यदि आप रिक्ति है) अगर आप एक जोड़ा HStackएक साथ Spacer()करने के लिए यह की सामग्री के रूप में VStack

अद्यतन - वहाँ एक बेहतर रास्ता नहीं है!

स्वीकृत उत्तर की जाँच करने के बाद, मैंने महसूस किया कि स्वीकृत उत्तर वास्तव में काम नहीं करता है! यह पहली नज़र में काम करता प्रतीत होता है, लेकिन यदि आप VStackएक हरे रंग की पृष्ठभूमि के लिए अपडेट करते हैं , तो आप देखेंगे कि VStackअभी भी वही चौड़ाई है।

struct ContentView : View {
    var body: some View {
        NavigationView {
            VStack(alignment: .leading) {
                Text("Hello World")
                    .font(.title)
                Text("Another")
                    .font(.body)
                Spacer()
                }
                .background(Color.green)
                .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
                .background(Color.red)
        }
    }
}

ऐसा इसलिए है क्योंकि .frame(...)वास्तव में पदानुक्रम को देखने के लिए एक और दृश्य जोड़ रहा है और वह दृश्य स्क्रीन को भरना समाप्त कर देता है। हालाँकि, VStackअभी भी नहीं है।

यह समस्या मेरे उत्तर में भी समान प्रतीत होती है और इसे ऊपर की तरह (अलग-अलग पृष्ठभूमि के रंग डालते हुए और बाद में) एक ही दृष्टिकोण का उपयोग करके जांच की जा सकती है .frame(...)। वास्तव में चौड़ी करने के लिए प्रकट होने वाला एकमात्र तरीका स्पेसर्स VStackका उपयोग करना है:

struct ContentView : View {
    var body: some View {
        VStack(alignment: .leading) {
            HStack{
                Text("Title")
                    .font(.title)
                Spacer()
            }
            Text("Content")
                .lineLimit(nil)
                .font(.body)
            Spacer()
        }
            .background(Color.green)
    }
}

कोशिश की थी relativeWidth, काम नहीं किया। किसी तरह GeometryReaderकाम करता है अगर .frameपहले रखा गया है.background(Color.red)
ielyamani

GeometryReaderजब मैं "मॉडिफ़ायर जोड़ें" के बाद दिखाई गई सूची में मैं नहीं देख सकता Show SwiftUI Inspector, या यूआई के भीतर कोई और। तुम कैसे की खोज की थी GeometryReader?
चला गया

1
@ गॉन - स्टैक ओवरफ्लो :)
जेक

20

स्विफ्ट 5.2 और आईओएस 13.4 के साथ, अपनी आवश्यकताओं के अनुसार, आप अपने VStackशीर्ष अग्रणी बाधाओं और एक पूर्ण आकार के फ्रेम के साथ संरेखित करने के लिए निम्न उदाहरणों में से एक का उपयोग कर सकते हैं ।

ध्यान दें कि एक ही प्रदर्शन में सभी परिणाम नीचे दिए कोड स्निपेट, लेकिन के प्रभावी फ्रेम गारंटी नहीं है VStackऔर न ही की संख्या Viewतत्वों है कि जब तक दृश्य पदानुक्रम डिबगिंग प्रकट हो सकता है।


1. frame(minWidth:idealWidth:maxWidth:minHeight:idealHeight:maxHeight:alignment:)विधि का उपयोग करना

सबसे सरल तरीका यह है कि VStackअधिकतम चौड़ाई और ऊंचाई के साथ अपने फ्रेम को सेट करें और इसमें आवश्यक संरेखण भी पास करें frame(minWidth:idealWidth:maxWidth:minHeight:idealHeight:maxHeight:alignment:):

struct ContentView: View {

    var body: some View {
        VStack(alignment: .leading) {
            Text("Title")
                .font(.title)
            Text("Content")
                .font(.body)
        }
        .frame(
            maxWidth: .infinity,
            maxHeight: .infinity,
            alignment: .topLeading
        )
        .background(Color.red)
    }

}

एक विकल्प के रूप में, यदि आपके Views के लिए विशिष्ट संरेखण के साथ अधिकतम फ्रेम सेट करना आपके कोड बेस में एक सामान्य पैटर्न है, तो आप इस पर एक एक्सटेंशन विधि बना सकते हैं View:

extension View {

    func fullSize(alignment: Alignment = .center) -> some View {
        self.frame(
            maxWidth: .infinity,
            maxHeight: .infinity,
            alignment: alignment
        )
    }

}

struct ContentView : View {

    var body: some View {
        VStack(alignment: .leading) {
            Text("Title")
                .font(.title)
            Text("Content")
                .font(.body)
        }
        .fullSize(alignment: .topLeading)
        .background(Color.red)
    }

}

2. Spacerसंरेखण को मजबूर करने के लिए एस का उपयोग करना

आप अपने VStackपूर्ण आकार के अंदर एम्बेड कर सकते हैं HStackऔर Spacerअपने VStackशीर्ष अग्रणी संरेखण को मजबूर करने के लिए ट्रेलिंग और बॉटम एस का उपयोग कर सकते हैं :

struct ContentView: View {

    var body: some View {
        HStack {
            VStack(alignment: .leading) {
                Text("Title")
                    .font(.title)
                Text("Content")
                    .font(.body)

                Spacer() // VStack bottom spacer
            }

            Spacer() // HStack trailing spacer
        }
        .frame(
            maxWidth: .infinity,
            maxHeight: .infinity
        )
        .background(Color.red)
    }

}

3. एक ZStackऔर एक पूर्ण आकार की पृष्ठभूमि का उपयोग करनाView

इस उदाहरण से पता चलता है कि किस प्रकार आपके VStackअंदर ZStackएक शीर्ष अग्रणी संरेखण है। ध्यान दें कि Colorअधिकतम चौड़ाई और ऊंचाई निर्धारित करने के लिए दृश्य का उपयोग कैसे किया जाता है:

struct ContentView: View {

    var body: some View {
        ZStack(alignment: .topLeading) {
            Color.red
                .frame(maxWidth: .infinity, maxHeight: .infinity)

            VStack(alignment: .leading) {
                Text("Title")
                    .font(.title)
                Text("Content")
                    .font(.body)
            }
        }
    }

}

4. उपयोग करना GeometryReader

GeometryReaderनिम्नलिखित घोषणा है :

एक कंटेनर दृश्य जो अपनी सामग्री को अपने स्वयं के आकार के कार्य के रूप में परिभाषित करता है और अंतरिक्ष को समन्वित करता है। [...] यह दृश्य अपने मूल लेआउट के लिए एक लचीला पसंदीदा आकार देता है।

नीचे दिए गए कोड स्निपेट से पता चलता है कि शीर्ष अग्रणी बाधाओं और एक पूर्ण आकार फ्रेम के साथ GeometryReaderअपने संरेखित करने के लिए कैसे उपयोग करें VStack:

struct ContentView : View {

    var body: some View {
        GeometryReader { geometryProxy in
            VStack(alignment: .leading) {
                Text("Title")
                    .font(.title)
                Text("Content")
                    .font(.body)
            }
            .frame(
                width: geometryProxy.size.width,
                height: geometryProxy.size.height,
                alignment: .topLeading
            )
        }
        .background(Color.red)
    }

}

5. overlay(_:alignment:)विधि का उपयोग करना

यदि आप VStackकिसी मौजूदा पूर्ण आकार के शीर्ष पर अपने शीर्ष अग्रणी अवरोधों के साथ संरेखित करना चाहते हैं View, तो आप overlay(_:alignment:)विधि का उपयोग कर सकते हैं :

struct ContentView: View {

    var body: some View {
        Color.red
            .frame(
                maxWidth: .infinity,
                maxHeight: .infinity
            )
            .overlay(
                VStack(alignment: .leading) {
                    Text("Title")
                        .font(.title)
                    Text("Content")
                        .font(.body)
                },
                alignment: .topLeading
            )
    }

}

प्रदर्शित करें:


10

सबसे आसान तरीका है कि मैं इस मुद्दे को हल करने का प्रबंधन एक ZStack + .edgesIgnoringSafeArea।

struct TestView : View {

    var body: some View {
        ZStack() {
            Color.yellow.edgesIgnoringSafeArea(.all)
            VStack {
                Text("Hello World")
            }
        }
    }
}


4

आप इसका उपयोग करके कर सकते हैं GeometryReader

GeometryReader

कोड:

struct ContentView : View {
    var body: some View {
        GeometryReader { geometry in
            VStack {
               Text("Turtle Rock").frame(width: geometry.size.width, height: geometry.size.height, alignment: .topLeading).background(Color.red)
            }
        }
    }
}

आपका आउटपुट जैसे:

यहाँ छवि विवरण दर्ज करें


4

एक अच्छा समाधान और "गर्भनिरोधक" के बिना भूल गया है ZStack

ZStack(alignment: .top){
    Color.red
    VStack{
        Text("Hello World").font(.title)
        Text("Another").font(.body)
    }
}

परिणाम:

यहाँ छवि विवरण दर्ज करें


3

एक और विकल्प के अंदर HStackएक के Spacer()बाद एक साक्षात्कारों को रखना और उसके बाद रखना है :

struct ContentView : View {
    var body: some View {
        VStack(alignment: .leading) {

            HStack {
                Text("Title")
                    .font(.title)
                    .background(Color.yellow)
                Spacer()
            }

            Text("Content")
                .lineLimit(nil)
                .font(.body)
                .background(Color.blue)

            Spacer()
            }

            .background(Color.red)
    }
}

जिसके परिणामस्वरूप :

HStack एक VStack के अंदर


1
इम्हो, यह सबसे सुरुचिपूर्ण समाधान है
व्याचेस्लाव

3

मेरे लिए यह काम किया गया है (यदि ScrollViewवैकल्पिक हो तो और अधिक सामग्री जोड़ी जा सकती है, यदि आवश्यक हो, तो सामग्री केंद्रित है):

import SwiftUI

struct SomeView: View {
    var body: some View {
        GeometryReader { geometry in
            ScrollView(Axis.Set.horizontal) {
                HStack(alignment: .center) {
                    ForEach(0..<8) { _ in
                        Text("🥳")
                    }
                }.frame(width: geometry.size.width, height: 50)
            }
        }
    }
}

// MARK: - Preview

#if DEBUG
struct SomeView_Previews: PreviewProvider {
    static var previews: some View {
        SomeView()
    }
}
#endif

परिणाम

केंद्रित


2

मुझे पता है कि यह सभी के लिए काम नहीं करेगा, लेकिन मुझे यह दिलचस्प लगा कि इसके लिए सिर्फ एक डिवाइडर को जोड़ना है।

struct DividerTest: View {
var body: some View {
    VStack(alignment: .leading) {
        Text("Foo")
        Text("Bar")
        Divider()
    }.background(Color.red)
  }
}

2

यह एक उपयोगी कोड है:

extension View {
    func expandable () -> some View {
        ZStack {
            Color.clear
            self
        }
    }
}

.expandable()संशोधक के साथ और उसके बिना परिणामों की तुलना करें :

Text("hello")
    .background(Color.blue)

-

Text("hello")
    .expandable()
    .background(Color.blue)

यहाँ छवि विवरण दर्ज करें


2

यहाँ छवि विवरण दर्ज करें

पेज डिजाइन का उपयोग कर लॉगिन करें SwiftUI

import SwiftUI

struct ContentView: View {

    @State var email: String = "william@gmail.com"
    @State var password: String = ""
    @State static var labelTitle: String = ""


    var body: some View {
        VStack(alignment: .center){
            //Label
            Text("Login").font(.largeTitle).foregroundColor(.yellow).bold()
            //TextField
            TextField("Email", text: $email)
                .textContentType(.emailAddress)
                .foregroundColor(.blue)
                .frame(minHeight: 40)
                .background(RoundedRectangle(cornerRadius: 10).foregroundColor(Color.green))

            TextField("Password", text: $password) //Placeholder
                .textContentType(.newPassword)
                .frame(minHeight: 40)
                .foregroundColor(.blue) // Text color
                .background(RoundedRectangle(cornerRadius: 10).foregroundColor(Color.green))

            //Button
            Button(action: {

            }) {
                HStack {
                    Image(uiImage: UIImage(named: "Login")!)
                        .renderingMode(.original)
                        .font(.title)
                        .foregroundColor(.blue)
                    Text("Login")
                        .font(.title)
                        .foregroundColor(.white)
                }


                .font(.headline)
                .frame(minWidth: 0, maxWidth: .infinity)
                .background(LinearGradient(gradient: Gradient(colors: [Color("DarkGreen"), Color("LightGreen")]), startPoint: .leading, endPoint: .trailing))
                .cornerRadius(40)
                .padding(.horizontal, 20)

                .frame(width: 200, height: 50, alignment: .center)
            }
            Spacer()

        }.padding(10)

            .frame(minWidth: 0, idealWidth: .infinity, maxWidth: .infinity, minHeight: 0, idealHeight: .infinity, maxHeight: .infinity, alignment: .top)
            .background(Color.gray)

    }

}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

1

पैरेंट को भरने के लिए आप एक आसान एक्सटेंशन में जियोमेट्री राइडर का उपयोग कर सकते हैं

extension View {
    func fillParent(alignment:Alignment = .center) -> some View {
        return GeometryReader { geometry in
            self
                .frame(width: geometry.size.width,
                       height: geometry.size.height,
                       alignment: alignment)
        }
    }
}

इसलिए अनुरोधित उदाहरण का उपयोग करते हुए, आपको मिलता है

struct ContentView : View {
    var body: some View {
        VStack(alignment: .leading) {
            Text("Title")
                .font(.title)

            Text("Content")
                .lineLimit(nil)
                .font(.body)
        }
        .fillParent(alignment:.topLeading)
        .background(Color.red)
    }
}

(ध्यान दें कि स्पेसर की अब आवश्यकता नहीं है)

यहाँ छवि विवरण दर्ज करें


यह फुल स्क्रीन नहीं है।
डक डक

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.