東引甌越

不断学习, 与时俱进.

嗨,我是孙亚洲(@sunyazhou13),一名来自北国冰城的iOS开发者,也搞过一些mac.现居帝都北京.开发数年有余,没有为往圣续绝学深感惭愧,始于2016.望诸位同仁多多指教.


iOS扩大UIButton的点击的响应范围

前言

开发过程中经常遇到UIButton点击区域太小 又不想 改动按钮的大小.

今天的文章和大家分享一下解决这种问题的代码

实现思路

  • 子类话UIButton 复写 它的hitTest:方法
  • 子类话UIButton 复写 point:inside:withEvent: 方法

第一种方式

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let biggerButtonFrame = theButton.frame.insetBy(dx: -30, dy: -30) // 1
if biggerButtonFrame.contains(point) { // 2
return theButton // 3
}
return super.hitTest(point, with: event) // 4
}
    1. 让theButton的 x 扩大 30, y 扩大 30 (正数为缩小 负数为放大. 然后宽高 分别是2 30和 2 30)
    1. 判断点击的位置是否在放大完的frame内.
    1. 如果是 就返回button
    1. 不是的话让事件继续传递

注意:这里没判断 theButton.alpha == 0 和 theButton.userInterface.. == YES 还有它是否可见之类的,请自行判断

第二种方式

复写UIView的point:方法

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

OC的版本是这样

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
//这里写上
CGRectInset(<#CGRect rect#>, <#CGFloat dx#>, <#CGFloat dy#>)
...
}

但是 第二种方式 其实 是 hitTest:方法调用之前UIView的判断,它判断当前点击的point是否在这个UIView上.

不过 还是推荐第一种方式

核心代码

其实 最核心的代码是

CGRectInset(<#CGRect rect#>, <#CGFloat dx#>, <#CGFloat dy#>)

CGRect CGRectOffset(CGRect rect, CGFloat dx, CGFloat dy)是以rect为中心,根据dx和dy来实现缩小。

如果dx 和 dy是负数 则放大 ,正数则缩小

但是大家可能很疑惑 那宽度和高度怎么 缩小放大

首先: 我们明确 这个API的含义 只要传入正数 它就缩放 那么 宽高也会适当前传入的dx和dy来决定 缩放比

因为是中心点缩放 所以宽高 要 X 2,因为有两侧嘛,左侧缩小30右侧也需要缩小30,上部和底部是一样的.

大家可自行查阅google看下

参考Increasing the tap area of a UIButton
参考 iOS触摸事件全家桶

全文完

最近的文章

iOS呼吸动画

前言快放假了, 怕十一文章更新不及时,早点完成文章,保证每个月 2篇的产出量, 今天给大家带来的是 呼吸动画, 做的不是特别好. 上图 大概是这个样子 需求和实现思路具体要求 内部头像呼吸放大缩小 无限循环 每次放大同时需要背景还有一张图也放大 并且透明 点击缩放整个背景视图 实现思路首先 …

于  iOS开发, macOS开发 继续阅读
更早的文章

iOS键盘动画细节

前言很久没写技术文章里,本篇记录了一下一个键盘弹出的小细节动画,像微信一样流程 上图 动画细节代码细节核心主要是通知中的一些key 动画时长 动画的出现方式 … 下面的通知是接收 键盘将要出现的通知UIKeyboardWillShowNotification [[NSNotification …

于  iOS开发, macOS开发 继续阅读