美文网首页
【iOS】UIButton超出父视图点击无效(swift)

【iOS】UIButton超出父视图点击无效(swift)

作者: Qire_er | 来源:发表于2021-12-02 11:21 被阅读0次

写在前面的:

有时候,我们需要将响应事件的子view视图,超出父view视图的范围。但是在默认情况下,超出去的部分,是无法响应事件的!……

重现效果:

动图演示

解决方法:

  1. 扩大父view视图区域(呵呵)
  2. 重写父view的hitTest(_:with:)方法

对于第一种方法,很多时候是最简单粗暴,但有时我们UI设计确实需要子视图超过父视图的效果,那么就可以尝试用第二种方法!

官方定义:

- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;   // recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system

官方解释:
返回视图层级结构(包括其自身)中,包含指定点的事件接收者最远的子视图。(真晦涩!)

Returns the farthest descendant of the receiver in the view hierarchy (including itself) that contains a specified point.

一般会跟另一个方法结合使用:(检测当前事件触发点是否在指定视图里面)

- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;   // default returns YES if point is in bounds

演示代码:

页面定义部分

//
//  HitTestView.swift
//  UIKit-basic
//
//  Created by Qire_er on 2021/12/1.
//

import UIKit

class HitTestView: UIView {
    
    var button: UIButton! // 定义【按钮】控件
    var count: Int = 0 // 定义【点击】数
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        let rect = frame.insetBy(dx: 40, dy: -30) // 设置收缩量
        self.button = UIButton(frame: CGRect(x: 0, y: 0, width: rect.width, height: rect.height)) // 创建【按钮】实例
        self.button.setTitle("测试:0", for: .normal) // 定义【按钮】显示文本
        self.button.addTarget(self, action: #selector(click), for: .touchUpInside) // 定义【按钮】点击事件处理函数
        
        self.button.backgroundColor = UIColor.blue.withAlphaComponent(0.85) // 设置【按钮】背景色
        addSubview(self.button) // 添加【按钮】视图
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    // 定义【点击】事件处理函数
    @objc func click() {
        self.count += 1 // 更新【点击】数
        self.button.setTitle("测试:\(count)", for: .normal) // 更新【按钮】显示文本
    }
    
    // 重写 hitTest 方法
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        var view = super.hitTest(point, with: event) // 获取上一级view
        
        let ePoint = self.button.convert(point, from: self) // 将事件触发点point的坐标转换为button自己的坐标
        
        // 检测事件触发点point是否在button的内部
        let isInside = self.button.point(inside: ePoint, with: event)
        if isInside {
            // 如果在button内部
            view = self.button // 就将button作为事件的第一响应者
        }
        return view
    }
}

控制器使用部分

//
//  HitTestCV.swift
//  UIKit-basic
//
//  Created by Qire_er on 2021/12/1.
//

import UIKit

class HitTestCV: UIViewController {
    
    var contView: UIView! // 定义【容器】视图
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let width = UIScreen.main.bounds.width // 定义【屏幕】宽度
        let height = UIScreen.main.bounds.height // 定义【屏幕】高度
        let contWidth: CGFloat = 200 // 定义【容器】宽度
        let contHeight: CGFloat = 60 // 定义【容器】视图
        let offsetY: CGFloat = 45 // 定义【容器】Y轴偏移量

        
        self.contView = HitTestView(frame: CGRect(x: (width - contWidth) / 2, y: (height - contHeight) / 2 - offsetY, width: contWidth, height: contHeight))
        self.contView.backgroundColor = UIColor.orange // 设置【容器】背景色
        
        self.view.addSubview(self.contView) // 添加【容器】到【主视图】
        self.view.backgroundColor = UIColor.white // 设置底色为白色,否则黑区区一片!
    }
}

(==完==)

ps: 以上仅代表个人浅见,请大佬们指正!-

相关文章

网友评论

      本文标题:【iOS】UIButton超出父视图点击无效(swift)

      本文链接:https://www.haomeiwen.com/subject/zwjyxrtx.html