आईओएस - एक दृश्य के माध्यम से सभी स्पर्शों को आगे बढ़ाएं


75

मेरे पास कई अन्य विचारों के शीर्ष पर एक दृश्य है। मैं स्क्रीन पर कुछ छूने का पता लगाने के लिए केवल ओवरली का उपयोग कर रहा हूं, लेकिन इसके अलावा मैं नहीं चाहता कि दृश्य नीचे के अन्य विचारों के व्यवहार को रोक सके, जो स्क्रॉलव्यू हैं, आदि। मैं सभी स्पर्शों को कैसे आगे बढ़ा सकता हूं यह ओवरले व्यू? यह UIView का उप-समूह है। इस तरह

0

कोशिश कुछ ...

for (UIView *view in subviews) 
    [view touchesBegan:touches withEvent:event]; 

उपरोक्त कोड, उदाहरण के लिए अपने touchesBegan विधि में देखने के subviews के सभी छूता से होकर गुजरेगा।

+6

इस दृष्टिकोण AFAIK के साथ समस्या यह है कि UIKit ढांचे की कक्षाओं के लिए अंतिम रूप अग्रेषित करने के लिए प्रयास करने से सबसे अधिक बार नहीं होगा प्रभाव। ऐप्पल के प्रलेखन के अनुसार यूआईकिट फ्रेमवर्क कक्षाएं उन स्पर्शों को प्राप्त करने के लिए डिज़ाइन नहीं की गई हैं जिनके दृश्य दृश्य को किसी अन्य दृश्य पर सेट किया गया है। तो यह दृष्टिकोण ज्यादातर UIView के कस्टम उप-वर्गों के लिए काम करता है। 02 mar. 112011-03-02 23:05:35


4

दृश्य आपको छूता है अग्रेषित करना चाहते हैं एक subview/superview होने के लिए नहीं होता है, तो आपके सामने कोई कस्टम गुण अपने UIView उपवर्ग में इतनी तरह सेट कर सकते हैं:

@interface SomeViewSubclass : UIView { 

    id forwardableTouchee; 

} 
@property (retain) id forwardableTouchee; 

के संश्लेषण के लिए सुनिश्चित करें आपके मीटर में यह:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 

    [self.forwardableTouchee touchesBegan:touches withEvent:event]; 

} 
:

@synthesize forwardableTouchee; 

और फिर इस तरह के रूप में अपने UIResponder तरीकों में से किसी में निम्नलिखित शामिल

आप कहीं भी अपने UIView का दृष्टांत, सेट आप घटनाओं चाहते हैं जो कुछ भी देखने के लिए forwardableTouchee संपत्ति के लिए भेजा जाना: विचारों के लिए एक ओवरले देखने से छूता गुजर के लिए

SomeViewSubclass *view = [[[SomeViewSubclass alloc] initWithFrame:someRect] autorelease]; 
    view.forwardableTouchee = someOtherView; 

75

नीचे, में निम्न विधि को लागू UIView:

ऑब्जेक्टिव-सी:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { 
    NSLog(@"Passing all touches to the next view (if any), in the view stack."); 
    return NO; 
} 

स्विफ्ट:

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 
    print("Passing all touches to the next view (if any), in the view stack.") 
    return false 
} 
+2

मेरे पास एक ही समस्या है, लेकिन मैं जो चाहता हूं वह यह है कि यदि मैं जेश्चर के साथ ज़ूमिंग/घूर्णन/दृश्य को देख रहा हूं तो उसे हाँ वापस कर देना चाहिए और बाकी की घटना के लिए इसे वापस नहीं करना चाहिए, मैं इसे कैसे प्राप्त कर सकता हूं? 12 aug. 132013-08-12 06:27:33


58
myWebView.userInteractionEnabled = NO; 

मुझे बस इतना ही चाहिए!


38

यह एक पुराना धागा है, लेकिन यह एक खोज पर आया, इसलिए मैंने सोचा कि मैं अपना 2 सी जोड़ूंगा। मैं subviews के साथ एक कवर UIView है, और केवल छूता है कि subviews में से एक मारा रोकना चाहते हैं, तो मैं

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    for (UIView* subview in self.subviews) { 
     if ([subview hitTest:[self convertPoint:point toView:subview] withEvent:event] != nil) { 
      return YES; 
     } 
    } 
    return NO; 
} 
+1

