美文网首页ios常用功能
swift扩大UIButton或者UIView的点击区域

swift扩大UIButton或者UIView的点击区域

作者: 苍眸之宝宝 | 来源:发表于2020-06-08 09:41 被阅读0次

    1.使用场景

    在界面中,有些按钮和视图的区域比较小,用户难以准确的触摸到该区域;为了方便用户的操作,在不改变frame的前提下,扩大它的点击事件相应区域。

    2.扩大它的点击事件相应区域方法

    2.1在它的superView里,重写 hitTest: 方法

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
            let viewFrame = theView.frame.inset(by: UIEdgeInsets.init(top: -20, left: -20, bottom: -20, right: -20))
            if viewFrame.contains(point) {
                return theView
            }
            return super.hitTest(point, with: event)
        }
    

    以它 frame 进行扩大( UIEdgeInsets 相应的负数为扩大,正数为缩小)到目标 frame ,然后判断这个目标 frame 是否包括点击事件的点,如果是,就返回这个 theView,否则,就交给 super.hitTest: 去处理。

    2.2重写它的point(inside point: CGPoint, with event: UIEvent?)方法

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
            let biggerFrame = self.bounds.inset(by: UIEdgeInsets.init(top: -20, left: -20, bottom: -20, right: -20))
            return biggerFrame.contains(point)
        }
    

    这个方法是在我们无法确定 theView 的 superView 进行扩大点击事件,例如:UIBarButtonItem等。

    2.3是这两种方法的混合,将需要扩展的数据添加到相应的分类或者 superView 的类中

    ///提供多个运行时的key
        struct RuntimeKey {
            static let buttonKey = UnsafeRawPointer.init(bitPattern: "BTNKey".hashValue)
        }
        
        ///需要扩充的边距
        var hitTestEdgeInsets: UIEdgeInsets? {
            set {
                objc_setAssociatedObject(self, RuntimeKey.buttonKey!, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_COPY)
            }
            get {
                return objc_getAssociatedObject(self, RuntimeKey.buttonKey!) as? UIEdgeInsets ?? UIEdgeInsets.zero
            }
        }
        
        ///是否响应
        open override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
            if (hitTestEdgeInsets! == UIEdgeInsets.zero) || !isEnabled || isHidden {
                return super.point(inside: point, with: event)
            }
            else {
                let expandArea = self.bounds.inset(by: hitTestEdgeInsets!)
                return expandArea.contains(point)
            }
        }
        
        open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
            return super.hitTest(point, with: event)
        }
    

    该例子是以UIButton的分类添加hitTestEdgeInsets的属性来达到按钮的点击相应区域的。

    2.4注意的点

    theView 扩展点击相应区域时,其扩展的区域不能超过 superView 的 frame ,否则不会相应改点击事件;如果需要响应点击事件,需要对其 superView 进行和 theView 进行同样的处理。

    相关文章

      网友评论

        本文标题:swift扩大UIButton或者UIView的点击区域

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