4

我已经设置了UIButton背景图片并在上面加上了一个标题(我使用了setBackgroundImagenot 方法setImage)。现在我想扩大 a 的 hitTest 区域UIButton而不挤压它的背景图像。

我怎样才能做到这一点?

4

5 回答 5

6

一种更简洁的方法是覆盖 pointInside。

这是一个 Swift 版本:

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
    let expandedBounds = CGRectInset(self.bounds, -15, -15)
    return CGRectContainsPoint(expandedBounds, point)
}
于 2014-11-24T07:18:47.043 回答
5

这是已接受答案的更正版本。我们使用bounds代替frameCGRectInset代替CGRectMake。更清洁,更可靠。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    return CGRectContainsPoint([self expandedBounds], point) ? self : nil;
}

- (CGRect)expandedBounds {
    return CGRectInset(self.bounds, -20, -20);
}
于 2013-12-12T13:36:55.457 回答
2

此版本允许您定义所有 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
    }
}
于 2016-06-21T01:51:26.107 回答
1

好吧,你可以扩展 UIButton 并覆盖 UIView 的 hitTest 方法:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    int expandMargin = 20;
    CGRect extendedFrame = CGRectMake(0 - expandMargin , 0 - expandMargin , self.bounds.size.width + (expandMargin * 2) , self.bounds.size.height + (expandMargin * 2));
    return (CGRectContainsPoint(extendedFrame , point) == 1) ? self : nil;
}
于 2012-09-06T10:14:43.897 回答
0

我为此目的制作了一个图书馆

您可以选择使用类别,无需子类化

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

或者您可以继承您的 UIView 或 UIButton 并设置minimumHitTestWidth和/或minimumHitTestHeight. 然后,您的按钮命中测试区域将由这 2 个值表示。

就像其他解决方案一样,它使用该- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event方法。该方法在 iOS 执行命中测试时被调用。这篇博文很好地描述了 iOS 命中测试的工作原理。

https://github.com/kgaidis/KGHitTestingViews

@interface KGHitTestingButton : UIButton <KGHitTesting>

@property (nonatomic) CGFloat minimumHitTestHeight; 
@property (nonatomic) CGFloat minimumHitTestWidth;

@end

您也可以只继承并使用 Interface Builder 而无需编写任何代码: 在此处输入图像描述

于 2016-10-29T02:01:02.120 回答