प्रोग्रामेटिक रूप से लेआउट की कमी पैदा करना


84

मुझे पता है कि बहुत सारे लोगों ने पहले ही इस बारे में कई सवाल पूछे थे, लेकिन जवाब के साथ भी मैं इसे काम नहीं कर सकता।

जब मैं स्टोरीबोर्ड पर बाधाओं से निपट रहा हूं, तो यह आसान है लेकिन कोड में मेरे पास कठिन समय है। मैं, उदाहरण के लिए, एक दृश्य है कि सही पक्ष पर रहता है और स्क्रीन अभिविन्यास के अनुसार स्क्रीन की ऊंचाई है कोशिश करते हैं। यह मेरा कोड है:

UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 748)];
myView.backgroundColor = [UIColor redColor];
[self.view addSubview:myView];
[self.view addConstraints:[NSLayoutConstraint
    constraintsWithVisualFormat:@"V:|-[myView(>=748)]-|"
    options:0 metrics:nil
    views:NSDictionaryOfVariableBindings(myView)]];

यह कुछ बाधाओं को संतुष्ट नहीं करता है। मैं नहीं देखता कि क्या गलत है। इसके अलावा, मैं self.myViewएक स्थानीय चर की तरह संपत्ति का उपयोग क्यों नहीं कर सकता myView?


उपरोक्त कोड में vivi क्या है?
डेव

14
कृपया "IOS" के बजाय शीर्षक को "iOS" में बदलें - बाद वाला सिस्को के स्विच / राउटर ऑपरेटिंग सिस्टम को संदर्भित करता है। मुझे भ्रमित कर दिया। धन्यवाद।
अरमानी

1
इस बारे में कई प्रश्न: (1) "कुछ बाधाओं को पूरा नहीं करने" पर आपको क्या त्रुटि हो रही है? (२) क्या आप बाधाओं पर ऑटोरेस्ज़िंग का अनुवाद कर रहे हैं myView? (३) क्या है vivi(जैसा कि एसीबी ने पूछा) (४) क्या आपके पास कोई संपत्ति myViewघोषित है self?
टिम

1
मैं टिम, अच्छी तरह से माफ करना vivi, मैं बहुत तेजी से टेप ... यह myView है। अनुवाद करने से आपका क्या अभिप्राय है? सब मैं यह ऊपर कोड पर है। संपत्ति के बारे में, मेरे पास कुछ अन्य विचार हैं जो संपत्ति के रूप में घोषित किए जाते हैं, लेकिन जब मैं उसी कोड को उस संपत्ति पर लागू करता हूं जो यह दुर्घटनाग्रस्त होता है ... संदेश "त्रुटि" वास्तव में बड़ा है, मैं इसे यहां पेस्ट नहीं कर सकता
pierre23

किसी विशेष दृष्टिकोण से बाधाओं को हटाने के लिए अस्थायी रूप से इस stackoverflow.com/questions/13388104/…
सैम बी

जवाबों:


106

कोड में ऑटो लेआउट का उपयोग करते समय, फ्रेम सेट करना कुछ भी नहीं करता है। तो यह तथ्य कि आपने ऊपर के दृश्य पर 200 की चौड़ाई निर्दिष्ट की है, जब आप उस पर अड़चन स्थापित करते हैं तो इसका कोई मतलब नहीं है। किसी दृश्य के अवरोध के लिए असंदिग्ध होने के लिए, उसे चार चीजों की आवश्यकता होती है: एक एक्स-पोजीशन, एक वाई-पोजीशन, एक चौड़ाई और किसी भी अवस्था के लिए ऊँचाई।

वर्तमान में ऊपर दिए गए कोड में, आपके पास केवल दो (ऊंचाई, पर्यवेक्षण के सापेक्ष, और y- स्थिति, पर्यवेक्षक के सापेक्ष) है। इसके अतिरिक्त, आपके पास दो आवश्यक बाधाएं हैं जो इस बात पर निर्भर करती हैं कि दृश्य के पर्यवेक्षण की बाधाएं सेटअप कैसे हैं। यदि पर्यवेक्षण में एक आवश्यक बाधा होती है जो निर्दिष्ट करती है कि यह ऊँचाई 748 से कुछ कम है, तो आपको "असंतोषजनक बाधा" अपवाद मिलेगा।

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

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

