दिलचस्प पोस्ट
IO ऑर्डर से बाहर होता है जब getLine और putStr का इस्तेमाल करते हैं आर के लिए Windows पाठ संपादक की अनुशंसाएं विजुअल स्टूडियो 2012 – कभी-कभी गायब / टूटे हुए इंटेलिसेंस कॉलम के डेटा प्रकार को बदलने के लिए ईएफ प्रवासन PHP सत्र आईडी कितना अनूठा है jQuery – यह कई $ (दस्तावेज़) के लिए खराब है .ready (function () {}); जहां MySQL स्टोर डेटाबेस फ़ाइलों को करता है? क्या बेहतर है, DOM फ़ंक्शंस के माध्यम से नए तत्वों को जोड़ने, या एचटीएमएल टैग्स के साथ तार जोड़ना? ऋणात्मक सरणी अनुक्रमणियां सी में अनुमत हैं? चेतावनी: PDOStatement :: execute (): SQLSTATE : अमान्य पैरामीटर संख्या: बाउंड चर की संख्या में टोकन की संख्या से मेल नहीं खाती कैसे आर में एक कुंजीपटल के लिए प्रतीक्षा करने के लिए? स्ट्रिंग के रूप में संपत्ति का नाम प्राप्त करें Google मुखपृष्ठ एक iframe में लोड नहीं करेगा जावास्क्रिप्ट स्ट्रिंग / पूर्णांक तुलना दो तिथियों की तुलना

UIButton: हिट क्षेत्र को डिफ़ॉल्ट हिट क्षेत्र से बड़ा करना

मेरे पास UIButton और इसके हिट एरिया के साथ एक सवाल है। मैं इंटरफ़ेस बिल्डर में जानकारी डार्क बटन का उपयोग कर रहा हूं, लेकिन मुझे लगता है कि हिट क्षेत्र कुछ लोगों की उंगलियों के लिए काफी बड़ा नहीं है

क्या एक बटन के हिट एरिया को प्रोग्रामेटिक रूप से या इंटरफ़ेस बिल्डर में इंफोबटन ग्राफ़िक के आकार को बदलने के बिना बढ़ाया जा सकता है?

Solutions Collecting From Web of "UIButton: हिट क्षेत्र को डिफ़ॉल्ट हिट क्षेत्र से बड़ा करना"

चूंकि मैं पृष्ठभूमि छवि का उपयोग कर रहा हूं, इनमें से कोई समाधान मेरे लिए अच्छा काम नहीं करता है यहां एक समाधान है जो कुछ मज़ेदार उद्देश्य-सी जादू करता है और न्यूनतम कोड के साथ समाधान में गिरावट देता है।

सबसे पहले, एक UIButton एक श्रेणी जोड़ें जो हिट टेस्ट को ओवरराइड करता है और हिट टेस्ट फ्रेम के विस्तार के लिए एक संपत्ति भी जोड़ता है

UIButton + Extensions.h

 @interface UIButton (Extensions) @property(nonatomic, assign) UIEdgeInsets hitTestEdgeInsets; @end 

UIButton + Extensions.m

 #import "UIButton+Extensions.h" #import <objc/runtime.h> @implementation UIButton (Extensions) @dynamic hitTestEdgeInsets; static const NSString *KEY_HIT_TEST_EDGE_INSETS = @"HitTestEdgeInsets"; -(void)setHitTestEdgeInsets:(UIEdgeInsets)hitTestEdgeInsets { NSValue *value = [NSValue value:&hitTestEdgeInsets withObjCType:@encode(UIEdgeInsets)]; objc_setAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -(UIEdgeInsets)hitTestEdgeInsets { NSValue *value = objc_getAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS); if(value) { UIEdgeInsets edgeInsets; [value getValue:&edgeInsets]; return edgeInsets; }else { return UIEdgeInsetsZero; } } - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { if(UIEdgeInsetsEqualToEdgeInsets(self.hitTestEdgeInsets, UIEdgeInsetsZero) || !self.enabled || self.hidden) { return [super pointInside:point withEvent:event]; } CGRect relativeFrame = self.bounds; CGRect hitFrame = UIEdgeInsetsInsetRect(relativeFrame, self.hitTestEdgeInsets); return CGRectContainsPoint(hitFrame, point); } @end 

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

 [button setHitTestEdgeInsets:UIEdgeInsetsMake(-10, -10, -10, -10)]; 

