子类 UIView 上的 UIPanGestureRecognizer

Posted

技术标签:

【中文标题】子类 UIView 上的 UIPanGestureRecognizer【英文标题】:UIPanGestureRecognizer on subclass UIView 【发布时间】:2016-12-12 16:17:53 【问题描述】:

我一直在尝试更多地了解对某些对象进行子类化。 现在我将UIView 子类化,它有一个PanGestureRecognizer 用于左右滑动。

似乎找不到问题。它甚至不会移动UIView。我尝试查看UIView 的生命周期以将isUserInteractionEnabled 设置为true,但没有结果。请看下面的代码:

风险投资

import UIKit

class SwipeViewController: UIViewController 

override func viewDidLoad() 
    super.viewDidLoad()

    addNewProfile()


private func addNewProfile() 

    let swipeView = SwiperView(frame: CGRect(x: self.view.bounds.width / 2 - 150, y: self.view.bounds.height / 2 - 75, width: 300, height: 150))
    swipeView.parentView = self.view
    swipeView.delegate = self
    swipeView.shadow = true
    swipeView.isUserInteractionEnabled = true
    swipeView.backgroundColor = UIColor.white
    swipeView.alpha = 0.0
    view.addSubview(swipeView)

    UIView.animate(withDuration: 0.3, animations: 
        swipeView.alpha = 1.0
    , completion:  (succeed) in
        swipeView.isUserInteractionEnabled = true
    )



//MARK: - ChosenSwipeResultDelegate
extension SwipeViewController: ChosenSwipeResultDelegate 

    func pickedLeftSide() 

    

    func pickedRightSide() 

    


SwiperView

import UIKit

protocol ChosenSwipeResultDelegate 

func pickedLeftSide()
func pickedRightSide()


@IBDesignable class SwiperView: UIView 

private var _shadow: Bool!
private var _parentView: UIView!

var delegate: ChosenSwipeResultDelegate?

var parentView: UIView 
    set 
        _parentView = newValue
    
    get 
        return _parentView
    


@IBInspectable var shadow: Bool 
    get 
        return layer.shadowOpacity > 0.0
    
    set 
        if newValue == true 
            addShadow()
        
    


@IBInspectable var cornerRadius: CGFloat 
    get 
        return layer.cornerRadius
    
    set 
        layer.cornerRadius = newValue

        if shadow == false 
            layer.masksToBounds = true
        
    


override func setNeedsLayout() 
    super.setNeedsLayout()
    isUserInteractionEnabled = true



override func awakeFromNib() 
    super.awakeFromNib()

    isUserInteractionEnabled = true
    let dragGesture = UIPanGestureRecognizer(target: self, action: #selector(SwiperView.dragging(gesture:)))
    addGestureRecognizer(dragGesture)


func dragging(gesture: UIPanGestureRecognizer) 

    let translation = gesture.translation(in: parentView)
    let tinderView = gesture.view!

    tinderView.center = CGPoint(x: parentView.bounds.width / 2 + translation.x, y: parentView.bounds.height / 2 + translation.y)

    let xFromCenter = tinderView.center.x - parentView.bounds.width / 2

    let scale = min(100 / abs(xFromCenter), 1)

    var rotation = CGAffineTransform(rotationAngle: xFromCenter / 200)

    let stretch = rotation.scaledBy(x: scale, y: scale)

    tinderView.transform = stretch

    if gesture.state == .ended 

        if tinderView.center.x < 100 
            print("left")

            UIView.animate(withDuration: 0.3, animations: 
                tinderView.alpha = 0.0
            , completion:  (succeed) in

                self.delegate?.pickedLeftSide()
            )

         else if tinderView.center.x > parentView.bounds.width - 100 

            print("right")

            UIView.animate(withDuration: 0.3, animations: 
                tinderView.alpha = 0.0
            , completion:  (succeed) in

                self.delegate?.pickedRightSide()
            )
         else 

            print("Not chosen")

            rotation = CGAffineTransform(rotationAngle: 0)

            let stretch = rotation.scaledBy(x: 1, y: 1)
            tinderView.transform = stretch

            tinderView.center = CGPoint(x: parentView.bounds.width / 2, y: parentView.bounds.height / 2)

        
    


private func addShadow(shadowColor: CGColor = UIColor.black.cgColor, shadowOffset: CGSize = CGSize(width: 1.0, height: 2.0), shadowOpacity: Float = 0.4, shadowRadius: CGFloat = 3.0) 
    layer.shadowColor = shadowColor
    layer.shadowOffset = shadowOffset
    layer.shadowOpacity = shadowOpacity
    layer.shadowRadius = shadowRadius


【问题讨论】:

你有一个很棒的调试器。调试!查看您的dragging 是否被调用。如果是,请在运行时检查变量值。自己想办法。 【参考方案1】:

将这些代码添加到你的 SwiperView 看看它是否解决了问题

  override init(frame: CGRect) 
        super.init(frame: frame)

        isUserInteractionEnabled = true
        let dragGesture = UIPanGestureRecognizer(target: self, action: #selector(SwiperView.dragging(gesture:)))
        addGestureRecognizer(dragGesture)

    

    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)

        isUserInteractionEnabled = true
        let dragGesture = UIPanGestureRecognizer(target: self, action: #selector(SwiperView.dragging(gesture:)))
        addGestureRecognizer(dragGesture)
    

【讨论】:

修复了问题! :) 我需要在init frame 中实现它的原因是什么?

以上是关于子类 UIView 上的 UIPanGestureRecognizer的主要内容,如果未能解决你的问题,请参考以下文章

在 iPhone 中使用 UIPanGesture 旋转 UIView 的框架增加减少

UIPanGesture 正在工作,但 UITapGesture 在 UIView 上不起作用

Swift 中的 UIScrollView 内的 UIPanGesture

使用 UIPanGesture 将图像的位置存储到 Objc 中 UIView 中的新位置

子类 UIView 上的 UIPanGestureRecognizer

仅在 iPhone 上水平添加 UIPanGesture