如何为UIView扩展方法swift添加Gecture

问题描述 投票:0回答:2

嗨,我想在PanGecture的顶部给UIViewUIViewControllers滑动动作。为了那个我在视图控制器扩展中编写一个常用方法,但它使整个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
2个回答
0
投票

您可以添加此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")
}

0
投票

使用此类扩展。

 //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 
                })
© www.soinside.com 2019 - 2024. All rights reserved.