Swift - 在UIScrollView中使用UISwipeGestureRecognizer

5
我相信我找到了一个解决方案,但它是用Obj-C编写的,而我对将其转换为Swift完全陌生和困惑:在UIScrollView子视图中的水平UISwipeGestureRecognizer?(UIScrollView仅需要识别垂直滚动) 我有一个Main.storyboard,在其中添加了两个子视图,可以在它们之间水平滚动。目前,上下滑动被检测到,但由于UIScrollView,左右滑动没有被检测到。有什么解决此干扰的方法吗? Main.storyboard:
// Global
let vc0 = ViewController0(nibName: "ViewController0", bundle: nil)
let vc1 = ViewController1(nibName: "ViewController1", bundle: nil)

class ViewController: UIViewController, UIScrollViewDelegate, UIGestureRecognizerDelegate {

@IBOutlet weak var scrollView: UIScrollView!

override func viewDidLoad() {
    super.viewDidLoad()

    self.addChildViewController(vc0)
    self.scrollView.addSubview(vc0.view)
    vc0.didMoveToParentViewController(self)

    var frame1 = vc1.view.frame
    frame1.origin.x = self.view.frame.size.width
    vc1.view.frame = frame1

    self.addChildViewController(vc1)
    self.scrollView.addSubview(vc1.view)
    vc1.didMoveToParentViewController(self)

    self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width * 2, self.view.frame.size.height - 66)
    self.scrollView.delegate = self

    // Swipe Gesture Recognizers
    let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.respondToSwipeGesture(_:)))
    swipeRight.direction = UISwipeGestureRecognizerDirection.Right
    let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.respondToSwipeGesture(_:)))
    swipeLeft.direction = UISwipeGestureRecognizerDirection.Left
    let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.respondToSwipeGesture(_:)))
    swipeUp.direction = UISwipeGestureRecognizerDirection.Up
    let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.respondToSwipeGesture(_:)))
    swipeDown.direction = UISwipeGestureRecognizerDirection.Down

    swipeRight.delegate = self
    swipeLeft.delegate = self

    self.view.addGestureRecognizer(swipeRight)
    self.view.addGestureRecognizer(swipeLeft)
    self.view.addGestureRecognizer(swipeUp)
    self.view.addGestureRecognizer(swipeDown)
}

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    return true
}

// Debugging - Only Up & Down Swipes Are Detected
func respondToSwipeGesture(gesture: UIGestureRecognizer) {
    if let swipeGesture = gesture as? UISwipeGestureRecognizer {
        switch swipeGesture.direction {
        case UISwipeGestureRecognizerDirection.Right:
            print("Swiped right")
        case UISwipeGestureRecognizerDirection.Down:
            print("Swiped down")
        case UISwipeGestureRecognizerDirection.Left:
            print("Swiped left")
        case UISwipeGestureRecognizerDirection.Up:
            print("Swiped up")
        default:
            break
        }
    }
}
}
1个回答

12
我认为您需要实现 UIGestureRecognizerDelegate 协议。
这样做是否达到您的要求?
import UIKit

class ViewController: UIViewController, UIScrollViewDelegate, UIGestureRecognizerDelegate {

    @IBOutlet weak var scrollView: UIScrollView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // these were made in a storyboard I whipped up for this example.
        let vc0 = self.storyboard!.instantiateViewControllerWithIdentifier("vc0")
        let vc1 = self.storyboard!.instantiateViewControllerWithIdentifier("vc1")

        self.addChildViewController(vc0)
        self.scrollView.addSubview(vc0.view)
        vc0.didMoveToParentViewController(self)

        var frame1 = vc1.view.frame
        frame1.origin.x = self.view.frame.size.width
        vc1.view.frame = frame1

        self.addChildViewController(vc1)
        self.scrollView.addSubview(vc1.view)
        vc1.didMoveToParentViewController(self)

        self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width * 2, self.view.frame.size.height - 66)
        self.scrollView.delegate = self

        // Swipe Gesture Recognizers
        // These can be lets because they aren't mutated and I'm using the latest Selector syntax
        let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.respondToSwipeGesture(_:)))
        swipeRight.direction = UISwipeGestureRecognizerDirection.Right
        let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.respondToSwipeGesture(_:)))
        swipeLeft.direction = UISwipeGestureRecognizerDirection.Left
        let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.respondToSwipeGesture(_:)))
        swipeUp.direction = UISwipeGestureRecognizerDirection.Up
        let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.respondToSwipeGesture(_:)))
        swipeDown.direction = UISwipeGestureRecognizerDirection.Down

        // ViewController will be the delegate for the left and right swipes
        swipeRight.delegate = self
        swipeLeft.delegate = self

        self.view.addGestureRecognizer(swipeRight)
        self.view.addGestureRecognizer(swipeLeft)
        self.view.addGestureRecognizer(swipeUp)
        self.view.addGestureRecognizer(swipeDown)
    }

    // here are those protocol methods with Swift syntax
    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }

    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
        return true
    }

    // Debugging - All Swipes Are Detected Now
    func respondToSwipeGesture(gesture: UIGestureRecognizer) {
        if let swipeGesture = gesture as? UISwipeGestureRecognizer {
            switch swipeGesture.direction {
            case UISwipeGestureRecognizerDirection.Right:
                print("Swiped right")
            case UISwipeGestureRecognizerDirection.Down:
                print("Swiped down")
            case UISwipeGestureRecognizerDirection.Left:
                print("Swiped left")
            case UISwipeGestureRecognizerDirection.Up:
                print("Swiped up")
            default:
                break
            }
        }
    }
}

啊,糟糕!我忘记在我的代码中包含变量vc0和vc1了。它们被放置在全局位置。现在已经更新了。我尝试运行你的代码,但没有初始化vc0和vc1,结果程序崩溃了。嗯... - theflarenet
你使用的是Swift和Xcode的哪个版本?还有崩溃信息是什么? - Andrew Sowers
我正在使用最新版本的Swift和xCode。抱歉没有具体说明。当我开始向vc0滑动时,它会立即崩溃:Terminating app due to uncaught exception 'NSInvalidArgumentException',reason: '-[Project.ViewController respondToSwipeGesture:]:无法识别发送到实例0x7be75360的选择器' - theflarenet
我已经更新了我的问题中的代码,并且保留了我的全局变量,因为我认为问题就出在那里。 - theflarenet
看起来 respondToSwipeGesture 不在 viewController 的范围内。你需要它在外面吗?在我的例子中,我把 respondToSwipeGesture 设为了 viewController 的一个方法。 - Andrew Sowers
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接