When a CALayer has a speed other than 1.0 (or other manipulations to its local time coordinate space), animations need to convert beginTime values into this time space. For a beginOffset of zero, the layer automatically sets the beginTime to the current active time of the layer. For non-zero values (delayed animations), the conversion has to be performed by the caller. This article has a pretty good explanation: https://coveller.com/2016/05/core_animation_timing/ Closes internal issue b/72403469
Ink
The Ink component provides a radial action in the form of a visual ripple of ink expanding outward from the user's touch.
Design & API Documentation
- Material Design guidelines: Radial Action
- API: MDCInkGestureRecognizer
- API: MDCInkTouchController
- API: MDCInkView
Installation
Installation with CocoaPods
To add this component to your Xcode project using CocoaPods, add the following to your Podfile:
pod 'MaterialComponents/Ink'
To add this component along with its themer and other related extensions, please add the following instead:
pod 'MaterialComponents/Ink+Extensions'
Then, run the following command:
pod install
Usage
Importing
Before using Ink, you'll need to import it:
Swift
import MaterialComponents
Objective-C
#import "MaterialInk.h"
The Ink component exposes two interfaces that you can use to add material-like feedback to the user:
MDCInkViewis a subclass ofUIViewthat draws and animates ink ripples and can be placed anywhere in your view hierarchy.MDCInkTouchControllerbundles anMDCInkViewinstance with aUITapGestureRecognizerinstance to conveniently drive the ink ripples from the user's touches.
MDCInkTouchController
The simplest method of using ink in your views is to use a
MDCInkTouchController:
Swift
let myButton = UIButton(type: .system)
myButton.setTitle("Tap Me", for: .normal)
let inkTouchController = MDCInkTouchController(view: myButton)
inkTouchController.addInkView()
Objective-C
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeSystem];
[myButton setTitle:@"Tap me" forState:UIControlStateNormal];
MDCInkTouchController *inkTouchController = [[MDCInkTouchController alloc] initWithView:myButton];
[inkTouchController addInkView];
The MDCInkTouchControllerDelegate gives you control over aspects of the
ink/touch relationship, such as how the ink view is created, where it is
inserted in view hierarchy, etc. For example, to temporarily disable ink
touches, the following code uses the delegate's
inkTouchController:shouldProcessInkTouchesAtTouchLocation: method:
Swift
class MyDelegate: NSObject, MDCInkTouchControllerDelegate {
func inkTouchController(_ inkTouchController: MDCInkTouchController, shouldProcessInkTouchesAtTouchLocation location: CGPoint) -> Bool {
// Determine if we want to display the ink
return true
}
}
...
let myButton = UIButton(type: .system)
myButton.setTitle("Tap Me", for: .normal)
let myDelegate = MyDelegate()
let inkTouchController = MDCInkTouchController(view: myButton)
inkTouchController.delegate = myDelegate
inkTouchController.addInkView()
Objective-C
@interface MyDelegate: NSObject <MDCInkTouchControllerDelegate>
@end
@implementation MyDelegate
- (BOOL)inkTouchController:(MDCInkTouchController *)inkTouchController
shouldProcessInkTouchesAtTouchLocation:(CGPoint)location {
return YES;
}
@end
...
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeSystem];
[myButton setTitle:@"Tap me" forState:UIControlStateNormal];
MyDelegate *myDelegate = [[MyDelegate alloc] init];
MDCInkTouchController *inkTouchController = [[MDCInkTouchController alloc] initWithView:myButton];
inkTouchController.delegate = myDelegate;
[inkTouchController addInkView];
NOTE: The ink touch controller does not keep a strong reference to the view to which it is attaching the ink view. An easy way to prevent the ink touch controller from being deallocated prematurely is to make it a property of a view controller (like in these examples.)
MDCInkView
Alternatively, you can use MCDInkView directly to display ink ripples using your own touch processing:
Swift
let myCustomView = MyCustomView(frame: CGRect.zero)
let inkView = MDCInkView()
inkView.inkColor = UIColor.red
myCustomView.addSubview(inkView)
...
// When the touches begin, there is one animation
inkView.startTouchBeganAnimation(at: touchPoint, completion: nil)
...
// When the touches end, there is another animation
inkView.startTouchEndedAnimation(at: touchPoint, completion: nil)
Objective-C
MyCustomView *myCustomView = [[MyCustomView alloc] initWithFrame:CGRectZero];
MDCInkView *inkView = [[MDCInkView alloc] init];
inkView.inkColor = [UIColor redColor];
[myCustomView addSubview:inkView];
...
// When the touches begin, there is one animation
[inkView startTouchBeganAnimationAtPoint:touchPoint completion:nil];
...
// When the touches end, there is another animation
[inkView startTouchEndedAnimationAtPoint:touchPoint completion:nil];
