दिलचस्प पोस्ट
JavaScript में URL को पार्स करें क्या मेरे iPhone आवेदन को रिवर्स-इंजिनियर करना संभव है? सी # दो सामान्य मान जोड़ना स्विफ्ट – एन्कोड यूआरएल Android में कर्ल का उपयोग करना एंड्रॉइड रनटाइम एक्सपैशन: सेवा को इन्स्तांत करने में असमर्थ Android – सरणी का उपयोग करने के लिए स्पिनर को कॉन्फ़िगर करें यह स्ट्रिंग सी कोड है जिसके कारण एक विभाजन त्रुटि है? PHP में मेल इंजेक्शन की उचित रोकथाम अपने आप को एक वेक्टर संलग्न करने का अच्छा तरीका संरक्षित सदस्य / फ़ील्ड वास्तव में बुरे हैं? छवि समानता की तुलना करने के लिए जावा लाइब्रेरी PHP – जबकि पाश (! Feof ()) outputting / सब कुछ दिखा नहीं है क्यों StyleCop "यह" के साथ विधि या गुण कॉल prefixing सिफारिश करता है? gitx मैं अपने 'पृथक हेड' को मास्टर में कैसे वापस कर सकता हूं

क्यों UINavigationBar स्पर्श घटनाओं चोरी?

मेरे पास यूआईएलएबल के साथ एक कस्टम यूआई बटन है जो सबव्यू के रूप में जोड़ा गया है। बटन चयनकर्ता को केवल तब ही प्रदर्शन करता है जब मैं इसे शीर्ष बाउंड के कम से कम 15 बिन्दुओं को स्पर्श करता हूं। और जब मैं उस क्षेत्र के ऊपर टैप करता हूं, तब कुछ नहीं होता।

मुझे पता चला कि यह गलत बटन और लेबल के निर्माण के कारण नहीं हुआ है, क्योंकि मेरे द्वारा लगभग 15 पिक्सल पर बटन को कम करने के बाद यह सही ढंग से काम करता है।

अद्यतन करें मैं यह कहने में भूल गया कि यूआईनेविगेशनबार के नीचे स्थित बटन और बटन के ऊपरी भाग के 1/3 का स्पर्श इवेंट नहीं मिलता है।

छवि यहां थी

4 बटन के साथ देखें नेविगेशनबार के नीचे स्थित है और शीर्ष पर "बास्केटबॉल" को स्पर्श करते समय, बैकबुटन टच इवेंट प्राप्त करते हैं, और जब शीर्ष पर "पियानो" को छूते हैं, तो दाएं बरबटन (यदि मौजूद है) स्पर्श प्राप्त करें यदि मौजूद नहीं है, तो कुछ भी नहीं हुआ

मुझे ऐप डॉक्स में यह दस्तावेज सुविधा नहीं मिली।

इसके अलावा मुझे यह समस्या मेरी समस्या से जुड़ी हुई है, लेकिन कोई जवाब भी नहीं है I

वेब के समाधान से एकत्रित समाधान "क्यों UINavigationBar स्पर्श घटनाओं चोरी?"

मैंने देखा है कि यदि आपने उपयोगकर्ता इंटरफ़ेस सक्षम किया है, तो बंद करने के लिए, नेविगेशनबार अब छूने वाले "चोरी" नहीं करता है।

तो आपको अपने UINavigationBar और अपने CustomNavigationBar में यह करना होगा:

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { if ([self pointInside:point withEvent:event]) { self.userInteractionEnabled = YES; } else { self.userInteractionEnabled = NO; } return [super hitTest:point withEvent:event]; } 

UINavigationBar को subclass कैसे करें के बारे में जानकारी आप यहां पा सकते हैं

मुझे यहां जवाब मिला (एप्पल डेवलपर फोरम)

कीथ में एप्पल डेवलपर तकनीकी सहायता, 18 मई 2010 (आईफोन ओएस 3) पर:

मैं अनुशंसा करता हूं कि आप नेवी बार या टूलबार के करीब निकटता में टच-संवेदनशील UI से बचें। इन क्षेत्रों को आम तौर पर "ढलान कारकों" के रूप में जाना जाता है जिससे उपयोगकर्ताओं को सटीक छूने की कठिनाई के बिना बटन पर टच इवेंट को आसान बनाते हैं। उदाहरण के लिए UIButtons के लिए यह भी मामला है।

