ios常用功能

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

2020-06-08  本文已影响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 进行同样的处理。

上一篇下一篇

猜你喜欢

热点阅读