नोट: अपनी कक्षाओं में श्रेणी आयात करने के लिए याद रखें ( #import "UIButton+Extensions.h" )

बस इंटरफ़ेस बिल्डर में छवि बढ़त के अंदर मूल्य निर्धारित करें

स्विफ्ट में एक्स्टेंशन का उपयोग करते हुए यहां एक शानदार समाधान है यह एप्पल के मानव इंटरफेस दिशानिर्देशों ( https://developer.apple.com/ios/human-interface-guidelines/visual-design/layout/ ) के अनुसार, सभी UIButtons को कम से कम 44×44 अंक के हिट क्षेत्र देता है।

स्विफ्ट 2:

 private let minimumHitArea = CGSizeMake(44, 44) extension UIButton { public override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? { // if the button is hidden/disabled/transparent it can't be hit if self.hidden || !self.userInteractionEnabled || self.alpha < 0.01 { return nil } // increase the hit frame to be at least as big as `minimumHitArea` let buttonSize = self.bounds.size let widthToAdd = max(minimumHitArea.width - buttonSize.width, 0) let heightToAdd = max(minimumHitArea.height - buttonSize.height, 0) let largerFrame = CGRectInset(self.bounds, -widthToAdd / 2, -heightToAdd / 2) // perform hit test on larger frame return (CGRectContainsPoint(largerFrame, point)) ? self : nil } } 

स्विफ्ट 3:

 fileprivate let minimumHitArea = CGSize(width: 100, height: 100) extension UIButton { open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { // if the button is hidden/disabled/transparent it can't be hit if self.isHidden || !self.isUserInteractionEnabled || self.alpha < 0.01 { return nil } // increase the hit frame to be at least as big as `minimumHitArea` let buttonSize = self.bounds.size let widthToAdd = max(minimumHitArea.width - buttonSize.width, 0) let heightToAdd = max(minimumHitArea.height - buttonSize.height, 0) let largerFrame = self.bounds.insetBy(dx: -widthToAdd / 2, dy: -heightToAdd / 2) // perform hit test on larger frame return (largerFrame.contains(point)) ? self : nil } } 

आप UIButton या एक कस्टम UIView और ओवरराइड point(inside:with:) subclass भी कर सकते हैं point(inside:with:) जैसे कुछ के साथ:

स्विफ्ट 3

 override func point(inside point: CGPoint, with _: UIEvent?) -> Bool { let margin: CGFloat = 5 let area = self.bounds.insetBy(dx: -margin, dy: -margin) return area.contains(point) } 

उद्देश्य सी

 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { CGFloat margin = 5.0; CGRect area = CGRectInset(self.bounds, -margin, -margin); return CGRectContainsPoint(area, point); } 

स्विफ्ट 3.0 में चेज़ का UIButton + एक्सटेंशन है

 import UIKit private var pTouchAreaEdgeInsets: UIEdgeInsets = .zero extension UIButton { var touchAreaEdgeInsets: UIEdgeInsets { get { if let value = objc_getAssociatedObject(self, &pTouchAreaEdgeInsets) as? NSValue { var edgeInsets: UIEdgeInsets = .zero value.getValue(&edgeInsets) return edgeInsets } else { return .zero } } set(newValue) { var newValueCopy = newValue let objCType = NSValue(uiEdgeInsets: .zero).objCType let value = NSValue(&newValueCopy, withObjCType: objCType) objc_setAssociatedObject(self, &pTouchAreaEdgeInsets, value, .OBJC_ASSOCIATION_RETAIN) } } open override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { if UIEdgeInsetsEqualToEdgeInsets(self.touchAreaEdgeInsets, .zero) || !self.isEnabled || self.isHidden { return super.point(inside: point, with: event) } let relativeFrame = self.bounds let hitFrame = UIEdgeInsetsInsetRect(relativeFrame, self.touchAreaEdgeInsets) return hitFrame.contains(point) } } 

इसका उपयोग करने के लिए, आप यह कर सकते हैं:

 button.touchAreaEdgeInsets = UIEdgeInsets(top: -10, left: -10, bottom: -10, right: -10) 

अपनी छवि के साथ backgroundImage छवि संपत्ति सेट न करें, छवि imageView सेट करें इसके अलावा, सुनिश्चित करें कि आपके पास imageView.contentMode सेट है, UIViewContentModeCenter पर

मैं सुझाव देता हूं कि UIButton को अपनी जानकारी बटन पर केंद्रित कस्टम प्रकार के साथ रखें। उस आकार के कस्टम बटन का आकार बदलें जिसे आप हिट एरिया चाहते हैं वहां से आपके पास दो विकल्प हैं:

  1. कस्टम बटन के 'हाइलाइट पर स्पर्श दिखाएं' विकल्प देखें। सफेद चमक सूचना बटन पर दिखाई देगी, लेकिन ज्यादातर मामलों में उपयोगकर्ता उंगली इस को कवर करेंगे और सभी वे देखेंगे जो बाहर के आसपास की चमक है।

  2. सूचना बटन के लिए एक आईबीओलेट और 'टच डाउन' के लिए कस्टम बटन के लिए दो IBActions और 'टच अप इनसाइड' के लिए एक सेट करें। फिर Xcode में टचडाउन इवेंट ने जानकारी बटन की हाइलाइट की गई संपत्ति को हाँ पर सेट किया और टचपिनस इवेंट ने हाइलाइट की गई संपत्ति को NO सेट किया।

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

अपने बटन के लिए एक नया उप-वर्ग बनाएं (या कोई नियंत्रण)

 #import <UIKit/UIKit.h> @interface MNGButton : UIButton @end 

आगे अपने उपवर्ग कार्यान्वयन में बिंदुअरेसर विधि को ओवरराइड करें

 @implementation MNGButton -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { //increase touch area for control in all directions by 20 CGFloat margin = 20.0; CGRect area = CGRectInset(self.bounds, -margin, -margin); return CGRectContainsPoint(area, point); } @end 

आपके स्टोरीबोर्ड / xib फ़ाइल पर सवाल में नियंत्रण का चयन करें और पहचान निरीक्षक को खोलें और अपने कस्टम क्लास के नाम पर टाइप करें।

mngbutton

बटन वाले दृश्य के लिए अपने UIViewController वर्ग में, बटन को अपने उपवर्ग के नाम के लिए वर्ग के प्रकार में बदलें

 @property (weak, nonatomic) IBOutlet MNGButton *helpButton; 

अपने स्टोरीबोर्ड / एक्सआईटी बटन को संपत्ति आईबीओटलेट में लिंक करें और उप-कक्षा में परिभाषित क्षेत्र को फिट करने के लिए आपके टच एरिया का विस्तार किया जाएगा।

CGRectInset और CGRectContainsPoint विधियों के साथ एक साथ बिंदु इनसाइड विधि को ओवरराइड करने के अलावा, किसी भी UIView subclass के आयताकार स्पर्श क्षेत्र को विस्तारित करने के लिए CGGeometry की जांच करने के लिए समय लेना चाहिए। एनएसएचपस्टर में सीजीजीओमित्री उपयोग-मामले पर आपको कुछ अच्छे सुझाव मिल सकते हैं।

उदाहरण के लिए, ऊपर उल्लिखित विधियों का उपयोग करके टच एरिया अनियमित बना सकता है या क्षैतिज स्पर्श क्षेत्र के रूप में दो बार बड़े पैमाने पर छूने वाले क्षेत्र का चयन कर सकता है:

 CGRect area = CGRectInset(self.bounds, -(2*margin), -margin); 

एनबी: किसी भी यूआई कक्षा नियंत्रण को अलग-अलग नियंत्रणों (या किसी भी UIView subclass, जैसे UIImageView, आदि) के लिए स्पर्श क्षेत्र को विस्तारित करने के समान परिणाम उत्पन्न करना चाहिए।

यह मेरे लिए काम करता है:

 UIButton *button = [UIButton buttonWithType: UIButtonTypeCustom]; // set the image (here with a size of 32 x 32) [button setImage: [UIImage imageNamed: @"myimage.png"] forState: UIControlStateNormal]; // just set the frame of the button (here 64 x 64) [button setFrame: CGRectMake(xPositionOfMyButton, yPositionOfMyButton, 64, 64)]; 

मैं स्वेज़िंग के द्वारा एक अधिक सामान्य दृष्टिकोण का उपयोग कर रहा हूं -[UIView pointInside:withEvent:] यह मुझे UIButton न केवल, किसी भी UIView पर हिट परीक्षण व्यवहार को संशोधित करने की अनुमति देता है

बार-बार, एक बटन एक कंटेनर दृश्य के अंदर रखा जाता है जो हिट परीक्षण को सीमित करता है। उदाहरण के लिए, जब एक बटन एक कंटेनर दृश्य के शीर्ष पर होता है और आप स्पर्श लक्ष्य ऊपर की ओर बढ़ाना चाहते हैं, तो आपको कंटेनर व्यू के स्पर्श लक्ष्य का भी विस्तार करना होगा।

 @interface UIView(Additions) @property(nonatomic) UIEdgeInsets hitTestEdgeInsets; @end @implementation UIView(Additions) + (void)load { Swizzle(self, @selector(pointInside:withEvent:), @selector(myPointInside:withEvent:)); } - (BOOL)myPointInside:(CGPoint)point withEvent:(UIEvent *)event { if(UIEdgeInsetsEqualToEdgeInsets(self.hitTestEdgeInsets, UIEdgeInsetsZero) || self.hidden || ([self isKindOfClass:UIControl.class] && !((UIControl*)self).enabled)) { return [self myPointInside:point withEvent:event]; // original implementation } CGRect hitFrame = UIEdgeInsetsInsetRect(self.bounds, self.hitTestEdgeInsets); hitFrame.size.width = MAX(hitFrame.size.width, 0); // don't allow negative sizes hitFrame.size.height = MAX(hitFrame.size.height, 0); return CGRectContainsPoint(hitFrame, point); } static char hitTestEdgeInsetsKey; - (void)setHitTestEdgeInsets:(UIEdgeInsets)hitTestEdgeInsets { objc_setAssociatedObject(self, &hitTestEdgeInsetsKey, [NSValue valueWithUIEdgeInsets:hitTestEdgeInsets], OBJC_ASSOCIATION_RETAIN); } - (UIEdgeInsets)hitTestEdgeInsets { return [objc_getAssociatedObject(self, &hitTestEdgeInsetsKey) UIEdgeInsetsValue]; } void Swizzle(Class c, SEL orig, SEL new) { Method origMethod = class_getInstanceMethod(c, orig); Method newMethod = class_getInstanceMethod(c, new); if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); else method_exchangeImplementations(origMethod, newMethod); } @end 

इस दृष्टिकोण के बारे में अच्छी बात यह है कि आप स्टोरीबोर्ड में भी उपयोगकर्ता परिभाषित रनटाइम अटिटिड जोड़कर इसका उपयोग कर सकते हैं। अफसोस की बात है, UIEdgeInsets वहाँ एक प्रकार के रूप में सीधे उपलब्ध नहीं है, लेकिन चूंकि UIEdgeInsets में चार CGFloat साथ एक स्ट्रक्चर होते हैं, यह "रीक्ट" को चुनकर और इस तरह के मूल्यों को भरकर काम करता है: {{top, left}, {bottom, right}}

UIButton के व्यवहार को न बदलें

 @interface ExtendedHitButton: UIButton + (instancetype) extendedHitButton; - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event; @end @implementation ExtendedHitButton + (instancetype) extendedHitButton { return (ExtendedHitButton *) [ExtendedHitButton buttonWithType:UIButtonTypeCustom]; } - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { CGRect relativeFrame = self.bounds; UIEdgeInsets hitTestEdgeInsets = UIEdgeInsetsMake(-44, -44, -44, -44); CGRect hitFrame = UIEdgeInsetsInsetRect(relativeFrame, hitTestEdgeInsets); return CGRectContainsPoint(hitFrame, point); } @end 

स्विफ्ट 3 पर मेरा समाधान:

 class MyButton: UIButton { override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool { let relativeFrame = self.bounds let hitTestEdgeInsets = UIEdgeInsetsMake(-25, -25, -25, -25) let hitFrame = UIEdgeInsetsInsetRect(relativeFrame, hitTestEdgeInsets) return hitFrame.contains(point) } } 

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

अन्य संभावना में UIButton के बजाय UIImage का उपयोग करना शामिल है

मैं जानकारी बटन के हिट क्षेत्र में प्रोग्रामेटिक रूप से वृद्धि करने में सक्षम हूं। "मैं" ग्राफ़िक पैमाने को बदलता नहीं है और नए बटन फ़्रेम में केंद्रित रहता है।

जानकारी बटन का आकार 18×19 [*] के लिए इंटरफ़ेस बिल्डर में तय किया जा रहा है इसे आईबीओटलेट से कनेक्ट करके, मैं किसी भी मुद्दे के बिना कोड में अपने फ्रेम आकार को बदलने में सक्षम था

 static void _resizeButton( UIButton *button ) { const CGRect oldFrame = infoButton.frame; const CGFloat desiredWidth = 44.f; const CGFloat margin = ( desiredWidth - CGRectGetWidth( oldFrame ) ) / 2.f; infoButton.frame = CGRectInset( oldFrame, -margin, -margin ); } 

[*]: आईओएस के बाद के संस्करणों में जानकारी बटन के हिट क्षेत्र में वृद्धि हुई है।

मार्जिन समायोजित करने के लिए मैं इंटरफ़ेस बिल्डर संपत्ति को सक्षम करने के लिए स्विफ्ट में निम्नलिखित वर्ग का उपयोग कर रहा हूं:

 @IBDesignable class ALExtendedButton: UIButton { @IBInspectable var touchMargin:CGFloat = 20.0 override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool { var extendedArea = CGRectInset(self.bounds, -touchMargin, -touchMargin) return CGRectContainsPoint(extendedArea, point) } } 

यह मेरा स्विफ्ट 3 समाधान है (इस ब्लॉगपोस्ट पर आधारित: http://bdunagan.com/2010/03/01/iphone-tip-larger-hit-area-for-uibutton/ )

 class ExtendedHitAreaButton: UIButton { @IBInspectable var hitAreaExtensionSize: CGSize = CGSize(width: -10, height: -10) override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { let extendedFrame: CGRect = bounds.insetBy(dx: hitAreaExtensionSize.width, dy: hitAreaExtensionSize.height) return extendedFrame.contains(point) ? self : nil } } 

चेस का कस्टम हिट टेस्ट UIButton के उपवर्ग के रूप में लागू किया गया उद्देश्य-सी में लिखित

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

CustomeHitAreaButton.h

 #import <UIKit/UIKit.h> @interface CustomHitAreaButton : UIButton - (void)setHitTestEdgeInsets:(UIEdgeInsets)hitTestEdgeInsets; @end 

CustomHitAreaButton.m

 #import "CustomHitAreaButton.h" @interface CustomHitAreaButton() @property (nonatomic, assign) UIEdgeInsets hitTestEdgeInsets; @end @implementation CustomHitAreaButton - (instancetype)initWithFrame:(CGRect)frame { if(self = [super initWithFrame:frame]) { self.hitTestEdgeInsets = UIEdgeInsetsZero; } return self; } -(void)setHitTestEdgeInsets:(UIEdgeInsets)hitTestEdgeInsets { self->_hitTestEdgeInsets = hitTestEdgeInsets; } - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { if(UIEdgeInsetsEqualToEdgeInsets(self.hitTestEdgeInsets, UIEdgeInsetsZero) || !self.enabled || self.hidden) { return [super pointInside:point withEvent:event]; } CGRect relativeFrame = self.bounds; CGRect hitFrame = UIEdgeInsetsInsetRect(relativeFrame, self.hitTestEdgeInsets); return CGRectContainsPoint(hitFrame, point); } @end 

ओवरराइड विरासत में मिली UIButton के माध्यम से कार्यान्वयन

स्विफ्ट 2.2 :

 // don't forget that negative values are for outset _button.hitOffset = UIEdgeInsets(top: -10, left: -10, bottom: -10, right: -10) ... class UICustomButton: UIButton { var hitOffset = UIEdgeInsets() override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool { guard hitOffset != UIEdgeInsetsZero && enabled && !hidden else { return super.pointInside(point, withEvent: event) } return UIEdgeInsetsInsetRect(bounds, hitOffset).contains(point) } } 

WJBackgroundInsetButton.h

 #import <UIKit/UIKit.h> @interface WJBackgroundInsetButton : UIButton { UIEdgeInsets backgroundEdgeInsets_; } @property (nonatomic) UIEdgeInsets backgroundEdgeInsets; @end 

WJBackgroundInsetButton.m

 #import "WJBackgroundInsetButton.h" @implementation WJBackgroundInsetButton @synthesize backgroundEdgeInsets = backgroundEdgeInsets_; -(CGRect) backgroundRectForBounds:(CGRect)bounds { CGRect sup = [super backgroundRectForBounds:bounds]; UIEdgeInsets insets = self.backgroundEdgeInsets; CGRect r = UIEdgeInsetsInsetRect(sup, insets); return r; } @end 

कभी श्रेणी में विधि को ओवरराइड न करें उपवर्ग बटन और ओवरराइड - pointInside:withEvent: :। उदाहरण के लिए यदि आपके बटन की तरफ 44 पिक्सल से कम है (जो कि न्यूनतम टेपबल क्षेत्र के रूप में अनुशंसित है) इसका प्रयोग करें:

 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { return (ABS(point.x - CGRectGetMidX(self.bounds)) <= MAX(CGRectGetMidX(self.bounds), 22)) && (ABS(point.y - CGRectGetMidY(self.bounds)) <= MAX(CGRectGetMidY(self.bounds), 22)); } 

मैंने इस उद्देश्य के लिए एक पुस्तकालय बनाया है

आप एक UIView श्रेणी का उपयोग करना चुन सकते हैं, कोई उप-क्लासिंग आवश्यक नहीं है :

 @interface UIView (KGHitTesting) - (void)setMinimumHitTestWidth:(CGFloat)width height:(CGFloat)height; @end 

या आप अपने UIView या UIButton subclass कर सकते हैं और minimumHitTestWidth और / या minimumHitTestHeight सेट तब आपके बटन हिट-टेस्ट क्षेत्र का प्रतिनिधित्व इन 2 मानों द्वारा किया जाएगा।

बस अन्य समाधानों की तरह, यह - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event का उपयोग करता है - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event विधि विधि कहा जाता है जब आईओएस हिट-टेस्टिंग करता है। इस ब्लॉग पोस्ट में आईओएस हिट-टेस्टिंग काम करने पर अच्छा विवरण दिया गया है।

https://github.com/kgaidis/KGHitTestingViews

 @interface KGHitTestingButton : UIButton <KGHitTesting> @property (nonatomic) CGFloat minimumHitTestHeight; @property (nonatomic) CGFloat minimumHitTestWidth; @end 

आप कोई भी कोड लिखे बिना इंटरफ़ेस बिल्डर का उप-वर्ग और उपयोग भी कर सकते हैं: यहां छवि विवरण दर्ज करें

मैं tableviewcell.accessoryView के अंदर बटन के लिए इस चाल का उपयोग अपने स्पर्श क्षेत्र को विस्तारित करने के लिए कर रहा हूँ

 #pragma mark - Touches - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint location = [touch locationInView:self]; CGRect accessoryViewTouchRect = CGRectInset(self.accessoryView.frame, -15, -15); if(!CGRectContainsPoint(accessoryViewTouchRect, location)) [super touchesBegan:touches withEvent:event]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint location = [touch locationInView:self]; CGRect accessoryViewTouchRect = CGRectInset(self.accessoryView.frame, -15, -15); if(CGRectContainsPoint(accessoryViewTouchRect, location) && [self.accessoryView isKindOfClass:[UIButton class]]) { [(UIButton *)self.accessoryView sendActionsForControlEvents:UIControlEventTouchUpInside]; } else [super touchesEnded:touches withEvent:event]; } 

मैं बस @ चाज समाधान के बंदरगाह में तेजी से 2.2 था

 import Foundation import ObjectiveC private var hitTestEdgeInsetsKey: UIEdgeInsets = UIEdgeInsetsZero extension UIButton { var hitTestEdgeInsets:UIEdgeInsets { get { let inset = objc_getAssociatedObject(self, &hitTestEdgeInsetsKey) as? NSValue ?? NSValue(UIEdgeInsets: UIEdgeInsetsZero) return inset.UIEdgeInsetsValue() } set { let inset = NSValue(UIEdgeInsets: newValue) objc_setAssociatedObject(self, &hitTestEdgeInsetsKey, inset, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } public override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool { guard !UIEdgeInsetsEqualToEdgeInsets(hitTestEdgeInsets, UIEdgeInsetsZero) && self.enabled == true && self.hidden == false else { return super.pointInside(point, withEvent: event) } let relativeFrame = self.bounds let hitFrame = UIEdgeInsetsInsetRect(relativeFrame, hitTestEdgeInsets) return CGRectContainsPoint(hitFrame, point) } } 

एक आप इस तरह उपयोग कर सकते हैं

 button.hitTestEdgeInsets = UIEdgeInsetsMake(-10, -10, -10, -10) 

किसी भी अन्य संदर्भ के लिए https://stackoverflow.com/a/13067285/1728552 देखें

ऊपर गीतात्स के उत्तर पर आधार (जो मुझे सबसे खूबसूरत समाधान मिला), यहां तेज 3 संस्करण है:

 import UIKit fileprivate let minimumHitArea = CGSize(width: 44, height: 44) extension UIButton { open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { // if the button is hidden/disabled/transparent it can't be hit if isHidden || !isUserInteractionEnabled || alpha < 0.01 { return nil } // increase the hit frame to be at least as big as `minimumHitArea` let buttonSize = bounds.size let widthToAdd = max(minimumHitArea.width - buttonSize.width, 0) let heightToAdd = max(minimumHitArea.height - buttonSize.height, 0) let largerFrame = bounds.insetBy(dx: -widthToAdd / 2, dy: -heightToAdd / 2) // perform hit test on larger frame return (largerFrame.contains(point)) ? self : nil } } 

मैंने चेस की प्रतिक्रिया का पालन किया है और यह एक महान समस्या है, जब आप एरिया को बहुत बड़ा बनाते हैं, जो ज़ोन से बड़ा होता है जहां बटन को अचयनित नहीं किया जाता है (यदि ज़ोन बड़ा नहीं था) तो यह यूआईसीआईटीओएलएलईवेंट टचअप इनसाइड इवेंट के लिए चयनकर्ता को कॉल नहीं करता है ।

मुझे लगता है कि आकार 200 से अधिक है, किसी भी दिशा या ऐसा कुछ।

मैं इस खेल को बहुत देर कर रहा हूं, लेकिन एक साधारण तकनीक पर तौलना चाहता हूं जो आपकी समस्याओं को हल कर सके। मेरे लिए यहां एक विशिष्ट प्रोग्राममैटिक UIButton स्निपेट है:

 UIImage *arrowImage = [UIImage imageNamed:@"leftarrow"]; arrowButton = [[UIButton alloc] initWithFrame:CGRectMake(15.0, self.frame.size.height-35.0, arrowImage.size.width/2, arrowImage.size.height/2)]; [arrowButton setBackgroundImage:arrowImage forState:UIControlStateNormal]; [arrowButton addTarget:self action:@selector(onTouchUp:) forControlEvents:UIControlEventTouchUpOutside]; [arrowButton addTarget:self action:@selector(onTouchDown:) forControlEvents:UIControlEventTouchDown]; [arrowButton addTarget:self action:@selector(onTap:) forControlEvents:UIControlEventTouchUpInside]; [arrowButton addTarget:self action:@selector(onTouchUp:) forControlEvents:UIControlEventTouchDragExit]; [arrowButton setUserInteractionEnabled:TRUE]; [arrowButton setAdjustsImageWhenHighlighted:NO]; [arrowButton setTag:1]; [self addSubview:arrowButton]; 

मैं अपने बटन के लिए एक पारदर्शी पीएनजी छवि लोड कर रहा हूं और पृष्ठभूमि छवि सेट कर रहा हूं। मैं UIImage और रेटिना के लिए 50% की स्केलिंग के आधार पर फ्रेम की स्थापना कर रहा हूँ। ठीक है, हो सकता है कि आप ऊपर या नहीं से सहमत हों, लेकिन अगर आप हिट क्षेत्र को बड़ा बनाना चाहते हैं और अपने आप को सिरदर्द बचाने के लिए चाहते हैं:

मैं क्या करता हूं, फ़ोटो को फ़ोटोशॉप में खोलें और बस कैनवास के आकार में 120% तक बढ़ो और बचाओ। प्रभावी रूप से आपने छवि को पारदर्शी पिक्सल के साथ बड़ा बना दिया है

सिर्फ एक दृष्टिकोण

@jlajlar का जवाब ऊपर लग रहा था अच्छा और सीधा है लेकिन यह Xamarin.iOS से मेल नहीं खाता है, इसलिए मैं इसे Xamarin में परिवर्तित कर दिया। यदि आप एक्सरामिन आईओएस पर एक समाधान की तलाश कर रहे हैं, तो यहां यह जाता है:

 public override bool PointInside (CoreGraphics.CGPoint point, UIEvent uievent) { var margin = -10f; var area = this.Bounds; var expandedArea = area.Inset(margin, margin); return expandedArea.Contains(point); } 

आप इस पद्धति को उस कक्षा में जोड़ सकते हैं जहां आप ओवरव्राइड यूआईवीयूवी या यूआईएमएजेव्यू देखें। यह अच्छी तरह से काम किया 🙂

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

इसके बजाय, मैं पीएनजी पारदर्शी क्षेत्र को बड़ा बनाकर नल क्षेत्र को बड़ा करता हूं I

यह स्विफ्ट संस्करण आपको सभी UIButtons के लिए न्यूनतम हिट आकार को परिभाषित करने देता है महत्वपूर्ण, यह भी मामले को संभालता है जब UIButtons छिपे हुए हैं, जो कई जवाबों की उपेक्षा करते हैं

 extension UIButton { public override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? { // Ignore if button hidden if self.hidden { return nil } // If here, button visible so expand hit area let hitSize = CGFloat(56.0) let buttonSize = self.frame.size let widthToAdd = (hitSize - buttonSize.width > 0) ? hitSize - buttonSize.width : 0 let heightToAdd = (hitSize - buttonSize.height > 0) ? hitSize - buttonSize.height : 0 let largerFrame = CGRect(x: 0-(widthToAdd/2), y: 0-(heightToAdd/2), width: buttonSize.width+widthToAdd, height: buttonSize.height+heightToAdd) return (CGRectContainsPoint(largerFrame, point)) ? self : nil } } 
  • श्रेणियों या एक्सटेंशन में ओवरराइड किए बिना
  • 44×44 न्यूनतम प्रति निर्देश

मेरा स्वीकार कर लेना:

 open class MinimumTouchAreaButton: UIButton { open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { guard !self.isHidden, self.isUserInteractionEnabled, self.alpha > 0 else { return nil } let expandedBounds = bounds.insetBy(dx: min(bounds.width - 44, 0), dy: min(bounds.height - 44, 0)) return expandedBounds.contains(point) ? self : nil } }