2012-02-29 16 views
14

मैं अपने अनुप्रयोगों में से एक के लिए एक ऑटोलायआउट-अनुकूल स्प्लिट व्यू क्लास बना रहा हूं। इसकी विभिन्न विशेषताओं में से यह है कि यह पैन को ध्वस्त कर सकता है, और उनके पतन को एनिमेट कर सकता है, जैसा कि आपने NSSplitView को देखा होगा।NSLayoutConstraint.constant एनीमेशन को अनदेखा कर रहा है

जब से मैं बाधाओं उपयोग कर रहा हूँ, मैं फलक पर एक आवश्यक चौड़ाई = (वर्तमान चौड़ाई) बाधा डाल रहा है, और फिर सेट करके ऐसा कर रहा हूँ प्राप्त करने बाधा के 0 के लिए निरंतर एक एनिमेटेड फैशन में:

- (NSLayoutConstraint*)newHiddenConstraintAnimated:(BOOL)animated { 
    NSLayoutConstraint * constraint = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:NSWidth(self.view.frame)]; 
    constraint.priority = NSLayoutPriorityRequired; 

    CABasicAnimation * anim = [CABasicAnimation animation]; 
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 
    anim.duration = 0.2; 
    constraint.animations = [NSDictionary dictionaryWithObject:anim forKey:@"constant"]; 

    [self.view addConstraint:constraint]; 

    [(animated ? constraint.animator : constraint) setConstant:0.0]; 

    return constraint; 
} 

यह खूबसूरती से काम करता है। दुर्भाग्यवश, बाद में फलक का विस्तार करना इतना अच्छा किराया नहीं है।

- (void)removeHiddenConstraintAnimated:(BOOL)animated { 
    if(!animated) { 
     [self.view removeConstraint:self.hiddenConstraint]; 
    } 
    else { 
     NSLayoutConstraint * constraint = self.hiddenConstraint; 
     NSView * theView = self.view; 

     [NSAnimationContext beginGrouping]; 

     [constraint.animator setConstant:self.width]; 

     [NSAnimationContext currentContext].completionHandler = ^{ 
      [theView removeConstraint:constraint]; 
     }; 

     [NSAnimationContext endGrouping]; 
    } 

    self.hiddenConstraint = nil; 
} 

अगर मैं कुछ समय कोड डालने, मैं देख सकता है कि पूरा होने हैंडलर लगभग तुरंत आग, बाधा को हटाने से पहले यह चेतन करने के लिए समय है। NSAnimationContext पर एक अवधि निर्धारित करने से कोई प्रभाव नहीं पड़ता है।

कोई विचार क्या मैं यहां गलत कर सकता हूं?

+0

क्या आपने कभी इस स्प्लिट व्यू क्लास को समाप्त किया था? ओपन-सोर्स जा रहा है इसकी संभावना? –

+0

मैं इस समय की योजना नहीं बना रहा हूं। यह इस एप्लिकेशन के लिए काफी विशिष्ट है, और मेरा मानना ​​है कि [PURRDACTED] में 'NSSplitView' को ऑटोलायआउट के साथ बेहतर काम करने के लिए फिर से डिजाइन किया गया है। –

+0

ओह, गॉचा। [Redacted] के संबंध में, ऑटो लेआउट के संबंध में यह अच्छी सुविधा है, लेकिन निश्चित रूप से यह पुराने लक्ष्य के साथ पिछड़ा नहीं है। ओह ठीक है, मैं अपना खुद का अनुमान लगाऊंगा! :) –

उत्तर

15

आपके पास पहले पूरा होने हैंडलर स्थापित करने के लिए और उसके बाद ही करने के लिए संदेश भेजने एनिमेटर प्रॉक्सी। अन्यथा, ऐसा लगता है कि एनीमेशन शुरू होने के बाद पूरा होने वाले हैंडलर को तुरंत चालू कर दिया जाता है और एनीमेशन के समय समाप्त होने से पहले निरंतर हटा दिया जाता है। मैं सिर्फ सरल कोड का एक टुकड़ा के साथ इस जाँच की है:

[NSAnimationContext beginGrouping]; 
    NSAnimationContext.currentContext.duration = animagionDuration; 
    NSAnimationContext.currentContext.completionHandler = ^{[self removeConstraint:collapseConstraint];}; 
    [collapseConstraint.animator setConstant:expandedHeight]; 
    [NSAnimationContext endGrouping]; 

यह पूरी तरह से काम करता है, लेकिन अगर आप -setConstant: के बाद पूरा होने हैंडलर निर्धारित करते हैं, एनीमेशन चलाने के लिए एक मौका नहीं है।

