9

के साथ मॉडलिंग व्यू को केंद्रित करना मैं एक फेसबुक पीओपी एनिमेटेड संक्रमण को लागू करने के प्रयास में वर्तमान दृश्य नियंत्रक और एक कस्टम मोडल प्रस्तुति स्टाइल का उपयोग कर एक UIViewController प्रस्तुत कर रहा हूं।ऑटोलायआउट

मोडल दृश्य पूरी तरह से गतिशील है, कोड में ऑटोलायआउट बाधाओं का उपयोग करके परिभाषित किया गया है। मोडल को वापस करने के लिए कोई xib/storyboard नहीं है।

मुझे स्क्रीन पर केंद्र के लिए मोडल दृश्य नहीं मिल सकता है! Autolayout पर्याप्त नहीं है, क्योंकि बाधाओं को जोड़ने के लिए कोई पर्यवेक्षण नहीं है!

मेरे पेश कोड इस (एक अमेरिकन प्लान पॉप कोड नमूना से लिया गया) की तरह दिखता है:

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext 
{ 
    UIView *fromView = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view; 
    fromView.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed; 
    fromView.userInteractionEnabled = NO; 

    UIView *dimmingView = [[UIView alloc] initWithFrame:fromView.bounds]; 
    dimmingView.backgroundColor = [UIColor colorWithRed:(24/255.0) green:(42/255.0) blue:(15/255.0) alpha:1.0]; 
    dimmingView.layer.opacity = 0.0; 

    UIView *toView = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view; 
    toView.frame = CGRectMake(0, 
           0, 
           CGRectGetWidth(transitionContext.containerView.bounds) - 104.f, 
           CGRectGetHeight(transitionContext.containerView.bounds) - 320.f); 
    toView.center = CGPointMake(transitionContext.containerView.center.x, -transitionContext.containerView.center.y); 

    [transitionContext.containerView addSubview:dimmingView]; 
    [transitionContext.containerView addSubview:toView]; 

    POPSpringAnimation *positionAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPositionY]; 
    positionAnimation.toValue = @(transitionContext.containerView.center.y); 
    positionAnimation.springBounciness = 10; 
    [positionAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { 
     [transitionContext completeTransition:YES]; 
    }]; 

    POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY]; 
    scaleAnimation.springBounciness = 20; 
    scaleAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(1.2, 1.4)]; 

    POPBasicAnimation *opacityAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerOpacity]; 
    opacityAnimation.toValue = @(0.2); 

    [toView.layer pop_addAnimation:positionAnimation forKey:@"positionAnimation"]; 
    [toView.layer pop_addAnimation:scaleAnimation forKey:@"scaleAnimation"]; 
    [dimmingView.layer pop_addAnimation:opacityAnimation forKey:@"opacityAnimation"]; 
} 

इस खूबसूरती से काम करता है, लेकिन मैं वास्तविक दृश्य आकार की जरूरत है गतिशील होने के लिए (कभी कभी मोडल होगा पाठ की चार पंक्तियां और दो बटन, आदि)। इसे पूरा करने के लिए, मुझे वीसी सबक्लास में अनुवादों को सेट करने की आवश्यकता है। AutoresizingMaskIntoConstraints = NO। यह स्पष्ट रूप से प्रस्तुति एनिमेटर में कर रहे फ्रेम केंद्र को अस्वीकार करता है।

अंतिम परिणाम एक मॉडल है जो स्क्रीन के बाएं किनारे पर फंस गया है; उत्सुकता से, यह लंबवत रूप से केंद्रित है, लेकिन क्षैतिज नहीं है। दिखने में, यह कुछ इस तरह दिखता (काले वर्गों क्षमा, मैं कानूनी प्रयोजनों के लिए करना था):

screesshot

स्पष्ट समाधान के लिए एक दृश्य बाधा दृश्य केन्द्रों कि जोड़ने के लिए किया जाएगा। कोई समस्या नहीं, है ना?