लेकिन अगर आप नेविगेशन बार या टूलबार से पहले टच ईवेंट पर कब्जा करना चाहते हैं, तो आप UIWindow उप-वर्ग और ओवरराइड कर सकते हैं: – (शून्य) sendEvent: (UIEvent *) इवेंट;

इसके अलावा, मुझे पता चला कि जब मैं यूआईनेविगेशनबार के तहत क्षेत्र को स्पर्श करता हूँ, तो स्थान। 64 को परिभाषित करता है, हालांकि यह नहीं था। तो मैंने इसे बनाया:

CustomWindow.h

 @interface CustomWindow: UIWindow @end 

CustomWindow.m

 @implementation CustomWindow - (void) sendEvent:(UIEvent *)event { BOOL flag = YES; switch ([event type]) { case UIEventTypeTouches: //[self catchUIEventTypeTouches: event]; perform if you need to do something with event for (UITouch *touch in [event allTouches]) { if ([touch phase] == UITouchPhaseBegan) { for (int i=0; i<[self.subviews count]; i++) { //GET THE FINGER LOCATION ON THE SCREEN CGPoint location = [touch locationInView:[self.subviews objectAtIndex:i]]; //REPORT THE TOUCH NSLog(@"[%@] touchesBegan (%i,%i)", [[self.subviews objectAtIndex:i] class],(NSInteger) location.x, (NSInteger) location.y); if (((NSInteger)location.y) == 64) { flag = NO; } } } } break; default: break; } if(!flag) return; //to do nothing /*IMPORTANT*/[super sendEvent:(UIEvent *)event];/*IMPORTANT*/ } @end 

ऐप डिएलिगेट क्लास में मैं यूआई विन्डो के बजाय कस्टमवंडो का उपयोग करता हूं।

अब जब मैं नेविगेशन बार के तहत क्षेत्र को छूता हूं, तो कुछ नहीं होता है

मेरे बटन अभी भी स्पर्श इवेंट नहीं मिलते हैं, क्योंकि मुझे यह नहीं पता कि कैसे इस घटना को भेजने के लिए (और निर्देशांक बदलकर) बटन के साथ मेरे विचार में।

उपवर्ग UINavigationBar और इस विधि को जोड़ें। यह नल के माध्यम से पारित होने के कारण होगा, जब तक कि वे एक सबव्यू (जैसे कि एक बटन) को टैप कर रहे हों।

  -(UIView*) hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView *v = [super hitTest:point withEvent:event]; return v == self? nil: v; } 

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

पहले कोड को देखने दें

 class MyNavigationBar: UINavigationBar { private var secondTap = false private var firstTapPoint = CGPointZero override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool { if !self.secondTap{ self.firstTapPoint = point } defer{ self.secondTap = !self.secondTap } return super.pointInside(firstTapPoint, withEvent: event) } 

}

आप देख सकते हैं कि मैं दूसरी स्पर्श संभाल कर रहा हूं। समाधान के लिए नुस्खा है

हिट टेस्ट को कॉल के लिए दो बार कहा जाता है। पहली बार खिड़की पर वास्तविक बिंदु की सूचना दी है। सबकुछ अच्छा चल रहा है। दूसरे पास में, ऐसा होता है

अगर सिस्टम एक एनएवी बार देखता है और हिट पॉइंट Y पक्ष पर लगभग 9 पिक्सल से ज्यादा है, तो यह धीरे-धीरे 44 अंकों से कम करने की कोशिश करता है जहां एनएवी बार है।

स्पष्ट होने के लिए स्क्रीन पर एक नज़र डालें

यहां छवि विवरण दर्ज करें

तो एक तंत्र है जो आस-पास के तर्क का उपयोग दूसरे सत्र के उत्तरार्द्ध में किया जाएगा। यदि हम अपना दूसरा पास जान सकते हैं और फिर सुपर हिट टेस्ट पॉइंट के साथ कॉल करते हैं। काम हो गया।

उपरोक्त कोड ठीक उसी प्रकार करता है

अलेक्जेंडर द्वारा दिए गए उत्तर के आधार पर मेरे लिए काम करने वाले एक वैकल्पिक समाधान:

 self.navigationController?.barHideOnTapGestureRecognizer.enabled = false 

UIWindow को ओवरराइड करने के बजाय, आप UIWindow पर "स्लॉप एरिया" के लिए ज़िम्मेदार पहचानकर्ता को अक्षम कर सकते हैं।

दो चीजें हैं जो समस्या पैदा कर सकती हैं

  1. क्या आपने सेट अप करने की कोशिश की? setUserInteractionEnabled:NO लेबल के लिए setUserInteractionEnabled:NO

  2. मुझे लगता है कि काम करने वाला दूसरा काम बटन के शीर्ष पर लेबल जोड़ने के बाद से अलग हो सकता है, आप वापस लेबले भेज सकते हैं (यह काम हो सकता है, हालांकि यकीन नहीं है)

    [button sendSubviewToBack:label];

कोड काम करता है तो कृपया मुझे बताएं 🙂

आपके लेबल बहुत बड़ी हैं वे {0,0} (बटन के बायां शीर्ष कोने) से शुरू होते हैं, बटन की पूरी चौड़ाई को बढ़ाते हैं और संपूर्ण दृश्य की ऊंचाई होती है। अपना frame डेटा जांचें और फिर से प्रयास करें

इसके अलावा, आपके पास UIButton गुण titleLabel का उपयोग करने का विकल्प है। शायद आप बाद में शीर्षक सेट कर रहे हैं और यह आपकी खुद की UILabel बजाय इस लेबल में जाता है। यही कारण बताता है कि पाठ (बटन से संबंधित) काम करेगा, जबकि लेबल के बाकी बटन को कवर किया जाएगा (नल के माध्यम से जाने पर नहीं)

titleLabel एक पठन-योग्य संपत्ति है, लेकिन आप इसे टेक्स्ट रंग, फ़ॉन्ट, छाया, इत्यादि सहित अपने खुद के लेबल (शायद frame को छोड़कर) के रूप में अनुकूलित कर सकते हैं।

इसने मेरी समस्या हल की ..

मैंने hitTest को जोड़ा : मेरे Navbar subclass के साथ एवेन्ट कोड …

  -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { int errorMargin = 5;// space left to decrease the click event area CGRect smallerFrame = CGRectMake(0 , 0 - errorMargin, self.frame.size.width, self.frame.size.height); BOOL isTouchAllowed = (CGRectContainsPoint(smallerFrame, point) == 1); if (isTouchAllowed) { self.userInteractionEnabled = YES; } else { self.userInteractionEnabled = NO; } return [super hitTest:point withEvent:event]; } 

अलेक्जेंडर के समाधान का विस्तार:

चरण 1. उपवर्ग UIWindow

 @interface ChunyuWindow : UIWindow { NSMutableArray * _views; @private UIView *_touchView; } - (void)addViewForTouchPriority:(UIView*)view; - (void)removeViewForTouchPriority:(UIView*)view; @end // .m File // #import "ChunyuWindow.h" @implementation ChunyuWindow - (void) dealloc { TT_RELEASE_SAFELY(_views); [super dealloc]; } - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event { if (UIEventSubtypeMotionShake == motion && [TTNavigator navigator].supportsShakeToReload) { // If you're going to use a custom navigator implementation, you need to ensure that you // implement the reload method. If you're inheriting from TTNavigator, then you're fine. TTDASSERT([[TTNavigator navigator] respondsToSelector:@selector(reload)]); [(TTNavigator*)[TTNavigator navigator] reload]; } } - (void)addViewForTouchPriority:(UIView*)view { if ( !_views ) { _views = [[NSMutableArray alloc] init]; } if (![_views containsObject: view]) { [_views addObject:view]; } } - (void)removeViewForTouchPriority:(UIView*)view { if ( !_views ) { return; } if ([_views containsObject: view]) { [_views removeObject:view]; } } - (void)sendEvent:(UIEvent *)event { if ( !_views || _views.count == 0 ) { [super sendEvent:event]; return; } UITouch *touch = [[event allTouches] anyObject]; switch (touch.phase) { case UITouchPhaseBegan: { for ( UIView *view in _views ) { if ( CGRectContainsPoint(view.frame, [touch locationInView:[view superview]]) ) { _touchView = view; [_touchView touchesBegan:[event allTouches] withEvent:event]; return; } } break; } case UITouchPhaseMoved: { if ( _touchView ) { [_touchView touchesMoved:[event allTouches] withEvent:event]; return; } break; } case UITouchPhaseCancelled: { if ( _touchView ) { [_touchView touchesCancelled:[event allTouches] withEvent:event]; _touchView = nil; return; } break; } case UITouchPhaseEnded: { if ( _touchView ) { [_touchView touchesEnded:[event allTouches] withEvent:event]; _touchView = nil; return; } break; } default: { break; } } [super sendEvent:event]; } @end 

चरण 2: ChunyuWindow को निर्दिष्ट करें उदाहरण के लिए AppDelegate instance

चरण 3: touchesEnded:widthEvent: लागू touchesEnded:widthEvent: बटन के साथ view के लिए, उदाहरण के लिए:

 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesEnded: touches withEvent: event]; UITouch *touch = [touches anyObject]; CGPoint point = [touch locationInView: _buttonsView]; // a subview contains buttons for (UIButton* button in _buttons) { if (CGRectContainsPoint(button.frame, point)) { [self onTabButtonClicked: button]; break; } } } 

चरण 4: ChunyuWindow की ChunyuWindow कॉल करें, जब हम जो दृश्य देखते हैं, प्रकट होता है, और दृश्य removeViewForTouchPriority जाने पर या removeViewForTouchPriority को देखने के लिए, removeViewForTouchPriority कॉल करें, दृश्य में डिडएपियर / विजिट / डिसप्ले / डेअलोक देखें, तो चुनेयू में ChunyuWindow , शून्य है, और यह ChunyuWindow के समान है, कोई साइड इफेक्ट नहीं है

बार्ट व्हाईटले के अनुसार एक विस्तार संस्करण दें उपवर्ग की कोई ज़रूरत नहीं है

 @implementation UINavigationBar(Xxxxxx) - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView *v = [super hitTest:point withEvent:event]; return v == self ? nil: v; } @end 