+0

वाह, वास्तव में काम किया। पारितोषिक के लिए धन्यवाद! –

+0

बिलकुल नहीं, कुछ समय पहले मैंने एक ही मुद्दा मारा, और यह आपका प्रश्न था जिसने मुझे प्रयोग करने का नेतृत्व किया :) – skh

1

मैं सिर्फ इस सामग्री के साथ पकड़ के हो रही है अपने आप को तो यह एक अनुभवहीन विश्लेषण हो सकता है लेकिन:

मुझे ऐसा लगता है कि आप निर्दिष्ट करते हैं कि बाधाओं 'के गुणों पर एक एनीमेशन (अपने किसी और ब्लॉक में) लेकिन, फिर, एनीमेशन को चलाने का मौका देने से पहले, तुरंत बाध्यता (इसे संभावित रूप से रिलीज़ करने) के संदर्भ को तुरंत सेट करना।

मुझे उम्मीद है कि आप एनीमेशन पूर्णता ब्लॉक के भीतर से छिपाने के लिए, या ट्रिगर किए गए कॉन्स्ट्रेंस को सेट करना चाहते हैं।

ध्यान दें कि अगर, के रूप में होने की संभावना है, मैं गलत हूँ मैं बेहतर :)

+0

यह मानना ​​उचित है कि किसी दृश्य में आपके द्वारा जोड़े गए किसी भी बाधा का स्वामित्व है, इसलिए यदि बाधा को 'छुपे हुए कॉन्स्ट्रेन' संपत्ति के माध्यम से संदर्भित नहीं किया गया है, तो इसे अभी भी बाधाओं की दृश्य सूची द्वारा संदर्भित किया जाना चाहिए। इसे ब्लॉक द्वारा भी जीवित रखा जाता है, क्योंकि ब्लॉक उन ऑब्जेक्ट वेरिएबल्स के मानों को बनाए रखते हैं जिन्हें आप उपयोग करते हैं। –

+0

जैसा कि पीटर ने कहा था, 'बाधा' एक मजबूत संदर्भ है और ब्लॉक द्वारा कब्जा कर लिया गया है, और यहां तक ​​कि यदि दृश्य नहीं था तो यह बाधा बरकरार रखेगी। एक मामूली जटिल ऑटोलायआउट में सैकड़ों बाधाएं हैं, और विशाल बहुमत केवल उनके विचारों के संदर्भ में संदर्भित हैं। –

+0

दयालु उत्तर दोस्तों के लिए धन्यवाद। –

3

पूरा होने हैंडलर तुरंत फायरिंग, क्योंकि यह सोचता है कि है वहाँ नहीं किसी भी कर रहे हैं एक शब्द या दो क्यों मुझे यह समझने में मदद करने के बारे में जानना चाहेंगे एनिमेशन जो चलाने की जरूरत है। मैं जांचता हूं और पुष्टि करता हूं कि आपके द्वारा बनाई गई एनीमेशन अभी भी दृश्य से जुड़ी हुई है। डिफ़ॉल्ट रूप से CABasicAnimation को हटाए गए ओन कॉम्प्लेशन प्रॉपर्टी के माध्यम से पूरा होने पर खुद को हटाने के लिए सेट किया जाता है जो इसे CAAnimation से प्राप्त होता है (जो डिफ़ॉल्ट रूप से YES पर सेट होता है)।

आप चाहता हूँ

anim.removedOnCompletion = NO; 
+0

'anim.removedOnCompletion = NO;' को जोड़ना कोई प्रभाव नहीं है। अच्छा सुझाव, यद्यपि। –

12

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

मैं बजाय NSAnimationContext वर्ग विधि +runAnimationGroup:completionHandler: का उपयोग कर beginGrouping और endGrouping बयानों के द्वारा काम करने के लिए इसे पाने के लिए कर रहा था:

[NSAnimationContext runAnimationGroup:^(NSAnimationContext* context){ 
    [constraint.animator setConstant:self.width]; 
} completionHandler:^(void){ 
    [theView removeConstraint:constraint]; 
    NSLog(@"completed"); 
}]; 
+0

हां, ऐसा लगता है कि मेरे कोड पर कोई प्रभाव नहीं पड़ा है। मैं शायद एक रडार फाइल करेंगे, हालांकि; यह निश्चित रूप से ऐसा लगता है जैसे इसे काम करना चाहिए। –

+0

यह अजीब है। यह निश्चित रूप से ठीक काम करता है। –

+0

मेरे लिए भी काम किया। – stevex

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