This is a demo to show how Core Motion works and enables you to do "magic".
- Create a new Project. Choose the template for 1 view.
- Visit the Storyboard.
- In the main view controller add 1 UIView and a button.
- Add constraints so the button is centered at the bottom and the view covers the rest of the view controller respecting the margins.
- Set the label of the button to "Clear".
- Create a new UIView subclass and call it CanvasView.
- Set the class of the view that was added to the view controller to CanvasView.
- Create an outlet in the main view controller for the canvas view.
- Create an internal property in the canvas view to hold a UIBezierPath. Call it bezierPath.
- Initialize in initWithCoder, create the UIBezierPath there and set the default line width.
- In an new public method called clear, remove all the points from the path and mark the rectangle of the view as needed to be redrawn.
- In the storyboard connect the button with a new action of the view controller. The new action should invoke the clear method of the canvas view.
- In the drawRect method, stroke the path.
- Override the touchesBegan:withEvent:. Obtain the first touch from the set and add the point, translated of the coordinates of the Canvas view, to the Bezier path as a movement.
- Override touchesMoved:withEvent:. Obtain the first touch from the set and add the point, translated of the coordinates of the Canvas view, to the Bezier path as a line. Mark the rectangle of the view as needed to be redrawn.
- Override touchesCancelled:withEvent: and invoke touchesMoved:withEvent: with the corresponding parameters.
- Override touchesEnded:withEvent: and invoke touchesMoved:withEvent: with the corresponding parameters.
- Run and test.
- In Canvas view create a new method, "saveCurrentPath".
- Obtain the URL for the documents directory
- Append the current date an time with the path extension to have a unique filename. Use NSDateFormatter.
- Save the contents of the Bezier path with NSKeyedArchiver (archiveRootObject).
- Invoke this method from the clear method before the data is removed.
- Run it and generate the 4 paths so they can be saved.
- From the device manager, download the container with the paths.
- Edit the container to have proper names for the card suits (Spades, Diamonds, Hearts, and Clubs).
- Replace the container.
- Remove the invocation to save from the clear method.
- Write the method to load and display the paths (taking an NSUInteger).
- Invoke the method after clearing the path and before marking the view for redrawing.
- Run and test with.
- Import CoreMotion framework
- Create a new subclass of NSObject. Call it MotionController.
- In the private interface of the class define a property for the CMMotionManager.
- Create a method to perform lazy instanciation of the motionManager.
- Create a new public method to startMeasuringPosition.
- Verify that the deviceMotionAvailable is YES and set the interval of the device motion update to 0.5.
- Start the pushing updates and print the data inside of the block inorder to understand the dynamics. Use the reference frame XArbitraryZVertical. Use the main queue for the operations.
- Create another public method to stop the updates.
- Create an instance of the MotionController in the view controller and start measuring when view appears. Stop measuring when view disappears.
- Run and learn how to use the data.
- In MotionController, define an enum with two states (Drawing, Learning).
- Define a property that is of the enum type. and set it to drawing when the startMeasuring begins.
- Use a switch in the block for gathering the data and implement the logic for the two states there. (Remember to use weakSelf and identify the different values).
- Define a protocol to notify the view controller. Use an enum for the suites and have the enum in a different header, so it can also be used in the view controller and the canvas view.
- Implement the protocol on the view controller so that the path is deleted, the one for the corresponding suit is loaded and it is displayed.
- Declare itself as delegate of the motion controller.
- In the implementation of the method, tell the canvas to load the required suit, which means removing the current path, loading the path and redrawing.