2012-11-01 33 views
60

मैं अपने सभी बटनों में पैडिंग जोड़ना चाहता हूं, इसलिए मैंने UIButton को उपclassed, और अन्य परिवर्तनों के बीच, मैं setFrame विधि का उपयोग करके एक निश्चित पैडिंग जोड़ना चाहता था। सेटफ्रेम को छोड़कर सबकुछ काम कर रहा था। मैंने चारों ओर जांच की, और मुझे पता चला कि अगर मैं उस दृश्य पर "ऑटोलाउट का उपयोग करके" अनचेक करता हूं, तो मैं setFrame का उपयोग कर सकता हूं, और यह काम करता है। क्या इसके चारों ओर एक रास्ता है? मैं वास्तव में ऑटोलाउट का उपयोग करना चाहता हूं, क्योंकि यह ऐप 5 और पिछले डिवाइस दोनों पर ऐप को अच्छा बनाने में मदद करता है। लेकिन मैं अपने जीवन को एक लिटल आसान बनाने के लिए, मेरे सबक्लास में सेटफ्रेम का भी उपयोग करना चाहता हूं।क्या मैं एक ही दृश्य पर सेटफ्रेम और ऑटोलाउट का उपयोग कर सकता हूं?

सारांश, मेरा प्रश्न है: क्या मैं ऑटोलाउट का उपयोग कर सकता हूं और प्रोग्रामिंग के यूआईवीव के फ्रेम को समायोजित भी कर सकता हूं?

उत्तर

193

हां, यह किया जा सकता है।

आप निर्धारित करते हैं तो किसी दृश्य के translatesAutoresizingMaskIntoConstraints = YES, तो setFrame: करने के लिए कॉल स्वचालित रूप से देखने की वर्तमान autoresizingMask के आधार पर लेआउट बाधाओं में कार्यावधि में अनुवाद कर रहे हैं। यह आपको फ्रेम-आधारित लेआउट को बाधा-आधारित लेआउट के साथ मिश्रित करने देता है।

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

हालांकि, translatesAutoresizingMaskIntoConstraints का उपयोग करने के बारे में एक बड़ी चेतावनी है।

जब आप ऐसा करते हैं, आपको अभी भी यह सुनिश्चित करने की आवश्यकता है कि ये स्वचालित बाधाएं आपकी शेष बाधाओं से संतुष्ट हो सकती हैं

तो, उदाहरण के लिए, वहाँ पहले से ही कमी है कि आकार और आपके विचार की स्थिति का निर्धारण कर रहे हैं लगता है, और फिर आप भीtranslatesAutoresizingMaskIntoConstraints = YES सेट और setFrame: कहा जाता है। setFrame: पर कॉल दृश्य पर नई बाधा उत्पन्न करेगा, जो शायद पहले से मौजूद बाधाओं के साथ संघर्ष करेगा।

(वास्तव में, इस त्रुटि अक्सर होता है। क्या तुमने कभी परस्पर विरोधी की कमी के बारे में शिकायत एक लॉग संदेश देखते हैं, और उन बाधाओं में से एक एक NSAutoresizingMaskLayoutConstraint है, तो आप जो देख रहे एक स्वचालित बाधा के विरोध में है। यह वह जगह है एक आसान गलती है, क्योंकि translatesAutoresizingMaskIntoConstraints = YES डिफ़ॉल्ट मान है, तो आप कोड में बाधाओं को कॉन्फ़िगर करते हैं आप इसे बंद करना पड़ा अगर आप इन स्वत: कमी नहीं करना चाहती याद करने की जरूरत है।)

इसके विपरीत, फिर लगता है कि वहाँ पहले से मौजूद मौजूदा बाधाएं हैं जो आपके दृश्य का आकार और स्थिति निर्धारित करती हैं, लेकिन फिर आप setFrame: पर कॉल करने से पहले translatesAutoresizingMaskIntoConstraints = NO सेट करते हैं। इस मामले में, आपके setFrame: कॉल नई बाधा उत्पन्न नहीं करेंगे, इसलिए अलग-अलग बाधाओं के बीच कोई संघर्ष नहीं होगा। हालांकि, इस मामले में, सेट की गई बाधाओं और फ्रेम मान के बीच अभी भी "संघर्ष" है। अगली बार ऑटो लेआउट का आह्वान किया जाता है, यह दृश्य पर पहले से मौजूद मौजूदा बाधाओं को देखेगा, उन्हें आवश्यक फ्रेम फ्रेम की गणना करेगा, और फ्रेम को आवश्यक मान पर सेट कर देगा, जो आपके द्वारा मैन्युअल रूप से सेट किए गए मान को क्लोब कर देगा।

