ios 如何增加 UIButton 的点击区域?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31056703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I increase the Tap Area for UIButton?
提问by Sven Bauer
I use UIButton
with auto layout. When images are small the tap area is also small. I could imagine several approaches to fix this:
我使用UIButton
自动布局。当图像很小时,点击区域也很小。我可以想象几种方法来解决这个问题:
- increase the image size, i.e., place a transparent area around the image. This is not good because when you position the image you have to keep the extra transparent border in mind.
- use CGRectInset and increase the size. This does not work well with auto layout because using auto layout it will fall back to the original image size.
- 增加图像大小,即在图像周围放置一个透明区域。这不好,因为当您定位图像时,您必须牢记额外的透明边框。
- 使用 CGRectInset 并增加大小。这不适用于自动布局,因为使用自动布局它会回退到原始图像大小。
Beside the two approaches above is there a better solution to increase the tap area of a UIButton?
除了上述两种方法之外,是否有更好的解决方案来增加 UIButton 的点击区域?
回答by Travis
You can simply adjust the content inset of the button to get your desired size. In code, it will look like this:
您可以简单地调整按钮的内容插入以获得所需的大小。在代码中,它将如下所示:
button.contentEdgeInsets = UIEdgeInsets(top: 12, left: 16, bottom: 12, right: 16)
//Or if you specifically want to adjust around the image, instead use button.imageEdgeInsets
In interface builder, it will look like this:
在界面生成器中,它将如下所示:
回答by Syed Sadrul Ullah Sahad
Very easy. Create a custom UIButton class. Then override pointInside... method and change the value as you want.
好简单。创建自定义 UIButton 类。然后覆盖 pointInside... 方法并根据需要更改值。
#import "CustomButton.h"
@implementation CustomButton
-(BOOL) pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
CGRect newArea = CGRectMake(self.bounds.origin.x - 10, self.bounds.origin.y - 10, self.bounds.size.width + 20, self.bounds.size.height + 20);
return CGRectContainsPoint(newArea, point);
}
@end
It will take more 10 points touch area for every side.
每边将需要更多的 10 点接触区域。
回答by Glenn
I confirm that Syed's solution works well even with autolayout. Here's the Swift 4.x version:
我确认 Syed 的解决方案即使使用自动布局也能很好地工作。这是 Swift 4.x 版本:
import UIKit
class BeepSmallButton: UIButton {
// MARK: - Functions
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let newArea = CGRect(
x: self.bounds.origin.x - 5.0,
y: self.bounds.origin.y - 5.0,
width: self.bounds.size.width + 10.0,
height: self.bounds.size.height + 20.0
)
return newArea.contains(point)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
回答by user2094867
You can set the button EdgeInsets in storyboard or via code. The size of button should be bigger in height and width than image set to button.
您可以在情节提要中或通过代码设置按钮 EdgeInsets。按钮的高度和宽度应大于设置为按钮的图像。
Note: After Xcode8, setting content inset is available in size inspecor
注意:Xcode8 之后,size inspecor 中可以设置 content inset
Or you can also use image view with tap gesture on it for action while taping on image view. Make sure to tick User Interaction Enabled for imageview on storyboard for gesture to work. Make image view bigger than image to set on it and set image on it. Now set the mode of image view image to center on storyboard/interface builder.
或者您也可以在点击图像视图时使用带有点击手势的图像视图进行操作。确保为情节提要上的图像视图勾选用户交互已启用以使手势工作。使图像视图大于要在其上设置的图像并在其上设置图像。现在将图像视图图像的模式设置为故事板/界面构建器的中心。
You can tap on image to do action.
Hope it will be helpful.
希望它会有所帮助。
回答by Hyman
Swift 4 ? Xcode 9
斯威夫特 4 ? Xcode 9
You can select programmatically as -
您可以以编程方式选择 -
For Image -
对于图像 -
button.imageEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
For Title -
对于标题 -
button.titleEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
回答by Alex
This should work
这应该工作
import UIKit
@IBDesignable
class GRCustomButton: UIButton {
@IBInspectable var margin:CGFloat = 20.0
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
//increase touch area for control in all directions by 20
let area = self.bounds.insetBy(dx: -margin, dy: -margin)
return area.contains(point)
}
}
回答by Lucas Chwe
Subclass UIButton
and add this function
子类化UIButton
并添加此函数
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let verticalInset = CGFloat(10)
let horizontalInset = CGFloat(10)
let largerArea = CGRect(
x: self.bounds.origin.x - horizontalInset,
y: self.bounds.origin.y - verticalInset,
width: self.bounds.size.width + horizontalInset*2,
height: self.bounds.size.height + verticalInset*2
)
return largerArea.contains(point)
}
回答by Kevin Kruusi
Some context about the edge insets answer.
关于边缘插入答案的一些上下文。
When using auto layout combined with content edge insets you may need to change your constraints.
当使用自动布局结合内容边缘插入时,您可能需要更改约束。
Say you have a 10x10 image and you want to make it 30x30 for a larger hit area:
假设您有一个 10x10 的图像,并且您希望将其设为 30x30 以获得更大的命中区域:
Set your auto layout constraints to the desired larger area. If you build right now this would stretch the image.
Using the content edge insets to shrink the space available to the image so it matches the correct size. In this Example that would 10 10 10 10. Leaving the image with a 10x10 space to draw itself in.
Win.
将自动布局约束设置为所需的更大区域。如果您现在构建,这会拉伸图像。
使用内容边缘插入缩小图像可用的空间,使其匹配正确的大小。在这个例子中,这将是 10 10 10 10。给图像留下一个 10x10 的空间来绘制自己。
赢。
回答by Trident
I am not sure, but there should be a way to specify minimum size for any UIView, that might solve your problem with out extra work. But honestly, adding extra transparent background around the image is the best solution.
我不确定,但应该有一种方法可以为任何 UIView 指定最小大小,这可能会解决您的问题而无需额外工作。但老实说,在图像周围添加额外的透明背景是最好的解决方案。