Swift中的子类UIScrollView用于触摸开始和放大移动

时间:2015-04-22 13:44:49

标签: swift uiscrollview touchesbegan

enter image description here我使用的是Swift 1.2

我尝试使用此fiddle以及接受答案的第2条评论中的链接。

我使用带有自动布局的故事板,我在自定义类中为UIScrollView设置了自定义类。

我在UIViewController中没有收到任何包含我的自定义UIScrollView的触摸事件

编辑:更新了我的代码,了解我如何使用@Victor Sigler的答案。

自定义ScrollView代码:

import UIKit

protocol PassTouchesScrollViewDelegate {

func scrollTouchBegan(touches: Set<NSObject>, withEvent event: UIEvent)
func scrollTouchMoved(touches: Set<NSObject>, withEvent event: UIEvent)
}

class PassTouchesScrollView: UIScrollView {

var delegatePass : PassTouchesScrollViewDelegate?

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

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {

    self.delegatePass?.scrollTouchBegan(touches, withEvent: event)


}

override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {

    self.delegatePass?.scrollTouchMoved(touches, withEvent: event)

}

}

我的ViewController:

import UIKit

class ViewController: UIViewController, PassTouchesScrollViewDelegate {

@IBOutlet weak var scrollView: UIScrollView!

override func viewDidLoad() {
    super.viewDidLoad()

    scrollView.delegatePass = self
}

func scrollTouchBegan(touches: Set<NSObject>, withEvent event: UIEvent)    {

    println("began \(touches)")

}

func scrollTouchMoved(touches: Set<NSObject>, withEvent event: UIEvent)      {

    println("moved \(touches)")
}     

}

我试图让用户在UIImage上绘制一条线,我使用PanGesture识别器工作,但性能非常差,特别是在较旧的硬件上,我按照Ray Wenderlich教程使用触摸开始并且性能要好得多,但它是在UIView而不是ScrollView上。我需要一个UIScrollView,因为在用户绘制图像之前,他们可以放大和围绕它。

3 个答案:

答案 0 :(得分:6)

我以为你在考虑这个错误。如果您想知道UIScrollView何时移动,则无需将其子类化。 iOS已在UIScrollViewDelegate

内设置了您需要的所有方法

您必须实施UISCrollViewDelegate以获取有关UIScrollView中的操作的通知,并通过Interface Builder或代码设置delegate,由您自己决定。

请参阅以下示例以了解如何执行此操作:

class ViewController: UIViewController, UIScrollViewDelegate {

     @IBOutlet weak var scrollView: UIScrollView!

     override func viewDidLoad() {
       super.viewDidLoad()
       self.scrollView.delegate = self
     }
}

如果你想知道你上面解释的方式,你必须遵循以下步骤:

  1. 您必须像在类UIScrollView中那样从PassTouchesScrollView类创建子类并实现委托模式,以便通过以下方式通知UIScrollView

    import UIKit
    
    protocol PassTouchesScrollViewDelegate {
       func touchBegan()
       func touchMoved()
    }
    
    
    class PassTouchesScrollView: UIScrollView {
    
      var delegatePass : PassTouchesScrollViewDelegate?
    
      override init(frame: CGRect) {
        super.init(frame: frame)
      }
    
      required init(coder aDecoder: NSCoder) {
         super.init(coder: aDecoder)
      }
    
      override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    
         // Notify it's delegate about touched
         self.delegatePass?.touchBegan()
    
        if self.dragging == true {
           self.nextResponder()?.touchesBegan(touches, withEvent: event)
        } else {
           super.touchesBegan(touches, withEvent: event)
        }
    
     }
    
      override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent)  {
    
         // Notify it's delegate about touched
         self.delegatePass?.touchMoved()
    
         if self.dragging == true {            
            self.nextResponder()?.touchesMoved(touches, withEvent: event)
         } else {            
           super.touchesMoved(touches, withEvent: event)
         }
      }   
    }
    
  2. 您的课程ViewController必须按以下方式实施:

    class ViewController: UIViewController, UIScrollViewDelegate {
    
      @IBOutlet weak var scrollView: PassTouchesScrollView!
    
      override func viewDidLoad() {
        super.viewDidLoad()        
        scrollView.delegate = self  
        scrollView.delegatePass = self      
      }
    
      override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
      }
    
      func touchMoved() {
         println("touch moved")
      }
    
      func touchBegan() {
         println("touch began")
      }
    
    }
    
  3. 您必须在界面生成器中选择您的UIScrollView,并在类部件的Identity Inspector中将其设置为类PassTouchesScrollView

  4. 您应该在控制台中看到以下内容:

    touch began
    touch began
    touch began
    touch began
    touch began
    touch began
    touch moved
    touch move
    

    我希望这对你有所帮助。

答案 1 :(得分:4)

试试这个

  extension UIScrollView {

    override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.next?.touchesBegan(touches, with: event)
        print("touchesBegan")
    }

    override open func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.next?.touchesMoved(touches, with: event)
        print("touchesMoved")
    }

    override open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.next?.touchesEnded(touches, with: event)
        print("touchesEnded")
    }

}

答案 2 :(得分:0)

touchesBegan仅适用于UIView的子类。从UIViewController中取出它以使其工作。

UIResponder Apple Docs