2013-05-30 15 views
39

निम्न कोड (viewDidLoad में कहा जाता है) परिणाम पूरी तरह से लाल स्क्रीन में परिणाम। मैं उम्मीद करता हूं कि यह पूरी तरह से हरी स्क्रीन होगी। यह लाल क्यों है? और मैं इसे सब हरा कैसे बना सकता हूं?यूआईएसक्रॉलव्यू के साथ आईओएस ऑटोलाउटआउट: स्क्रॉल व्यू के सामग्री दृश्य को स्क्रॉल व्यू क्यों नहीं भरता है?

UIScrollView* scrollView = [UIScrollView new]; 
scrollView.translatesAutoresizingMaskIntoConstraints = NO; 
scrollView.backgroundColor = [UIColor redColor]; 
[self.view addSubview:scrollView]; 

UIView* contentView = [UIView new]; 
contentView.translatesAutoresizingMaskIntoConstraints = NO; 
contentView.backgroundColor = [UIColor greenColor]; 
[scrollView addSubview:contentView]; 

NSDictionary* viewDict = NSDictionaryOfVariableBindings(scrollView,contentView); 

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics:0 views:viewDict]]; 
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" options:0 metrics:0 views:viewDict]]; 

[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView]|" options:0 metrics:0 views:viewDict]]; 
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|" options:0 metrics:0 views:viewDict]]; 

उत्तर

66

स्क्रॉल दृश्यों के साथ बाधाएं अन्य विचारों के मुकाबले थोड़ा अलग तरीके से काम करती हैं। contentView और superview (scrollView) के बीच की बाधा scrollView के contentSize पर है, न कि frame पर। यह भ्रमित प्रतीत हो सकता है, लेकिन यह वास्तव में काफी उपयोगी है, जिसका अर्थ है कि आपको कभी भी contentSize समायोजित करना नहीं है, बल्कि contentSize स्वचालित रूप से आपकी सामग्री के अनुरूप समायोजित हो जाएगा। इस व्यवहार का वर्णन Technical Note TN2154 में किया गया है।

यदि आप स्क्रीन पर contentView आकार को परिभाषित करना चाहते हैं या ऐसा कुछ है, तो आपको contentView और मुख्य दृश्य के बीच एक बाधा जोड़नी होगी, उदाहरण के लिए। यह स्वीकार्य रूप से, स्क्रॉलव्यू में सामग्री डालने के लिए विरोधाभासी है, इसलिए शायद मैं इसे सलाह नहीं दूंगा, लेकिन यह किया जा सकता है।


इस अवधारणा को समझने के लिए, कि contentView के आकार, उसकी सामग्री के द्वारा संचालित किया जाएगा scrollView की bounds से नहीं, अपने contentView में लेबल जोड़ने: अब

UIScrollView* scrollView = [UIScrollView new]; 
scrollView.translatesAutoresizingMaskIntoConstraints = NO; 
scrollView.backgroundColor = [UIColor redColor]; 
[self.view addSubview:scrollView]; 

UIView* contentView = [UIView new]; 
contentView.translatesAutoresizingMaskIntoConstraints = NO; 
contentView.backgroundColor = [UIColor greenColor]; 
[scrollView addSubview:contentView]; 

UILabel *randomLabel = [[UILabel alloc] init]; 
randomLabel.text = @"this is a test"; 
randomLabel.translatesAutoresizingMaskIntoConstraints = NO; 
randomLabel.backgroundColor = [UIColor clearColor]; 
[contentView addSubview:randomLabel]; 

NSDictionary* viewDict = NSDictionaryOfVariableBindings(scrollView, contentView, randomLabel); 

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics:0 views:viewDict]]; 
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" options:0 metrics:0 views:viewDict]]; 

[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView]|" options:0 metrics:0 views:viewDict]]; 
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|" options:0 metrics:0 views:viewDict]]; 

