34

मैं अपने ऐप के भीतर एक springboard-like इंटरफेस बनाने की कोशिश कर रहा हूं। मैं UIScrollView में जोड़े गए UIButtons का उपयोग करने का प्रयास कर रहा हूं। जिस समस्या में मैं चल रहा हूं वह बटन है जो UIScrollView पर किसी भी स्पर्श को पार नहीं कर रहा है - अगर मैं फ्लिक/स्लाइड करने की कोशिश करता हूं और बटन पर प्रेस करने के लिए होता हूं तो यह UIScrollView के लिए पंजीकरण नहीं करता है, लेकिन अगर मैं बीच की जगह फ्लिक करता हूं बटन यह काम करेगा। यदि मैं उन्हें स्पर्श करता हूं तो बटन क्लिक/काम करते हैं।UIButtons के साथ UIScrollview - springboard को फिर से बनाने के लिए कैसे?

क्या कोई ऐसी संपत्ति या सेटिंग है जो बटन को अपने माता-पिता (पर्यवेक्षण) तक स्पर्श ईवेंट भेजने के लिए बाध्य करती है? UIScrollView जोड़ने से पहले बटन को किसी अन्य चीज़ में जोड़ने की आवश्यकता है?

//init scrolling area 
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 480, 480)]; 
scrollView.contentSize = CGSizeMake(480, 1000); 
scrollView.bounces = NO; 
scrollView.delaysContentTouches = NO; 

//create background image 
UIImageView *rowsBackground = [[UIImageView alloc] initWithImage:[self scaleAndRotateImage:[UIImage imageNamed:@"mylongbackground.png"]]]; 
rowsBackground.userInteractionEnabled = YES; 

//create button 
UIButton *btn = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; 
btn.frame = CGRectMake(100, 850, 150, 150); 
btn.bounds = CGRectMake(0, 0, 150.0, 150.0); 
[btn setImage:[self scaleAndRotateImage:[UIImage imageNamed:@"basicbutton.png"]] forState:UIControlStateNormal]; 
[btn addTarget:self action:@selector(buttonClick) forControlEvents:UIControlEventTouchUpInside]; 

//add "stuff" to scrolling area 
[scrollView addSubview:rowsBackground]; 
[scrollView addSubview:btn]; 

//add scrolling area to cocos2d 
//this is just a UIWindow 
[[[Director sharedDirector] openGLView] addSubview:scrollView]; 

//mem-mgmt 
[rowsBackground release]; 
[btn release]; 
[scrollView release]; 
+0

यह ध्यान देने योग्य है कि, भले ही एप्पल से पहले अनुमति दी गई है, '10.4' ' एप्लिकेशन जो वैकल्पिक डेस्कटॉप/होम स्क्रीन वातावरण बना सकते हैं या बहु अनुप्रयोग विजेट अनुभवों अनुकरण rejected' कर दिया जाएगा। बस कुछ नए आने वाले एक ऐसे उत्पादन ऐप को शिप करने की योजना बना रहे थे जिसकी अपनी स्प्रिंगबोर्ड है। – user

उत्तर

28

UIScrollView के लिए अपने सामग्री दृश्य (ओं) और एक स्पर्श जो स्वाइप या चुटकी में बदलता है, के बीच अंतर निर्धारित करने के लिए, इसे स्पर्श में देरी की आवश्यकता है और देखें कि आपकी उंगली कब चल रही है या नहीं देरी अपने उपरोक्त उदाहरण में delaysContentTouchesNO पर सेट करके, आप इसे होने से रोक रहे हैं। इसलिए, स्क्रॉल व्यू हमेशा बटन को स्पर्श करने के बजाय, इसे रद्द करने के बजाए, जब यह पता चला कि उपयोगकर्ता स्वाइप इशारा कर रहा है। delaysContentTouches को YES पर सेट करने का प्रयास करें।

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

+3

देरी करने के साथ एक संभावित समस्या सामग्री टच यह है कि बटन को हाइलाइट करने से पहले देरी होगी। नीचे रोमन के का जवाब आपको कोई देरी नहीं देगा, लेकिन फिर भी बटन दबाए जाने के बाद स्क्रॉल करने में सक्षम हो जाएगा। – GhostM

+0

संरचना सलाह बहुत बढ़िया है लेकिन मुझे इसमें दिलचस्पी होगी। धन्यवाद। –

1

UIScrollView घटनाओं खुद का एक बहुत संभालती है:

