【问题标题】:How to add Gecture for UIView Extension method swift如何快速为 UIView 扩展方法添加 Gecture
【发布时间】:2019-04-24 10:19:15
【问题描述】:

嗨,我想在UIViewControllers 的顶部为UIView 提供PanGecture 滑动操作。为此,我在视图控制器扩展中编写了一种常用方法,但它使整个viewcontroller 滑动。

我只想为 UIView 提供滑动操作,请帮助我将以下代码更改为 UIView Extension

extension UIViewController{

@objc  func pangectureRecognizerDismissoneScreen(_ sender: UIPanGestureRecognizer){  
        var initialTouchPoint: CGPoint = CGPoint(x: 0,y: 0)
        let touchPoint = sender.location(in: self.view?.window)

        if sender.state == UIGestureRecognizerState.began {
            initialTouchPoint = touchPoint
        } else if sender.state == UIGestureRecognizerState.changed {
            if touchPoint.y - initialTouchPoint.y > 0 {
                self.view.frame = CGRect(x: 0, y: touchPoint.y - initialTouchPoint.y, width: self.view.frame.size.width, height: self.view.frame.size.height)
            }
        } else if sender.state == UIGestureRecognizerState.ended || sender.state == UIGestureRecognizerState.cancelled {
            if touchPoint.y - initialTouchPoint.y > 100 {
                self.view.backgroundColor = UIColor.clear
                self.dismiss(animated: true, completion: nil)
            } else {
                UIView.animate(withDuration: 0.3, animations: {
                    self.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
                })
            }
        }
    }
}

【问题讨论】:

    标签: swift uiview uiviewcontroller swipe


    【解决方案1】:

    你可以添加这个 UIView 扩展

    import UIKit
    
    import RxSwift
    
    struct AssociatedKeys {
    static var actionState: UInt8 = 0
    }
    
    typealias ActionTap = () -> Void
    
    extension UIView {
    
    var addAction: ActionTap? {
        get {
            guard let value = objc_getAssociatedObject(self, &AssociatedKeys.actionState) as? ActionTap else {
                return nil
            }
            return value
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.actionState, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            self.tapWithAnimation()
        }
    }
    
    func tapWithAnimation() {
        self.gestureRecognizers?.removeAll()
        let longTap = UILongPressGestureRecognizer(target: self, action: #selector(viewLongTap(_:)))
        longTap.minimumPressDuration = 0.035
        longTap.delaysTouchesBegan = true
        self.addGestureRecognizer(longTap)
    }
    
    @objc
    func viewLongTap(_ gesture: UILongPressGestureRecognizer) {
        if gesture.state != .ended {
            animateView(alpha: 0.3)
            return
        } else if gesture.state == .ended {
            let touchLocation = gesture.location(in: self)
            if self.bounds.contains(touchLocation) {
                animateView(alpha: 1)
                addAction?()
                return
            }
        }
        animateView(alpha: 1)
    }
    
    fileprivate func animateView(alpha: CGFloat) {
        UIView.transition(with: self, duration: 0.3,
                          options: .transitionCrossDissolve, animations: {
                            self.subviews.forEach { subView in
                                subView.alpha = alpha
                            }
        })
    }
    }
    

    示例:

    myView.addAction = {
    print("click")
    }
    

    【讨论】:

    • 什么是 RxSwift
    • @srikanthkumar 只是忽略这个导入,我没有在这个扩展中使用这个导入。 RxSwift 是一个 pod ~> github.com/ReactiveX/RxSwift
    • 好的,但您的代码不会向下滑动并关闭视图。
    【解决方案2】:

    使用此类扩展。

     //Gesture extention
    
    extension UIGestureRecognizer {
        @discardableResult convenience init(addToView targetView: UIView,
                                            closure: @escaping () -> Void) {
            self.init()
    
            GestureTarget.add(gesture: self,
                              closure: closure,
                              toView: targetView)
        }
    }
    
    fileprivate class GestureTarget: UIView {
        class ClosureContainer {
            weak var gesture: UIGestureRecognizer?
            let closure: (() -> Void)
    
            init(closure: @escaping () -> Void) {
                self.closure = closure
            }
        }
    
        var containers = [ClosureContainer]()
    
        convenience init() {
            self.init(frame: .zero)
            isHidden = true
        }
    
        class func add(gesture: UIGestureRecognizer, closure: @escaping () -> Void,
                       toView targetView: UIView) {
            let target: GestureTarget
            if let existingTarget = existingTarget(inTargetView: targetView) {
                target = existingTarget
            } else {
                target = GestureTarget()
                targetView.addSubview(target)
            }
            let container = ClosureContainer(closure: closure)
            container.gesture = gesture
            target.containers.append(container)
    
            gesture.addTarget(target, action: #selector(GestureTarget.target(gesture:)))
            targetView.addGestureRecognizer(gesture)
        }
    
        class func existingTarget(inTargetView targetView: UIView) -> GestureTarget? {
            for subview in targetView.subviews {
                if let target = subview as? GestureTarget {
                    return target
                }
            }
            return nil
        }
    
        func cleanUpContainers() {
            containers = containers.filter({ $0.gesture != nil })
        }
    
        @objc func target(gesture: UIGestureRecognizer) {
            cleanUpContainers()
    
            for container in containers {
                guard let containerGesture = container.gesture else {
                    continue
                }
    
                if gesture === containerGesture {
                    container.closure()
                }
            }
        }
    } 
    

    编辑 1:-

    这样使用

     UIGestureRecognizer.init(addToView: yourView, closure: {
                      //  your code 
                    })
    

    【讨论】:

    • 我们如何使用这个
    • @srikanthkumar 看看。
    • 我使用如下方式,但它没有任何动作 let get = UIPanGestureRecognizer(target: self, action: #selector(pangectureRecognizerDismissoneScreen(_:))) UIGestureRecognizer.init(addToView: uiview) { self.view.backgroundColor = UIColor.darkGray.withAlphaComponent(0.1) self.uiview.addGestureRecognizer(get) }
    • 您在我的代码中看到,无论您将传递给“addToView”的任何视图,它都会执行手势识别器,完成(关闭)您可以执行任何操作,如果您仍有疑问,请查看此链接@ 987654321@@srikanthkumar
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-31
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    相关资源
    最近更新 更多