[self.view addConstraints:[NSLayoutConstraint
    constraintsWithVisualFormat:@"V:|-[myView(>=748)]-|"
    options:NSLayoutFormatDirectionLeadingToTrailing
    metrics:nil
    views:NSDictionaryOfVariableBindings(myView)]];

[self.view addConstraints:[NSLayoutConstraint
    constraintsWithVisualFormat:@"H:[myView(==200)]-|"
    options:NSLayoutFormatDirectionLeadingToTrailing
    metrics:nil
    views:NSDictionaryOfVariableBindings(myView)]];

वर्टिकल कॉन्स्टेंट के साथ शुरू होने वाले इस लेआउट को पढ़ते हुए मौखिक रूप से बताया गया है:

myView मानक स्थान के बराबर शीर्ष और नीचे की गद्दी के साथ अपने पर्यवेक्षण की ऊंचाई को भरेगा। myView के पर्यवेक्षण में 748's की न्यूनतम ऊंचाई है। myView की चौड़ाई 200pts है और इसके पर्यवेक्षण के खिलाफ मानक स्थान के बराबर एक सही पैडिंग है।

यदि आप सुपरवाइवे की ऊंचाई को बाधित किए बिना पूरे पर्यवेक्षक की ऊंचाई को भरने के लिए दृश्य को पसंद करेंगे, तो आप (>=748)दृश्य प्रारूप पाठ में पैरामीटर को छोड़ देंगे । यदि आपको लगता है कि (>=748)पैरामीटर को ऊँचाई देने की आवश्यकता है - आप इस उदाहरण में नहीं हैं: |बार के साथ पर्यवेक्षक के किनारों पर दृश्य को पिन करना ( ) या स्पेस के साथ बार ( |-,-| ) सिंटैक्स के , आप अपने दृश्य को y दे रहे हैं -पोजिशन (एक किनारे पर दृश्य को पिन करना), और ऊँचाई के साथ एक वाई-पोज़िशन (दोनों किनारों पर दृश्य को पिन करना), इस प्रकार दृश्य के लिए आपके बाधा सेट को संतुष्ट करता है।

आपके दूसरे प्रश्न के संबंध में:

का उपयोग करना NSDictionaryOfVariableBindings(self.myView)(यदि आपके पास myView के लिए एक संपत्ति सेटअप था) और अपने VFL self.myViewमें अपने VFL पाठ में उपयोग करने के लिए फीडिंग , तो आपको संभवतः एक अपवाद मिलेगा जब ऑटोलयूट आपके VFL पाठ को पार्स करने की कोशिश करता है। इसे शब्दकोश कुंजियों में डॉट नोटेशन और उपयोग करने की कोशिश करने वाले सिस्टम के साथ करना है valueForKeyPath:इसी तरह के सवाल और जवाब के लिए यहां देखें


कुछ वस्तुओं को मत भूलो जैसे कि उइलाबेल का आंतरिक आकार होता है और आपको उस वस्तु की चौड़ाई या ऊंचाई निर्धारित करने की आवश्यकता नहीं होती है, केवल स्थिति होती है। हालाँकि यदि आप ऊँचाई या चौड़ाई निर्धारित करते हैं, मेरा मानना ​​है कि यह दोनों को हटा देता है और आपको दोनों की आपूर्ति करनी होती है।
निक टर्नर

भले ही यह जवाब मेरे सवाल का जवाब नहीं दिया, लेकिन इससे मुझे कुछ एहसास हुआ। होने के लिए धन्यवाद! :)
मटज

1
इंटरनेट पर अब तक का एकमात्र संक्षिप्त और पठनीय ऑटो लेआउट परिचय।
जॉय कार्सन

plz मेरी मदद करो मेरा सवाल यह है ... मैं नहीं जानता कि कैसे बाधाओं का उपयोग करने के लिए प्रोग्राम stackoverflow.com/questions/36326288/…

61

नमस्ते, मैं इस पृष्ठ को बाधाओं और "कैसे" के लिए बहुत उपयोग कर रहा हूं। मुझे हमेशा इस बात का एहसास हुआ कि मुझे अपनी ज़रूरत का एहसास हो गया है:

myView.translatesAutoresizingMaskIntoConstraints = NO;

काम करने के लिए इस उदाहरण को पाने के लिए। यहां स्पष्टीकरण और कोड के लिए यूजरएक्सएक्सएक्सएक्स, आरओबी एम और विशेष रूप से लार्सस धन्यवाद, यह अमूल्य है।

