2013-10-13 7 views
12

मुझे वर्तमान में एक कठिन समय समझ रहा है कि निम्नलिखित इकाई परीक्षण आईपैड 2 पर क्यों विफल रहता है। ऑटो लेआउट थोड़ा लगता है (द्वारा 0.5 अंक) दो लेआउट बाधाओं के लिए आवश्यक सटीक केंद्र के सापेक्ष superview के अंदर गलत स्थिति view। विशेष रूप से अजीब लगता है कि महत्वपूर्ण परीक्षण (लेकिन अंतिम दावा) एक आईफोन 5 पर गुजरता है, इसलिए स्पष्ट गोल त्रुटि केवल एक (आईओएस 6) मंच को प्रभावित करती है। यहाँ क्या चल रहा है?आईओएस ऑटो लेआउट प्री-रेटिना डिस्प्ले (यूनिट टेस्ट शामिल) पर स्पष्ट गोल करने वाली त्रुटियों का कारण क्यों बनता है

UPDATE 1 मैं कोड के रूप में एक संभवतः संबंधित उपाय here के रूप में सुझाव बदल दिया है यह सुनिश्चित करें कि कि दोनों फ्रेम पर्याप्त चौड़ाई और ऊंचाई के मामले में विवश कर रहे हैं, भले ही translatesAutoresizingMaskIntoConstraintsNO है। हालांकि, यह स्पष्ट रूप से स्थिति में बदलाव नहीं करता है।

#import "BugTests.h" 

@implementation BugTests 

- (void)testCenteredLayout { 
    UIView *superview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 768, 88)]; 
    superview.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; 
    superview.translatesAutoresizingMaskIntoConstraints = YES; 

    UILabel *view = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; 
    view.text = @"Single Round against iPad."; 
    view.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; 
    view.translatesAutoresizingMaskIntoConstraints = NO; 
    [view addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:206.0]]; 
    [view addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant: 21.0]]; 

    [superview addSubview:view]; 

    [superview addConstraint:[NSLayoutConstraint constraintWithItem:superview attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]]; 
    [superview addConstraint:[NSLayoutConstraint constraintWithItem:superview attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]]; 

    STAssertEquals(superview.center, CGPointMake(384, 44), nil); // succeeds 
    STAssertEquals(view.center,  CGPointMake( 0, 0), nil); // succeeds 

    [superview setNeedsLayout]; 
    [superview layoutIfNeeded]; 

    STAssertTrue(!superview.hasAmbiguousLayout, nil); 

    STAssertEquals(superview.frame.size, CGSizeMake(768, 88), nil); // succeeds 
    STAssertEquals(view.frame.size,  CGSizeMake(206, 21), nil); // succeeds 

    STAssertEquals(superview.center, CGPointMake(384, 44), nil); // succeeds 

    STAssertEquals(superview.center, view.center,   nil); // fails: why? 
    STAssertEquals(view.center,  CGPointMake(384, 44.5), nil); // succeeds: why? 
} 

@end 

अद्यतन 2 मैं एक दूसरी इकाई परीक्षण में (जाहिरा तौर पर) एक ही समस्या का एक और उदाहरण पृथक कर दिया है। इस बार इसमें एक शीर्ष (केंद्र नहीं) बाधा शामिल है, और इस बार एक अंशकालिक बिंदु समन्वय ट्रिगर लगता है। (परीक्षण प्री-रेटिना उपकरणों पर भी सफल होता है जैसे y = 951, यानी एक विषम बिंदु समन्वय।) मैंने विभिन्न सिम्युलेटर कॉन्फ़िगरेशन (मेरे भौतिक आईपैड 2 और आईफोन 5 के बगल में) में जांच की है, वास्तव में एक रतिना की अनुपस्थिति से जुड़ा हुआ लगता है प्रदर्शन। (फिर से, लीड के लिए @ अर्कदीसज़ होल्को का धन्यवाद।)

इन परीक्षणों से मेरा वर्तमान अर्थ यह है कि अगर प्री-रेटिना डिस्प्ले पर पॉइंट-सटीक ऑटो लेआउट की आवश्यकता होती है तो उसे विषम ऊंचाई और fractional y-coordinates से बचना होगा। पर क्यों?

- (void)testNonRetinaAutoLayoutProblem2 { 
    UIView *superview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 768, 1004)]; 
    superview.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; 
    superview.translatesAutoresizingMaskIntoConstraints = YES; 

    CGFloat y = 950.5; // see e.g. pageControlTopConstraint 

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; 
    view.translatesAutoresizingMaskIntoConstraints = NO; 
    [superview addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeLeading  multiplier:1.0 constant:0.0]]; 
    [superview addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeTrailing  multiplier:1.0 constant:0.0]]; 
    [superview addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop  relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeTop   multiplier:1.0 constant:y]]; 
    [superview addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil  attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:8]]; 

    [superview addSubview:view]; 

    [superview setNeedsLayout]; 
    [superview layoutIfNeeded]; 

    STAssertTrue(!superview.hasAmbiguousLayout, nil); 
    STAssertTrue(!view.hasAmbiguousLayout,  nil); 

    STAssertEquals(superview.frame, CGRectMake(0, 0,  768, 1004), nil); // succeeds 
    STAssertEquals(view.frame,  CGRectMake(0, y,  768, 8), nil); // fails: why? 
    STAssertEquals(view.frame,  CGRectMake(0, y + 0.5, 768, 8), nil); // succeeds: why? 
} 
+0

यह केवल पर होता है आईओएस 6 पर आईपैड 2? –

+0

@ArkadiuszHolko यह समस्या आईपैड 2 पर आईओएस 6.1.3 चल रही है। यह आईओएस 6.1.4 पर चल रहे आईफोन 5 पर दिखाई नहीं देता है। ये नवीनतम आईओएस 6 रिलीज हैं। मुझे वर्तमान में आईओएस 7 पर परीक्षण करने का साधन नहीं मिला है। मैं और क्या कोशिश कर सकता हूं? – Drux

+1

क्या आप देख सकते हैं कि जब आप 'व्यू' की ऊंचाई 21 से 22 तक बदलते हैं तो क्या होता है? क्या परिणाम आईफोन और आईपैड के बीच अब सुसंगत हैं? आईपैड में रेटिना डिस्प्ले नहीं है, जिससे अंतर हो सकता है। –

उत्तर

11

जो आपने दिखाया है वह है कि ऑटोलायआउट गलत तरीके से विचारों का पालन करता है। गैर-रेटिना उपकरणों पर निकटतम पिक्सेल निकटतम बिंदु है, इसलिए यह पूरे नंबर तक चलता है। रेटिना स्क्रीन पर निकटतम पिक्सेल निकटतम आधा बिंदु है, इसलिए यह निकटतम तक चलता है .5। आप इसे अपने दूसरे टेस्ट में 950.25 पर बदलकर और उस दृश्य को ध्यान में रखते हुए प्रदर्शित कर सकते हैं। फ्रेम {{0, 950.5}, {768, 8}} बनी हुई है ({{0, 950.25}, {768, 8} में बदलने के बजाय })।

(बस साबित होता है कि यह गोलाई है और न ceil आईएनजी, यदि आप y बदलने के लिए 950.2 view.frame हो जाता है {{0, 950} {768, 8}}।)

+0

तो एक अंतर्निहित बाधा जिससे विचारों को पूरी पिक्सेल निर्देशांक में संरेखित करना चाहिए, सभी स्पष्ट बाधाओं की तुलना में उच्च प्राथमिकता है, मुझे लगता है ... – Drux

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