2

ScrollView is not recognising shake gesture

I have 3 files.

1.ContentVC - consists of scrollView to swipe between viewcontrollers

2.FirstVC - It contains shakegesture function

3.SecondVC - default view controller

When i shake the device nothing happens.

ContentVC.swift
class ContainerVC: UIViewController {
    @IBOutlet weak var scroll: UIScrollView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let left = self.storyboard?.instantiateViewController(withIdentifier: "vw") as! UINavigationController
        self.addChild(left)
        self.scroll.addSubview(left.view)
        self.didMove(toParent: self)

        let last = self.storyboard?.instantiateViewController(withIdentifier: "lastviewNav") as! UINavigationController
        self.addChild(last)
        self.scroll.addSubview(last.view)
        self.didMove(toParent: self)

        var middleframe:CGRect = last.view.frame
        middleframe.origin.x = self.view.frame.width
        last.view.frame = middleframe

        self.scroll.contentSize = CGSize(width: (self.view.frame.width) * 2, height: (self.view.frame.height))
    }
}
FirstVC.swift
override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
    if event?.subtype == UIEvent.EventSubtype.motionShake {
        if motion == .motionShake {
            print("quote is appearing by shaking the device")
        } else {
            print("No quote is coming")
        }
    }
}
ManWithBear
  • 2,787
  • 15
  • 27
Motivation gym5
  • 281
  • 1
  • 2
  • 17

1 Answers1

2

Motion events are delivered initially to the first responder and are forwarded up the responder chain as appropriate.
https://developer.apple.com/documentation/uikit/uiresponder/1621090-motionended

So make sure that:

  1. FirstVC able to became first responder:
override var canBecomeFirstResponder: Bool {
    return true
}
  1. FirstVC is first responder at specific point of time:
firstVC.becomeFirstResponder()

Now your UIViewController will be able to receive shake motion events.

You can read more about Responder chain: How do Responder Chain Works in IPhone? What are the "next responders"?

ManWithBear
  • 2,787
  • 15
  • 27
  • where to write firstVC.becomeFirstResponder() ? – Motivation gym5 Mar 21 '19 at 15:33
  • @Motivationgym5 it really depends on you application logic. In easiest way you can put it in the end of `ContainerVC.viewDidLoad()` – ManWithBear Mar 21 '19 at 15:35
  • It's showing error: Instance member 'becomeFirstResponder' cannot be used on type 'FirstVC'; did you mean to use a value of this type instead? – Motivation gym5 Mar 21 '19 at 15:42
  • @Motivationgym5 you need to call this function on your instance of `FirstVC`. In your example I assume it will be `(left.rootViewController as? FirstVC)?.becomeFirstResponder()` or in `viewDidLoad` of `FirstVC` just call `becomeFirstResponder()` – ManWithBear Mar 21 '19 at 21:22
  • As I said it really depends on logic and architecture of your app. – ManWithBear Mar 21 '19 at 21:25