ऊपर दिए गए उदाहरणों को चलाने के लिए यहां पूरा कोड दिया गया है:

UIView *myView = [[UIView alloc] init];
myView.backgroundColor = [UIColor redColor];
myView.translatesAutoresizingMaskIntoConstraints = NO;  //This part hung me up 
[self.view addSubview:myView];
//needed to make smaller for iPhone 4 dev here, so >=200 instead of 748
[self.view addConstraints:[NSLayoutConstraint
                           constraintsWithVisualFormat:@"V:|-[myView(>=200)]-|"
                           options:NSLayoutFormatDirectionLeadingToTrailing
                           metrics:nil
                           views:NSDictionaryOfVariableBindings(myView)]];

[self.view addConstraints:[NSLayoutConstraint
                           constraintsWithVisualFormat:@"H:[myView(==200)]-|"
                           options:NSLayoutFormatDirectionLeadingToTrailing
                           metrics:nil
                           views:NSDictionaryOfVariableBindings(myView)]];

11

स्विफ्ट संस्करण

स्विफ्ट 3 के लिए अपडेट किया गया

यह उदाहरण दो तरीकों को प्रोग्रामेटिक रूप से निम्न बाधाओं को जोड़ने के लिए दिखाएगा जैसे कि इंटरफ़ेस बिल्डर में कर रहा है:

चौड़ाई और ऊंचाई

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

कंटेनर में केंद्र

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

बॉयलरप्लेट कोड

override func viewDidLoad() {
    super.viewDidLoad()

    // set up the view
    let myView = UIView()
    myView.backgroundColor = UIColor.blue
    myView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(myView)

    // Add constraints code here (choose one of the methods below)
    // ...
}

विधि 1: एंकर स्टाइल

// width and height
myView.widthAnchor.constraint(equalToConstant: 200).isActive = true
myView.heightAnchor.constraint(equalToConstant: 100).isActive = true

// center in container
myView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
myView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

विधि 2: NSLayoutConstraint स्टाइल

// width and height
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 200).isActive = true
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100).isActive = true

// center in container
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0).isActive = true

टिप्पणियाँ

  • एंकर स्टाइल स्टाइल पर पसंदीदा तरीका है NSLayoutConstraint, हालांकि यह केवल iOS 9 से उपलब्ध है, इसलिए यदि आप iOS 8 का समर्थन कर रहे हैं तो आपको NSLayoutConstraintस्टाइल का उपयोग करना चाहिए ।
  • प्रोग्रामेटिक रूप से विवशता दस्तावेज बनाना भी देखें ।
  • एक पिनिंग बाधा को जोड़ने के एक समान उदाहरण के लिए इस उत्तर को देखें ।

5

संपत्तियों के बारे में अपने दूसरे प्रश्न के बारे में, आप self.myViewकेवल तभी उपयोग कर सकते हैं जब आपने इसे वर्ग में संपत्ति घोषित किया हो। चूंकि myViewएक स्थानीय चर है, आप इसे उस तरह से उपयोग नहीं कर सकते। इस बारे में अधिक जानकारी के लिए, मैं आपको घोषित संपत्तियों पर सेब के दस्तावेज के माध्यम से जाने की सलाह दूंगा ,


5

मैं self.myViewmyView जैसे स्थानीय चर के बजाय संपत्ति का उपयोग क्यों नहीं कर सकता ?

प्रयोग करके देखें:

NSDictionaryOfVariableBindings(_view)

के बजाय self.view


इससे मेरा ऐप दुर्घटनाग्रस्त हो गया, यह संदेश देता है: 'बाधा प्रारूप को पार्स करने में असमर्थ: पॉलीलाइन आइमेज व्यू विचारों की शब्दकोश में एक कुंजी नहीं है।'
ताई ले

4

कृपया यह भी ध्यान दें कि iOS9 से हम नए सहायक वर्ग NSLayoutAnchor के उपवर्गों का उपयोग करके प्रोग्राम को "अधिक संक्षिप्त, और पढ़ने में आसान" के रूप में परिभाषित कर सकते हैं ।

डॉक्टर से एक उदाहरण:

[self.cancelButton.leadingAnchor constraintEqualToAnchor:self.saveButton.trailingAnchor constant: 8.0].active = true;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.