आपको एक कस्टम UIView सबक्लास (या किसी अन्य UIView सबक्लास जैसे UIImageView या जो भी हो) का उप-वर्ग बनाना होगा और इस फ़ंक्शन को ओवरराइड करना होगा। संक्षेप में, उप-वर्ग में .h फ़ाइल में पूरी तरह खाली '@interface' हो सकता है, और ऊपर दिया गया कार्य '@ कार्यान्वयन' की संपूर्ण सामग्री हो। 07 mar. 142014-03-07 16:01:14


-1

को PixelCloudSt के जवाब संशोधित @PixelCloudStv ने सुझाव दिया के रूप में आप एक दृश्य से करने के लिए छुआ फेंक चाहते हैं एक और लेकिन इस प्रक्रिया पर कुछ अतिरिक्त नियंत्रण के साथ - उपवर्ग UIView

// हैडर

@interface TouchView : UIView 

@property (assign, nonatomic) CGRect activeRect; 

@end 

// कार्यान्वयन

#import "TouchView.h" 

@implementation TouchView 

#pragma mark - Ovverride 

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    BOOL moveTouch = YES; 
    if (CGRectContainsPoint(self.activeRect, point)) { 
     moveTouch = NO; 
    } 
    return moveTouch; 
} 

@end 

इंटरफ़ेस के बाद बिल्डर बस टच व्यू में दृश्य का वर्ग सेट करें और अपने रेक्ट के साथ सक्रिय रेक्ट सेट करें। इसके अलावा आप अन्य तर्क बदल सकते हैं और कार्यान्वित कर सकते हैं।


3

मुझे UIStackView के साथ एक समान समस्या थी (लेकिन कोई अन्य दृश्य हो सकता है)। मेरे विन्यास निम्नलिखित था: View controller with containerView and StackView

यह एक शास्त्रीय मामले में जहां मैं एक कंटेनर साइड पर बटन के साथ, पृष्ठभूमि में रखा जाना करने के लिए आवश्यक है कि है है। लेआउट उद्देश्यों के लिए, मैंने UIStackView में बटन शामिल किए हैं, लेकिन अब स्टैक व्यू का मध्य (खाली) भाग छूता है :-(

मैंने जो किया वह सबव्यू को परिभाषित करने वाली संपत्ति के साथ UIStackView का उप-वर्ग बनाता है जो होना चाहिए टच करने योग्य। अब, साइड बटन पर किसी भी स्पर्श (* ViewsWithActiveTouch * सरणी में शामिल) बटन पर दिए जाएंगे, जबकि इन विचारों के अलावा कहीं भी स्टैकव्यू पर कोई भी स्पर्श अवरुद्ध नहीं किया जाएगा, और इसलिए जो भी हो ढेर दृश्य के नीचे।

/** Subclass of UIStackView that does not accept touches, except for specific subviews given in the viewsWithActiveTouch array */ 
class NoTouchStackView: UIStackView { 

    var viewsWithActiveTouch: [UIView]? 

    override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? { 

    if let activeViews = viewsWithActiveTouch { 
     for view in activeViews { 
      if CGRectContainsPoint(view.frame, point) { 
       return view 

      } 
     } 
    } 
    return nil 
    } 
} 

14

@fresidue जवाब का उन्नत संस्करण है। आप इस UIView उपवर्ग के रूप में पारदर्शी दृश्य का उपयोग कर सकते हैं गुजर छूता है कहां इसके सबव्यू के बारे में बताओ।

@interface PassthroughView : UIView 

@end 

@implementation PassthroughView 

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    for (UIView *view in self.subviews) { 
     if (!view.hidden && [view pointInside:[self convertPoint:point toView:view] withEvent:event]) { 
      return YES; 
     } 
    } 
    return NO; 
} 

@end 

और में स्विफ्ट:: ऑब्जेक्टिव-सी में कार्यान्वयन

class PassthroughView: UIView { 
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 
    return subviews.contains(where: { 
     !$0.isHidden && $0.point(inside: self.convert(point, to: $0), with: event) 
    }) 
    } 
}