objective c - UIView फ्रेम, सीमाएं और केंद्र




objective-c ios (5)

इस पोस्ट के विस्तृत स्पष्टीकरण के साथ बहुत अच्छे जवाब हैं। मैं सिर्फ यह देखना चाहता हूं कि डब्ल्यूडब्ल्यूडीसी 2011 वीडियो में फ़्रेम, बाउंड्स, सेंटर, ट्रांसफॉर्म, बाउंड्स उत्पत्ति के अर्थ के लिए दृश्य प्रतिनिधित्व के साथ एक और स्पष्टीकरण है @ 4: 22 से 20:10 तक शुरू होने वाली UIKit रेंडरिंग को समझना

मैं जानना चाहता हूं कि इन गुणों का सही तरीके से उपयोग कैसे करें।

जैसा कि मैं समझता हूं, मैं जिस दृश्य को बना रहा हूं उसके कंटेनर से frame का उपयोग किया जा सकता है। यह कंटेनर व्यू के सापेक्ष दृश्य स्थिति सेट करता है। यह उस दृश्य का आकार भी सेट करता है।

मेरे द्वारा बनाए जा रहे दृश्य के कंटेनर से भी center का उपयोग किया जा सकता है। यह संपत्ति इसके कंटेनर के सापेक्ष दृश्य की स्थिति को बदल देती है।

अंत में, bounds स्वयं दृश्य के सापेक्ष हैं। यह देखने के लिए खींचने योग्य क्षेत्र को बदलता है।

क्या आप frame और bounds बीच संबंधों के बारे में अधिक जानकारी दे सकते हैं? clipsToBounds और masksToBounds गुणों के बारे में क्या?


इस प्रश्न का पहले से ही एक अच्छा जवाब है, लेकिन मैं इसे कुछ और चित्रों के साथ पूरक करना चाहता हूं। मेरा पूरा जवाब यहाँ है।

मुझे फ्रेम याद रखने में मदद करने के लिए, मैं दीवार पर एक तस्वीर फ्रेम के बारे में सोचता हूं। एक तस्वीर की तरह दीवार पर कहीं भी स्थानांतरित किया जा सकता है, दृश्य के फ्रेम की समन्वय प्रणाली पर्यवेक्षण है। (दीवार = पर्यवेक्षण, फ्रेम = दृश्य)

मुझे सीमा याद रखने में मदद करने के लिए, मुझे बास्केटबॉल कोर्ट की सीमाओं के बारे में लगता है। बास्केटबाल कहीं भी अदालत के भीतर है, जैसे दृश्य की सीमाओं की समन्वय प्रणाली स्वयं ही दृश्य में है। (अदालत = देखें, बास्केटबाल / खिलाड़ियों = दृश्य के अंदर सामग्री)

फ्रेम की तरह, view.center पर्यवेक्षण के निर्देशांक में भी है।

फ्रेम बनाम बाउंड - उदाहरण 1

पीला आयत दृश्य के फ्रेम का प्रतिनिधित्व करता है। हरा आयताकार दृश्य की सीमाओं का प्रतिनिधित्व करता है। दोनों छवियों में लाल बिंदु उनके समन्वय प्रणालियों के भीतर फ्रेम या सीमाओं की उत्पत्ति का प्रतिनिधित्व करता है।

Frame
    origin = (0, 0)
    width = 80
    height = 130

Bounds 
    origin = (0, 0)
    width = 80
    height = 130

उदाहरण 2

Frame
    origin = (40, 60)  // That is, x=40 and y=60
    width = 80
    height = 130

Bounds 
    origin = (0, 0)
    width = 80
    height = 130

उदाहरण 3

Frame
    origin = (20, 52)  // These are just rough estimates.
    width = 118
    height = 187

Bounds 
    origin = (0, 0)
    width = 80
    height = 130

उदाहरण 4

यह उदाहरण 2 जैसा ही है, इस समय को छोड़कर दृश्य की पूरी सामग्री को दिखाया गया है क्योंकि ऐसा लगता है कि यह दृश्य की सीमाओं पर नहीं फंस गया था।

Frame
    origin = (40, 60)
    width = 80
    height = 130

Bounds 
    origin = (0, 0)
    width = 80
    height = 130

उदाहरण 5

Frame
    origin = (40, 60)
    width = 80
    height = 130

Bounds 
    origin = (280, 70)
    width = 80
    height = 130

दोबारा, अधिक जानकारी के साथ मेरे उत्तर के लिए यहां देखें।