[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[randomLabel]-|" options:0 metrics:0 views:viewDict]]; 
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[randomLabel]-|" options:0 metrics:0 views:viewDict]]; 

आप करेंगे देखें कि contentView (और, contentSizescrollView) मानक मार्जिन के साथ लेबल फिट करने के लिए समायोजित किए गए हैं। और क्योंकि मैंने लेबल की चौड़ाई/ऊंचाई निर्दिष्ट नहीं की है, जो उस लेबल में आपके द्वारा रखे गए पाठ के आधार पर समायोजित होगी।


आप contentView भी मुख्य दृश्य की चौड़ाई के समायोजित करना चाहते हैं, तो आप ऐसा तरह फिर से परिभाषित कर सकता है आपके viewDict, और फिर इन अतिरिक्त की कमी (सभी दूसरों के अलावा, ऊपर) जोड़ें:

UIView *mainView = self.view; 

NSDictionary* viewDict = NSDictionaryOfVariableBindings(scrollView, contentView, randomLabel, mainView); 

[mainView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[contentView(==mainView)]" options:0 metrics:0 views:viewDict]]; 

scrollviews में बहु लेबल के साथ एक known issue (bug?) है, कि अगर आप इसे पाठ की मात्रा के अनुसार आकार बदलने के लिए चाहते हैं, आप इस तरह के रूप में, हाथ से कुछ सफ़ाई करना है:

dispatch_async(dispatch_get_main_queue(), ^{ 
    randomLabel.preferredMaxLayoutWidth = self.view.bounds.size.width; 
}); 
+1

मैं अगर पाठ बहुत पर फिट करने के लिए लंबा है लेबल पाने के लिए खड़ी विस्तार करने के लिए नहीं कर पा रहे एक पंक्ति। मैंने लाइनों की संख्या 0 पर सेट की है, और लाइन ब्रेकमोड को NSLineBreakByWordWrapping पर सेट किया है। क्या मैं कुछ भूल रहा हूँ? – rdelmar

+0

इसके अतिरिक्त, मैंने सामग्री की चौड़ाई को पिन करने के लिए आपके उत्तर में अंतिम पंक्ति को जोड़ा है स्क्रीन की चौड़ाई को देखें (अन्यथा सामग्री दृश्य की चौड़ाई लंबे पाठ को समायोजित करने के लिए पर्याप्त है)। यदि मैं स्पष्ट रूप से ऊंचाई की बाधा वाले लेबल की ऊंचाई निर्धारित करता हूं, तो यह काम करता है। – rdelmar

+0

हाँ, मैट ने इस समस्या के लिए [कुछ कार्य-आस-पास] खोजा (http://stackoverflow.com/questions/13149733/ios-autolayout-issue-with-uilabels-in-a-resizing-parent-view) मल्टीलाइन लेबल की बग। मैंने उनमें से एक को मेरे उत्तर के नीचे जोड़ा है। एक पूरी तरह असंतोषजनक समाधान। ऐसा लगता है कि आपको हार्डकोडिंग मान या इस क्लूडी वर्कअराउंड के बीच चयन करना है। – Rob

1

मैंने रोब का जवाब पहले ठीक दिखने की कोशिश की। लेकिन! यदि आपने को ज़ूम किया है, तो यह ऑटोलायआउट कोड रास्ते में होगा। यह सामग्री को आकार बदलता रहता है जब ज़ूम करता है। यही है, अगर मैं ज़ूम इन करता हूं (ज़ूमस्केले> 1), तो मैं स्क्रीन के बाहर के हिस्सों को स्क्रॉल करने में सक्षम नहीं होगा।

ऑटोलायआउट के साथ लड़ने के कुछ दिनों बाद, दुख की बात है कि मुझे कोई समाधान नहीं मिला। अंत में, इससे कोई फर्क नहीं पड़ता (wat? ठीक है, क्षमा करें)। अंत में, मैं सामग्री पर Autolayout को हटा देता हूं (एक निश्चित आकार सामग्री दृश्य का उपयोग करें), और उसके बाद लेआउटस्यूब्यूव्स में, मैंself.scrollView.contentInset समायोजित करता हूं। (मैं एक्सकोड 5, आईओएस 7 का उपयोग कर रहा हूं)

मुझे पता है कि यह इस प्रश्न का सीधा समाधान नहीं है। लेकिन मैं सिर्फ एक आसान कामकाज को इंगित करना चाहता हूं।यह एक निश्चित आकार की सामग्री को केंद्रित करने के लिए पूरी तरह से काम करता है स्क्रॉल व्यू में देखें, कोड की केवल 2 पंक्तियों के साथ! आशा है कि यह किसी की मदद कर सकते हैं;)

- (void)layoutSubviews { 
    [super layoutSubviews]; 

    // move contentView to center of scrollView by changing contentInset, 
    // because I CANNOT set this with AUTOLAYOUT!!! 
    CGFloat topInset = (self.frame.size.height - self.contentView.frame.size.height)/2; 
    self.scrollView.contentInset = UIEdgeInsetsMake(topInset, 0, 0, 0); 
} 
-1

सामान्य तौर पर, ऑटो लेआउट शीर्ष, बाएं, नीचे समझता है, और एक दृश्य के दाएं किनारों पर स्पष्ट किनारों किया जाना है। यही है, यदि आप अपने पर्यवेक्षण के बाएं किनारे पर एक दृश्य पिन करते हैं, तो आप वास्तव में पर्यवेक्षक की सीमाओं के न्यूनतम x-value पर इसे पिन कर रहे हैं। पर्यवेक्षण की सीमाओं को बदलना दृश्य की स्थिति को नहीं बदलता है।

UIScrollView क्लास अपनी सीमाओं की उत्पत्ति को बदलकर अपनी सामग्री को स्क्रॉल करता है। ऑटो लेआउट के साथ यह काम करने के लिए, स्क्रॉल व्यू के भीतर शीर्ष, बाएं, नीचे और दाएं किनारों का अर्थ अब इसकी सामग्री दृश्य के किनारों का है।

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

ध्यान दें कि स्क्रॉल व्यू के पर्यवेक्षण जैसे स्क्रॉल व्यू के उपट्री के बाहर दृश्य और दृश्य के बीच बाधा उत्पन्न करके अन्य स्क्रॉलिंग सामग्री पर फ़्लोट (स्क्रॉल नहीं) दिखाई देने के लिए आप स्क्रॉल व्यू का एक सबव्यूव देख सकते हैं।

यहाँ कैसे पुस्तक देखने के लिए, पहले मिश्रित दृष्टिकोण है, और फिर शुद्ध दृष्टिकोण को कॉन्फ़िगर करने के दो उदाहरण हैं

+0

स्टैक ओवरफ़्लो में आपका स्वागत है। कृपया समीक्षा करें [मैं एक अच्छा उत्तर कैसे लिखूं] (https://meta.stackexchange.com/questions/7656/how-do-i-write-a-good-answer-to-a-question)। – Rick

संबंधित मुद्दे