मेरे लिए इसका समाधान निम्न था:

सबसे पहले: अपने आवेदन में जोड़ें (यह कोई फर्क नहीं पड़ता कि आप इस कोड को दर्ज करते हैं, जहां आप इस कोड को दर्ज करते हैं) UINavigationBar लिए एक एक्सटेंशन जैसा है: निम्न कोड सिर्फ बिंदु और घटना के साथ एक अधिसूचना प्रेषित करते हैं जब navigationBar टेप किया जा रहा है।

 extension UINavigationBar { open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { NotificationCenter.default.post(name: NSNotification.Name(rawValue: "tapNavigationBar"), object: nil, userInfo: ["point": point, "event": event as Any]) return super.hitTest(point, with: event) } } 

उसके बाद अपने विशिष्ट दृश्य नियंत्रक में आपको अपने दृश्य में इस लाइन को जोड़कर इस नोटिफिकेशन को सुनना चाहिए viewDidLoad :

 NotificationCenter.default.addObserver(self, selector: #selector(tapNavigationBar), name: NSNotification.Name(rawValue: "tapNavigationBar"), object: nil) 

उसके बाद आपको अपने दृश्य नियंत्रक में विधि का उपयोग करने की आवश्यकता है:

 func tapNavigationBar(notification: Notification) { let pointOpt = notification.userInfo?["point"] as? CGPoint let eventOpt = notification.userInfo?["event"] as? UIEvent? guard let point = pointOpt, let event = eventOpt else { return } let convertedPoint = YOUR_VIEW_BEHIND_THE_NAVBAR.convert(point, from: self.navigationController?.navigationBar) if YOUR_VIEW_BEHIND_THE_NAVBAR.point(inside: convertedPoint, with: event) { //Dispatch whatever you wanted at the first place. } } 

पीडी: इस तरह के deinit में अवलोकन को हटाने के लिए मत भूलना:

 deinit { NotificationCenter.default.removeObserver(self) } 

यह बात है … यह थोड़ा सा 'मुश्किल' है, लेकिन कभी भी उपविभाजन न होने और navigationBar पर टैप किया जा रहा है, यह एक अच्छा काम है।