चूंकि मैंने जो सवाल पूछा है, उसे कई बार देखा गया है, इसलिए मैं इसका विस्तृत उत्तर प्रदान करूंगा। यदि आप अधिक सही सामग्री जोड़ना चाहते हैं तो इसे संशोधित करने के लिए स्वतंत्र महसूस करें।

सबसे पहले प्रश्न पर एक पुनरावृत्ति: फ्रेम, सीमाएं और केंद्र और उनके रिश्ते।

फ़्रेम ए व्यू का frame ( CGRect ) superview की समन्वय प्रणाली में अपने आयताकार की स्थिति है। डिफ़ॉल्ट रूप से यह ऊपर बाईं ओर शुरू होता है।

बाउंड्स एक व्यू की bounds ( CGRect ) अपने स्वयं के समन्वय प्रणाली में एक दृश्य आयताकार व्यक्त करती है।

केंद्र एक center superview समन्वय प्रणाली के संदर्भ में व्यक्त किया गया एक CGPoint है और यह दृश्य के सटीक केंद्र बिंदु की स्थिति निर्धारित करता है।

UIView + स्थिति से लिया गया ये पिछले गुणों के बीच संबंध हैं (वे कोड में काम नहीं करते क्योंकि वे अनौपचारिक समीकरण हैं):

  • frame.origin = center - (bounds.size / 2.0)

  • center = frame.origin + (bounds.size / 2.0)

  • frame.size = bounds.size

नोट: विचारों को घुमाए जाने पर ये रिश्ते लागू नहीं होते हैं। अधिक जानकारी के लिए, मैं सुझाव दूंगा कि आप स्टैनफोर्ड सीएस 1 9 3 पी पाठ्यक्रम के आधार पर रसोई ड्रॉवर से ली गई निम्नलिखित छवि पर नज़र डालें। क्रेडिट @ रूबर्ब जाता है।

frame का उपयोग करने से आप अपने superview दृश्य को पुनर्स्थापित और / या आकार बदल सकते हैं। आमतौर पर superview से उपयोग किया जा सकता है, उदाहरण के लिए, जब आप कोई विशिष्ट सबव्यूव बनाते हैं। उदाहरण के लिए:

// view1 will be positioned at x = 30, y = 20 starting the top left corner of [self view]
// [self view] could be the view managed by a UIViewController
UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 20.0f, 400.0f, 400.0f)];    
view1.backgroundColor = [UIColor redColor];

[[self view] addSubview:view1];

जब आपको एक view अंदर चित्रण करने के लिए निर्देशांक की आवश्यकता होती है तो आप आमतौर पर bounds संदर्भ लेते हैं। एक सामान्य उदाहरण एक view भीतर पहली बार एक इंसेट के रूप में आकर्षित करने के लिए किया जा सकता है। सबव्यूइंग को आकर्षित करने के लिए पर्यवेक्षण की bounds को जानना आवश्यक है। उदाहरण के लिए:

UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(50.0f, 50.0f, 400.0f, 400.0f)];    
view1.backgroundColor = [UIColor redColor];

UIView* view2 = [[UIView alloc] initWithFrame:CGRectInset(view1.bounds, 20.0f, 20.0f)];    
view2.backgroundColor = [UIColor yellowColor];

[view1 addSubview:view2];

जब आप किसी दृश्य की bounds बदलते हैं तो विभिन्न व्यवहार होते हैं। उदाहरण के लिए, यदि आप bounds size बदलते हैं, तो frame बदलता है (और इसके विपरीत)। परिवर्तन दृश्य के center के आसपास होता है। नीचे दिए गए कोड का प्रयोग करें और देखें कि क्या होता है:

NSLog(@"Old Frame %@", NSStringFromCGRect(view2.frame));
NSLog(@"Old Center %@", NSStringFromCGPoint(view2.center));    

CGRect frame = view2.bounds;
frame.size.height += 20.0f;
frame.size.width += 20.0f;
view2.bounds = frame;

NSLog(@"New Frame %@", NSStringFromCGRect(view2.frame));
NSLog(@"New Center %@", NSStringFromCGPoint(view2.center));

इसके अलावा, यदि आप bounds origin बदलते हैं तो आप इसकी आंतरिक समन्वय प्रणाली की origin को बदल देते origin । डिफ़ॉल्ट रूप से origin (0.0, 0.0) (शीर्ष बाएं कोने) पर है। उदाहरण के लिए, यदि आप view1 लिए origin बदलते हैं तो आप देख सकते हैं (अगर आप चाहते हैं तो पिछले कोड पर टिप्पणी करें) कि अब view2 लिए शीर्ष बाएं कोने view2 स्पर्श करता है। प्रेरणा काफी सरल है। आप 1 को view1 लिए कहते हैं कि इसका शीर्ष बाएं कोने अब स्थिति (20.0, 20.0) पर है (20.0, 20.0) लेकिन चूंकि view2 की frame origin (20.0, 20.0) से शुरू होती है, वे मिलेंगे।