अधिक जानकारी के लिए, ऐप्पल के Cocoa Auto Layout Guide में "ऑटो लेआउट को अपनाने" अनुभाग देखें।

+2

यह काम करता है लेकिन मुझे लॉग में बहुत सारी चेतावनियां दिखाई देती हैं। क्या कोई सुझाव दे सकता है कि इस दृष्टिकोण का उपयोग करने का सही तरीका क्या है? या मुझे सिर्फ चेतावनियों को अनदेखा करना चाहिए? धन्यवाद – Husyn

+4

यदि आप असंतोषजनक बाधाओं की चेतावनियां देखते हैं, तो वे शायद सार्थक हैं। यदि आप किसी अनुवाद पर 'translationsAutoresizingMaskIntoConstraints = true' के साथ परिचालन करते समय उन्हें देख रहे हैं, तो शायद हो रहा है कि आप पहले से ही * कुछ बाधाएं (शायद आईबी में सेट हैं) जो उस दृश्य के फ्रेम को नियंत्रित करने का प्रयास करें। फ्रेम पर उन पुरानी बाधाएं ऑटोरेसाइजिंग मास्क से स्वतः उत्पन्न होने वाले लोगों के साथ बातचीत कर रही हैं। उस स्थिति में, जवाब उन पुरानी बाधाओं को दूर करना है। यदि आपने उन्हें आईबी में डिजाइन समय पर बंद करने के लिए आईबी में जोड़ा है, तो आप उन्हें "प्लेसहोल्डर्स" को खोने के लिए बना सकते हैं। – algal

+1

ठीक हो गया! बहुत बढ़िया जवाब! – Developer

16

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

[cell.myLabel removeFromSuperview]; 
cell.myLabel.frame = someFrameIGenerated; 
[cell.contentView addSubview:cell.myLabel]; 
+0

ओह, अच्छा! मेरे लिए काम किया धन्यवाद! – Marky

+2

कोई समस्या नहीं है। हालांकि मैं आपको बताने के लिए बाध्य महसूस करता हूं कि मैं इससे छुटकारा पा रहा हूं और वास्तव में सीख रहा हूं कि आईबी में बाधाओं का उपयोग कैसे किया जाए। मुझे नहीं पता था कि वे अस्तित्व में हैं, और जटिल लेआउट बनाना अब और अधिक उचित लगता है। – Andrew

+0

हाँ मैंने कोशिश की, लेकिन तालिका शीर्षलेख दृश्य पर काम करने वाली बाधाएं नहीं मिल सका। शायद मुझे फिर कोशिश करनी चाहिए। – Marky

0

आपका ऐप एकाधिक डिवाइस झुकाव के लिए समर्थन नहीं करता है: उदाहरण के लिए, एक UITableViewCell उपवर्ग में एक कस्टम UILabel ले।

viewDidLoad दृश्य में जो आप viewDidLayoutSubviews में फिर

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 
    [aView setFrame:CGRectMake(15, 15, 100, 100)]; 
} 

आकार बदलने के लिए चाहते हैं के फ्रेम सेट:

-(void)viewDidLayoutSubviews 
{ 
    [self.view setTranslatesAutoresizingMaskIntoConstraints:NO]; 
} 

मुझे यकीन है कि नहीं कर रहा हूँ, लेकिन मुझे लगता है कि अगर आप का उपयोग करें यह समाधान, एक ओरिएंटेशन को दूसरे पर स्विच करने से समस्याएं हो सकती हैं

2

मेरे लिए काम करने वाला कुछ बस दृश्य नियंत्रक को मेरी बाधाओं के लिए IBOutlet जोड़ रहा था, फिर आउटलेट पर constant संपत्ति को बदल रहा था।

उदाहरण के लिए, दृश्य के एक्स मूल को बदलने के लिए, उस दृश्य की अग्रणी बाधा से अपने नियंत्रक को आउटलेट सेट करें। दूसरे शब्दों में, एक आउटलेट @IBOutlet var labelXOrigin: NSLayoutConstraint! बनाएं। फिर, जब आप एक्स स्थिति को समायोजित करना चाहते हैं, बस उप देखने के फ्रेम सेट करने के लिए

self.labelXOrigin.constant = 20.0 // Or whatever origin you want to set. 
2

सबसे अच्छा तरीका है की तरह कुछ करना autolayout परियोजनाओं में viewWillLayoutSubviews तरीका है।

सेट संपत्ति का अनुवाद किया गया हैअटोरोसिंगमास्कइन्टो कॉन्स्ट्रेनेंट्स = सच यह दिखाई देने के बाद काम करेगा या सेट करने के लिए बटन पर टैब होगा, बस दृश्य दिखाई देने के बाद।