यहाँ मेरी कोड है। आपको UIScrollView मैन्युअल रूप से बटन के लिए स्पर्शों को हिट करने और परीक्षण करने की आवश्यकता है।

0

एक और तरीका है:
1. एक साधारण कस्टम UIView
द्वारा डी बटन को प्रतिस्थापित करें 2. ध्वज "userInterationEnable = yes;" इनिट विधि
पर 3. दृश्य में यूआईआरस्पेन्डर विधि को "छूने वाला" यहां ओवरराइड करें, आप उस बटन को ट्रिगर कर सकते हैं जिसकी आपको आवश्यकता है।

0

मेरे अनुभव में पहला जवाब, यानी, बस delaysContentTouchesYES पर सेट करना, समस्या के संबंध में कुछ भी नहीं बदलता है। बटन अभी भी स्क्रॉल व्यू पर ट्रैकिंग परिणाम वितरित नहीं करेंगे। तीसरा जवाब सरल और बहुत उपयोगी दोनों है। धन्यवाद sieroaoj!

हालांकि, काम के तीसरे उत्तर के लिए आपको delaysContentTouchesYES पर भी सेट करने की आवश्यकता है। अन्यथा विधि touchesEnded को दृश्य में ट्रैकिंग के लिए भी बुलाया जाएगा। एक साधारण कस्टम UIView

  • द्वारा

    1. स्थानापन्न डी बटन झंडा रखो "userInterationEnable = हाँ,": इसलिए मैं द्वारा समस्या का समाधान कर सकता है init विधि
    2. दृश्य UIResponder विधि ओवरराइड में पर "touchesEnded" यहाँ आप कार्रवाई आप

    चौथा को गति प्रदान कर सकते हैं।

    उपवर्ग UIButton: यहां सेट delaysContentTouchesYES

  • +0

    देरी सामग्री टच = डिफ़ॉल्ट रूप से हाँ। – Andy

    1

    करने के लिए ठीक अपने जवाब है। (नोट: प्रत्येक ओवरराइड की शुरुआत में [सुपर ....] कॉल करें।

    • एक संपत्ति जोड़ें। प्रकार BOOL (जिसे सक्षमToRestore कहा जाता है)
    • एक संपत्ति जोड़ें। प्रकार CGPoint में से एक (startTouchPosition कहा जाता है)
    • awakeFromNib और initWithFrame में
    • , IsEnabled संपत्ति)
    • अवहेलना करने के लिए enableToRestore सेट "touchesBegan: withEvent:" स्पर्श स्थिति के शुरू होने से स्टोर करने के लिए।
    • ओवरराइड "स्पर्श: हटाया गया: सेव:" यह देखने के लिए जांचें कि क्षैतिज आंदोलन है या नहीं।
    • यदि हां, तो NO और को कोई भी सेट करने के लिए सक्षम सेट करें।

    नमूना कोड:

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
    { 
        UITouch *touch = [touches anyObject]; 
    
        [super touchesBegan:touches withEvent:event]; 
        [self setStartTouchPosition:[touch locationInView:self]]; 
    } 
    
    
    // 
    // Helper Function 
    // 
    - (BOOL)isTouchMovingHorizontally:(UITouch *)touch 
    { 
        CGPoint currentTouchPosition = [touch locationInView:self]; 
        BOOL  rValue = NO; 
    
        if (fabsf([self startTouchPosition].x - currentTouchPosition.x) >= 2.0) 
        { 
         rValue = YES; 
        } 
    
        return (rValue); 
    } 
    
    // 
    // This is called when the finger is moved. If the result is a left or right 
    // movement, the button will disable resulting in the UIScrollView being the 
    // next responder. The parrent ScrollView will then re-enable the button 
    // when the finger event is ended of cancelled. 
    // 
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
    { 
        [super touchesMoved:touches withEvent:event]; 
        if ([self isTouchMovingHorizontally:[touches anyObject]]) 
        { 
         [self setEnabled:NO]; 
         [self setSelected:NO]; 
        } 
    } 
    

    यह UIScrollView सक्रिय कर देंगे।

    सबक्लास UIScrollView। (नोट: प्रत्येक ओवरराइड के शुरू में फोन [सुपर ....]

    • अवहेलना दोनों "touchesEnded: withEvent:"। और "touchesCancelled: withEvent:"
    • ओवरराइड, सभी subviews रीसेट (और उनके subviews) ध्वज सक्षम
    • नोट:। एक श्रेणी का उपयोग करें और UIView करने के लिए पद्धति जोड़ें:।

    - (void) restoreAllEnables 
    { 
        NSArray *views = [self subviews]; 
    
        for (UIView *aView in views) 
        { 
         if ([aView respondsToSelector:@selector(restoreEnable)]) 
         { 
          [aView restoreEnable]; 
         } 
        } 
    } 
    
    - (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
    { 
        [super touchesEnded:touches withEvent:event]; 
        [self restoreAllEnables]; 
    } 
    
    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 
    { 
        [super touchesEnded:touches withEvent:event]; 
        [self restoreAllEnables]; 
    } 
    
    • श्रेणी में:

    -(void) restoreEnable 
    { 
        NSArray *views = [self subviews]; 
    
        if ([self respondsToSelector:@selector(enableToRestore)]) 
        { 
         [self setEnabled:[self enableToRestore]]; 
        } 
    
        for (UIView *aView in views) 
        { 
         if ([aView respondsToSelector:@selector(restoreEnable)]) 
         { 
          [aView restoreEnable]; 
         } 
        } 
    } 
    

    संपादित नोट: मैं कभी नहीं मिला है काम करने के लिए 3 के उत्तर दें। इसी तरह: setDelaysContentTouches: NO (दृश्य नियंत्रक या किसी स्थान पर सेट) को उत्तर 4 पर सर्वोत्तम परिणामों के लिए सेट किया जाना है। यह बटनों को बहुत तेज प्रतिक्रिया प्रदान करता है। सेटडेलेकंटेंट टच सेट करना: हाँ बटन पर प्रतिक्रिया समय पर गंभीर प्रभाव डालता है (150 मिमी) और प्रकाश बनाता है, तेज़ स्पर्श संभव नहीं है।

    5

    मेरे पास एक समान मामला है जो UIScrollView पर कई बटन हैं, और मैं इन बटनों को स्क्रॉल करना चाहता हूं। शुरुआत में, मैंने UIScrollView और UIButton दोनों को उप-वर्गीकृत किया। हालांकि, मैंने देखा है कि मेरे उप-वर्गीकृत UIScrollView को स्पर्श किया गया ईवेंट नहीं मिला, इसलिए मैं केवल उप-वर्ग UIButton में बदल गया।

    
    @interface MyPhotoButton : UIButton { 
    } 
    
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; 
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; 
    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; 
    @end 
    
    
    @implementation MyPhotoButton 
    
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
        [super touchesMoved:touches withEvent:event]; 
        [self setEnabled:NO]; 
        [self setSelected:NO]; 
    } 
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
        [super touchesEnded:touches withEvent:event]; 
        [self setEnabled:YES]; 
    } 
    
    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { 
        [super touchesCancelled:touches withEvent:event]; 
        [self setEnabled:YES]; 
    } 
    
    @end 
    
    +0

    यह समाधान मेरे लिए पूरी तरह से काम किया। – GroovyCarrot

    44

    समाधान है कि मेरे लिए काम किया शामिल:

    1. YES करने के लिए UIScrollView में canCancelContentTouches स्थापना।
    2. touchesShouldCancelInContentView:(UIView *)view को YES पर वापस करने के लिए ओवरराइड करने के लिए UIButton है। ।

    उन संदेशों को प्राप्त करने touchesShouldCancelInContentView रिटर्न "YES प्रलेखन के अनुसार देखने पर, NO देखने के लिए आगे स्पर्श संदेशों को रद्द करने के जारी रखने के डिफ़ॉल्ट मान YES है अगर दृश्य एक UIControl वस्तु नहीं है, अन्यथा यह रिटर्न NO । "

    UIButtonUIControlcanCancelContentTouches प्राप्त करने के लिए विस्तार आवश्यक है जो स्क्रॉलिंग को सक्षम बनाता है।

    +8

    बहुत बहुत धन्यवाद! स्पष्टीकरण के लिए, यह सबसे अच्छा काम करता है जब DelaysContentTouches = NO। – Schrockwell

    +7

    यह जाने का रास्ता है! (कम से कम आईओएस 4+ के लिए) मैंने पाया कि यह इस तरह ओवरराइड करने के लिए सबसे बहुमुखी है: '- (BOOL) स्पर्श करता है ShouldCancelInContentView: (UIView *) देखें { वापसी! [देखें isKindOfClass: [UISlider क्लास]]; } ' –

    +0

    अभी भी आईओएस 7 में पूरी तरह से काम कर रहा है। बहुत बहुत धन्यवाद !! – RyanG

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