CGRect frame = view1.bounds;
frame.origin.x += 20.0f;
frame.origin.y += 20.0f;
view1.bounds = frame; 

origin अपने superview भीतर view की स्थिति का प्रतिनिधित्व करती है लेकिन bounds केंद्र की स्थिति का वर्णन करती है।

अंत में, bounds और origin संबंधित अवधारणाएं नहीं हैं। दोनों दृश्य के frame को प्राप्त करने की अनुमति देते हैं (पिछले समीकरण देखें)।

व्यू 1 का केस स्टडी

निम्न स्निपेट का उपयोग करते समय क्या होता है।

UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 20.0f, 400.0f, 400.0f)];
view1.backgroundColor = [UIColor redColor];

[[self view] addSubview:view1];

NSLog(@"view1's frame is: %@", NSStringFromCGRect([view1 frame]));
NSLog(@"view1's bounds is: %@", NSStringFromCGRect([view1 bounds]));
NSLog(@"view1's center is: %@", NSStringFromCGPoint([view1 center]));

सापेक्ष छवि।

इसके बजाय यदि मैं निम्नलिखित की तरह [self view] सीमाओं को बदलता हूं तो क्या होता है।

// previous code here...
CGRect rect = [[self view] bounds];
rect.origin.x += 30.0f;
rect.origin.y += 20.0f;
[[self view] setBounds:rect];

सापेक्ष छवि।

यहां आप [self view] से कहते हैं कि इसका शीर्ष बाएं कोने अब स्थिति (30.0, 20.0) पर है, लेकिन चूंकि view1 की मूल उत्पत्ति (30.0, 20.0) से शुरू होती है, वे मिलेंगे।

अतिरिक्त संदर्भ (यदि आप चाहें तो अन्य संदर्भों के साथ अपडेट करने के लिए)

clipsToBounds बारे में clipsToBounds (स्रोत ऐप्पल डॉक्टर)

इस मान को YES पर सेट करने से सबव्यूस रिसीवर की सीमाओं पर चिपकने का कारण बनता है। यदि NO पर सेट किया गया है, तो जिनके फ्रेम रिसीवर की दृश्य सीमाओं से परे विस्तारित होते हैं वे क्लिप नहीं होते हैं। यह डिफ़ॉल्ट मान नहीं है।

दूसरे शब्दों में, यदि दृश्य का frame (0, 0, 100, 100) और इसका सबव्यूव (90, 90, 30, 30) , तो आप उस सबव्यूव का केवल एक हिस्सा देखेंगे। उत्तरार्द्ध माता-पिता के दृष्टिकोण की सीमा से अधिक नहीं होगा।

masksToBounds के बराबर है। एक UIView बजाय, यह संपत्ति एक CALayer लागू होती है। हुड के तहत, clipsToBounds कहते हैं। आगे के संदर्भों के लिए यूआईवीव के क्लिप टोबाउंड्स और कैलियर के मास्क टॉबाउंड्स के बीच संबंध कैसा है?


मुझे लगता है कि अगर आप इसे CALayer के बिंदु से सोचते हैं, तो सबकुछ अधिक स्पष्ट है।

फ़्रेम वास्तव में दृश्य या परत की एक विशिष्ट संपत्ति नहीं है, यह एक वर्चुअल प्रॉपर्टी है, जो सीमाओं, स्थिति ( UIView के केंद्र) से गणना की जाती है, और परिवर्तित होती है।

तो मूल रूप से परत / दृश्य लेआउट वास्तव में इन तीन संपत्ति (और एंकरपॉइंट) द्वारा तय किए जाते हैं, और इनमें से कोई भी तीन संपत्ति किसी भी अन्य संपत्ति को नहीं बदलेगी, जैसे परिवर्तन बदलने से सीमाएं नहीं बदलती हैं।


  • फ्रेम संपत्ति में फ्रेम आयताकार होता है, जो इसके पर्यवेक्षण के समन्वय प्रणाली में दृश्य के आकार और स्थान को निर्दिष्ट करता है।
  • सीमाओं की संपत्ति में सीमा आयताकार होता है, जो दृश्य के आकार (और इसकी सामग्री उत्पत्ति) के दृश्य को अपने स्थानीय समन्वय प्रणाली में निर्दिष्ट करता है।
  • केंद्र संपत्ति में पर्यवेक्षण के समन्वय प्रणाली में दृश्य का ज्ञात केंद्र बिंदु होता है।






bounds