Sve*_*uer 50 objective-c uibutton ios swift
我使用UIButton自动布局.当图像很小时,点击区域也很小.我可以想象几种方法来解决这个问题:
除了上述两种方法之外,是否有更好的解决方案来增加UIButton的抽头区域?
Tra*_*vis 53
您只需调整按钮的内容插入即可获得所需的大小.在代码中,它看起来像这样:
button.contentEdgeInsets = UIEdgeInsets(上:12,左:16,下:12,右:16)
//或者如果您特别想调整图像,请使用button.imageEdgeInsets
在界面构建器中,它将如下所示:

Sye*_*had 24
很容易.创建自定义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
Run Code Online (Sandbox Code Playgroud)
每侧需要10点以上的触摸区域.
小智 9
您可以在故事板中或通过代码设置按钮EdgeInsets.按钮的大小和高度应该比设置为按钮的图像大.
注意:在Xcode8之后,设置内容inset在尺寸检查中可用

或者您也可以使用带有点按手势的图像视图进行操作,同时在图像视图上进行操作.确保在故事板上勾选用户图像视图的用户交互,以便手势正常工作.使图像视图大于要在其上设置的图像并在其上设置图像.现在将图像视图图像的模式设置为storyboard /界面构建器的中心.
希望它会有所帮助.
我确认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")
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
这应该工作
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)
}
}
Run Code Online (Sandbox Code Playgroud)
关于边缘插入的一些上下文答案。
当使用自动布局与内容边缘插入相结合时,您可能需要更改约束。
假设您有一个 10x10 的图像,并且希望将其设为 30x30 以获取更大的点击区域:
将自动布局约束设置为所需的更大区域。如果你现在就构建,这会拉伸图像。
使用内容边缘插图缩小图像可用的空间,使其匹配正确的尺寸。在本例中,结果为 10 10 10 10。为图像留出 10x10 的空间来绘制自身。
赢。
小智 5
基于 Syed 的答案的 Swift 5 版本(更大区域的负值):
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return bounds.insetBy(dx: -10, dy: -10).contains(point)
}
Run Code Online (Sandbox Code Playgroud)
或者:
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return bounds.inset(by: UIEdgeInsets(top: -5, left: -5, bottom: -5, right: -5)).contains(point)
}
Run Code Online (Sandbox Code Playgroud)
我的方法是在小图像周围为按钮提供一些额外的空间contentEdgeInsets(其作用就像按钮内容之外的边距),但也alignmentRect使用相同的插图覆盖该属性,这会将自动布局使用的矩形带回来到图像中。这确保自动布局使用较小的图像而不是按钮的完整可点击范围来计算其约束。
class HIGTargetButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func setImage(_ image: UIImage?, for state: UIControl.State) {
super.setImage(image, for: state)
guard let image = image else { return }
let verticalMarginToAdd = max(0, (targetSize.height - image.size.height) / 2)
let horizontalMarginToAdd = max(0, (targetSize.width - image.size.width) / 2)
let insets = UIEdgeInsets(top: verticalMarginToAdd,
left: horizontalMarginToAdd,
bottom: verticalMarginToAdd,
right: horizontalMarginToAdd)
contentEdgeInsets = insets
}
override var alignmentRectInsets: UIEdgeInsets {
contentEdgeInsets
}
private let targetSize = CGSize(width: 44.0, height: 44.0)
}
Run Code Online (Sandbox Code Playgroud)
粉色按钮有一个更大的可点击目标(此处显示为粉色,但也可以是.clear)和一个较小的图像 - 它的前缘根据图标而不是整个按钮与绿色视图的前缘对齐。
这里提出的两种解决方案都可以工作......在适当的情况下。但这里有一些您可能会遇到的问题。首先是一些不完全明显的事情:
具体针对上述解决方案:
使用 contentEdgeInsets 增加按钮大小而不增加图标/文本大小,类似于添加 padding
button.contentEdgeInsets = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
Run Code Online (Sandbox Code Playgroud)
这个很简单,增加按钮尺寸会增加点击面积。
子类 UIButton 并覆盖point(inside point: CGPoint, with event: UIEvent?) -> Bool
class BigAreaButton: UIButton {
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return bounds.insetBy(dx: -20, dy: -20).contains(point)
}
}
Run Code Online (Sandbox Code Playgroud)
这个解决方案很棒,因为它允许您将点击区域扩展到视图边界之外,而无需更改布局,但有以下问题:
---------
| |
|oooo |
|oXXo |
|oXXo |
|oooo | Button-X nested in View-o will NOT extend beyond View-o
---------
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
27578 次 |
| 最近记录: |