लेकिन मैं इसे कहां जोड़ूं? देखें। सुपरव्यू शून्य है; कोई पर्यवेक्षण नहीं है। मैंने कस्टम 'पर्यवेक्षण' प्रॉपर्टी बनाने और इसे सेट करने का प्रयास किया, लेकिन ऑटोलाउटआउट यह नहीं जानता कि दृश्य को पदानुक्रम (प्रस्तुत करने वाला वीसी) के बाहर एक दृश्य को कैसे संभाला जाए। यह मेरे विचार पदानुक्रम, कैसा दिखता एनोटेट है:

enter image description here

आप जाहिरा तौर पर सीधे UITransitionView उपयोग करने के लिए नहीं करना पड़ेगा। UIWindow पर बाधाओं का कोई प्रभाव नहीं पड़ता है।

क्या किसी के पास कोई सलाह है? आप इस तरह की चीज़ों को कैसे संभालेंगे?

+0

मैं वास्तव में के लिए समाधान की जरूरत नहीं है आप लेकिन मैं आपको बताता हूं कि मैं इस स्थिति में क्या करूँगा: ** किसी भी Autolayout ** पर टिप्पणी करें, ** सीजीआरईटीएमके के माध्यम से स्थिति सेट करें (**। एक और बात: जिस तरीके से आपने इस सवाल को संरचित किया है, यह कहने में मुश्किल है कि कहां समस्या है। शुभकामनाएं। – carlodurso

+0

यह कैच -22 है। मुझे ऑटो लेआउट का उपयोग करने की आवश्यकता है, क्योंकि दृश्य को पूरी तरह से गतिशील होना चाहिए। – cdstamper

उत्तर

3

आप प्रोग्राम के रूप में कर सकते हैं अपने एनिमेट में कंटेनर व्यू से टूव्यू में एक केंद्रित बाधा जोड़ें ट्रांज़िशन विधि:

(स्विफ्ट में, लेकिन आपको विचार प्राप्त करने में सक्षम होना चाहिए ...)

containerView.addSubview(toView) 

let centerXLayoutConstraint = NSLayoutConstraint(item: toView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: containerView, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0) 
let centerYLayoutConstraint = NSLayoutConstraint(item: toView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: containerView, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0) 

containerView.addConstraint(centerXLayoutConstraint) 
containerView.addConstraint(centerYLayoutConstraint) 

जब मैंने कोशिश की, तो मैंने कंटेनर व्यू के सापेक्ष आकार के लिए चौड़ाई और ऊंचाई की बाधाओं को भी जोड़ा। यह काम किया - कोई समस्या नहीं है।

मुझे लगता है कि इसे स्वयं के आकार में देखने के साथ भी काम करना चाहिए। आपको अपने टूव्यू क्लास में आंतरिक आकार को ओवरराइड करना पड़ सकता है और/या इसके बाधाओं को अपडेट करने के लिए इसे मजबूर करने के साथ खेलना पड़ सकता है।

+0

बिल्कुल काम करता है। मैं थोड़ा चिंतित हूं कि मुझे सीधे कंटेनर व्यू तक पहुंचने की अनुमति नहीं है ... लेकिन यह अभी के लिए एक समाधान है। धन्यवाद! – cdstamper

+0

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

+0

यह काम करता है, मैं जमा करने वाला हूं और देखता हूं कि क्या होता है। अगर इसे खारिज कर दिया जाता है तो मैं कुछ महीनों में अपडेट करूंगा! – cdstamper

2

क्या आप इसे आजमा सकते हैं?

UIView के उप-वर्ग के रूप में अपने मोडल विंडो दृश्य को घोषित करें, और didMoveToSuperView लागू करें।

- (void)didMoveToSuperview { 
    UIView *superView = self.superview; 

    if(superView == nil) { 
     return; 
    } 

    [superView addConstraint:[NSLayoutConstraint constraintWithItem:self 
                  attribute:NSLayoutAttributeCenterX 
                  relatedBy:NSLayoutRelationEqual 
                  toItem:superView 
                  attribute:NSLayoutAttributeCenterX 
                 multiplier:1.0 
                  constant:0]]; 
    [superView addConstraint:[NSLayoutConstraint constraintWithItem:self 
                  attribute:NSLayoutAttributeCenterY 
                  relatedBy:NSLayoutRelationEqual 
                  toItem:superView 
                  attribute:NSLayoutAttributeCenterY 
                 multiplier:1.0 
                  constant:0]]; 

    // [superView layoutIfNeeded]; // If this does not work, try uncomment this. 
} 

यह स्वतः ही केंद्रित करना चाहिए जब किसी भी superview में जोड़ा।

कहने के लिए सुई, आपको translatesAutoresizingMaskIntoConstraints = NO और किसी चौड़ाई/ऊंचाई की बाधाओं की भी आवश्यकता है।

मैंने UITransitionView के साथ परीक्षण नहीं किया है, हालांकि। शायद यह positionAnimation के साथ यह संघर्ष।

संपादित करें: 2014/09/22

इसके बजाय autolayout की कमी का उपयोग कर दृश्य खुद मोडल के

, मुझे लगता है कि आपtranslatesAutoresizingMaskIntoConstraints = NO बिना systemLayoutSizeFittingSize: विधि उपयोग करना चाहिए।

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext 
{ 
    // ...snip 

    UIView *toView = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view; 

    toView.translatesAutoresizingMaskIntoConstraints = YES; // To clarify. You don't need this line because this is the default. 

    CGSize sysSize = [toView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; 
    toView.bounds = CGRectMake(0, 0, sysSize.width, sysSize.height); 
    toView.center = CGPointMake(transitionContext.containerView.center.x, -transitionContext.containerView.center.y); 
    toView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin; 

    // ...snip 

} 

और आप मोडल दृश्य आकार बदलने प्रदर्शन के बाद (संशोधित करने से यह सामग्री दी गई है का एक पक्ष प्रभाव के रूप में) चाहते हैं, अपने मोडल विचारों में कोड निम्नलिखित की तरह UIViewController उपवर्ग कार्य करें:

- (void)yourAppMethod { 
    NSString *message = @""; // <- as u like 
    UILabel *label = self.messageLabel; 
    label.text = message; 
    [self resizeViewIfNeeded]; // <- this will resize self.view 
} 

- (void)resizeViewIfNeeded { 
    CGSize sysSize = [self.view systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; 
    if(!CGSizeEqualToSize(sysSize, self.view.bounds.size)) { 
     self.view.bounds = CGRectMake(0, 0, sysSize.width, sysSize.height); 
    } 
} 
+0

मैं UIView सबक्लास में नहीं बदल सकता, इसे एक वीसी होना चाहिए । Transitioncontext कंटेनर दृश्य पर बाधाओं को सेट करने से चाल चल रही थी! सुझावों के लिए धन्यवाद। – cdstamper

0

animateTransition में: एक बार आप पदानुक्रम करने के लिए अपने विचारों को जोड़ने आप की तरह [आत्म addConstraints] एक निजी विधि कॉल कर सकते हैं और फिर कुछ इस तरह करते हैं:

- (void)addConstraints 
    { 
     [self.toView setTranslatesAutoresizingMaskIntoConstraints:NO]; 
     [self.dimmingView setTranslatesAutoresizingMaskIntoConstraints:NO]; 

     [self.containerView addConstraint:[NSLayoutConstraint constraintWithItem:self.toView 
                     attribute:NSLayoutAttributeCenterX 
                     relatedBy:NSLayoutRelationEqual 
                      toItem:self.containerView 
                     attribute:NSLayoutAttributeCenterX 
                     multiplier:1 
                     constant:0]]; 
     [self.containerView addConstraint:[NSLayoutConstraint constraintWithItem:self.toView 
                     attribute:NSLayoutAttributeCenterY 
                     relatedBy:NSLayoutRelationEqual 
                      toItem:self.containerView 
                     attribute:NSLayoutAttributeCenterY 
                     multiplier:1 
                     constant:0]]; 
     NSDictionary *views = @{@"dimmingView" : self.dimmingView}; 
     [self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[dimmingView]|" 
                        options:0 
                        metrics:nil 
                        views:views]]; 
     [self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[dimmingView]|" 
                        options:0 
                        metrics:nil 
                        views:views]]; 
} 
संबंधित मुद्दे