Как добавить архитектуру для метода расширения UIView swift

#swift #uiview #uiviewcontroller #swipe

#swift #uiview #uiviewcontroller #проведите пальцем

Вопрос:

Привет, я хочу предоставить PanGecture действие салфетки для UIView в верхней части UIViewControllers . для этого я пишу один общий метод в расширении контроллера представления, но он делает весь 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)
                })
            }
        }
    }
}
  

Ответ №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, amp;AssociatedKeys.actionState) as? ActionTap else {
            return nil
        }
        return value
    }
    set {
        objc_setAssociatedObject(self, amp;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")
}
  

Комментарии:

1. что такое RxSwift

2. @srikanthkumar просто игнорируйте этот импорт, я не использую этот импорт в этом расширении. RxSwift — это модуль ~> github.com/ReactiveX/RxSwift

3. Хорошо, но ваш код не проводит пальцем вниз и не закрывает представление.

Ответ №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 
                })
  

Комментарии:

1. как мы используем это

2. @srikanthkumar взгляните на это.

3. Я использую следующий способ, но он не получает никакого действия let get = UIPanGestureRecognizer(target: self, action: #selector(pangectureRecognizerDismissoneScreen(_:))) UIGestureRecognizer.init(addToView: uiview) { self.view.backgroundColor = UIColor.DarkGray.withAlphaComponent(0.1) self.uiview.addGestureRecognizer(получить) }

4. Вы видите в моем коде, какой бы вид вы ни передали в «addToView», он будет выполнять распознавание жестов, В завершении (закрытии) вы можете выполнить любое действие, если у вас все еще есть сомнения, проверьте эту ссылку gist.github.com/loganwright/3bd5fe87d499eff23d4a @srikanthkumar