如何增加UIButton的选择区域?

28

我已经以编程方式创建了 UIButton

togglebutton = [UIButton buttonWithType:UIButtonTypeCustom];
togglebutton.frame = CGRectMake(42, 15, 80, 21);
[togglebutton addTarget:self action:@selector(toggleview)   
forControlEvents:UIControlEventTouchUpInside];
[togglebutton setImage:[UIImage imageNamed:@"squ.png"] forState:UIControlStateNormal];
[buttonView addSubview:togglebutton];

输入图像描述

它被看作是上图中的右侧按钮。现在的要求是该按钮的选择区域应该比uibutton图像更大,以便用户可以通过触摸特定按钮附近的区域轻松点击该按钮。

[togglebutton setImageEdgeInsets: UIEdgeInsetsMake( 0, -30, 0, -25)];

我试图设置图像嵌入,但它使得图片不规则。请查看这个问题。


您是如何选择这些插图的,还尝试了哪些其他值? - Wain
看这个,尝试更改按钮图像的视图模式,然后它应该与插入和图像一起工作 - http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/WindowsandViews/WindowsandViews.html - Dominik Hadl
@Wain 我设置了图像插入,使其与按钮和图像大小的差异相匹配。 - Minkle Garg
可能是重复的问题:UIButton:如何使触控区域大于默认值? - kgaidis
我推荐这个答案uibutton-making-the-hit-area-larger-than-the-default-hit-area。也许它能帮助我们大多数人。 - guozqzzu
也许可以帮到你,我的Swift 3解决方案:https://dev59.com/2HRA5IYBdhLWcg3w1BmW#45436719 - Janserik
9个回答

47

您可以通过设置按钮的contentEdgeInsets来实现此目的,例如:

toggleButton.contentEdgeInsets = UIEdgeInsetsMake(0, 15, 0, 0); //set as you require 

6
根据财产声明,您需要负值来增加选择区域。利用此属性来调整按钮内容的有效绘图矩形的大小和位置。内容包括按钮图像和按钮标题。您可以为四个插入量(上、左、下、右)中的每个指定不同的值。正值会缩小或插入该边缘-将其移动到按钮的中心。负值会扩展或突出该边缘。 - kevinl
您也可以直接在Xcode GUI的Storyboard中设置此项。要这样做,请选择您想要的按钮并选择“Identity Inspector”,然后添加一个名为“contentEdigeInsets”的“User Define Runtime Attribute”,类型为“Rect”。有时这比在代码中完成更方便。 - Amos Joshua
1
请注意:正值会增加按钮的可点击区域。 - duncanc4
另外补充一点,我刚刚增加了按钮大小,然后设置了UIEdgeInsets为增加的正数值。 - green0range

18

对于Swift,您可以重写UIView类的函数'pointInside'来扩展可点击区域。

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
    // padding : local variable of your custom UIView, CGFloat
    // you can change clickable area dynamically by setting this value.

    let newBound = CGRect(
        x: self.bounds.origin.x - padding,
        y: self.bounds.origin.y - padding,
        width: self.bounds.width + 2 * padding,
        height: self.bounds.height + 2 * padding
    )
    return CGRectContainsPoint(newBound, point)
}

像这样使用:

class MyButton: UIButton {
    var padding = CGFloat(0) // default value

    //func pointInside at here!!
}
当您初始化按钮时,请设置自定义填充。
func initButton() {
    let button = MyButton(frame: CGRect(x: 100, y: 100, width: 30, height: 30))
    button.padding = 10 // any value you want
    view.addSubview(button)
}

然后您的按钮位于帧内(x:100,y:100,宽度:30,高度:30)

并且您的按钮的可点击区域可能在具有(x:90,y:90,宽度:50,高度:50)的框架中

**一定要检查与任何其他视图的重叠情况,因为其可点击区域比外观更大。

更新Swift 3

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    let padding = CGFloat(10)
    let extendedBounds = bounds.insetBy(dx: -padding, dy: -padding)
    return extendedBounds.contains(point)
}

4
这是使用自动布局的理想解决方案。 - GoldenJoe
也是那些需要调整按钮图像而不影响点击区域大小的理想解决方案。 - Charlton Provatas
即使方法 pointInside(point:with:) 返回 true,选择器仍未被调用。 - Saif

3
尝试使用UIButton的contentEdgeInsets属性。具体请参考UIButton文档

3
在Xcode 9中,您可以执行以下操作:

xcode 9 screenshot

这意味着您需要补偿图像偏移和内容偏移,以确保图像居中定位。

2
以下代码解决了我的问题。这是一种非常基本的方法,可以尝试一下:
    button.contentEdgeInsets = UIEdgeInsetsMake(15, 20, 10, 10);  //Change x,y,width,height as per your requirement.

1

针对Objective C

创建这个自定义的UIButton类并将其分配到你的按钮中。然后从viewController设置这些属性值。

//This is .h file
     #import <UIKit/UIKit.h>
        @interface CustomButton : UIButton
        @property (nonatomic) CGFloat leftArea;
        @property (nonatomic) CGFloat rightArea;
        @property (nonatomic) CGFloat topArea;
        @property (nonatomic) CGFloat bottomArea;
        @end



        //.m file is following
        #import "CustomButton.h
        @implementation CustomButton

        -(BOOL) pointInside:(CGPoint)point withEvent:(UIEvent *)event
        {
            CGRect newArea = CGRectMake(self.bounds.origin.x - _leftArea, self.bounds.origin.y - _topArea, self.bounds.size.width + _leftArea + _rightArea, self.bounds.size.height + _bottomArea + _topArea);

            return CGRectContainsPoint(newArea, point);
        }
        @end

0
在我的情况下,我的按钮图像很小,我想增加按钮区域,而不增加 uibutton 图像大小,因为它会看起来模糊。所以我增加了按钮框架,然后设置了按钮图像的 setImageEdgeInsets。正值的 edgeInsets 会缩小,负值会扩展。
self.menuButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.menuButton addTarget:self
                  action:@selector(onSideBarButtonTapped:)
        forControlEvents:UIControlEventTouchDown];
[self.menuButton setImage:[UIImage imageNamed:@"menu"]
                         forState:UIControlStateNormal];
self.menuButton.frame = CGRectMake(10, 3, 40, 40);

现在我要缩小图像尺寸,这样按钮就不会看起来模糊了。

[self.menuButton setImageEdgeInsets:UIEdgeInsetsMake(10, 10, 10, 10)];

-2
这是一个增加自定义UIButton可触摸区域的示例:
UIImage *ButtonImage=[UIImage imageNamed:@"myimage.png"];
UIButton *myButton=[UIButton buttonWithType:UIButtonTypeCustom];
myButton.frame=CGRectMake(10, 25, ButtonImage.size.width/2+10, ButtonImage.size.height/2+10);
[myButton setImage:ButtonImage forState:UIControlStateNormal];
myButton.imageEdgeInsets = UIEdgeInsetsMake(5, 5, 5, 5);
[myButton addTarget:self action:@selector(crossButtonClick:) forControlEvents:UIControlEventTouchDown];
[self.view addSubview:myButton];

希望这对你有所帮助。


-2
我会在该按钮周围创建一个UIView,这样您就可以将其大小设置为任何您想要的尺寸。然后,我会将UIView的背景颜色设置为透明色(不要将不透明度设置为0,否则手势无法被识别)。
然后,在uiview中添加一个UIGestureRecognizer来处理相同的IBAction。
当然,许多人会鼓励/更喜欢使用edgeInsets。

1
这绝对不是解决该问题的正确方式。 - cmyr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接