To add this component to your Xcode project using CocoaPods, add the following to your Podfile
:
pod 'MaterialComponents/Ink'
Then, run the following command:
pod install
Before using Ink, you'll need to import it:
import MaterialComponents
#import "MaterialInk.h"
The Ink component exposes two interfaces that you can use to add material-like feedback to the user:
MDCInkView
is a subclass of UIView
that draws and animates ink ripples and can be placed anywhere in your view hierarchy.MDCInkTouchController
bundles an MDCInkView
instance with a UITapGestureRecognizer
instance to conveniently drive the ink ripples from the user's touches.The simplest method of using ink in your views is to use a MDCInkTouchController
:
let myButton = UIButton(type: .system) myButton.setTitle("Tap Me", for: .normal) let inkTouchController = MDCInkTouchController(view: myButton) inkTouchController?.addInkView()
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:
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()
@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.)
Alternatively, you can use MCDInkView directly to display ink ripples using your own touch processing:
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)
MyCustomView *myCustomView = [[MyCustomView alloc] initWithFrame:CGRectZero]; MDCInkView *inkView = [MDCInkView new]; 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];