MPCoachMarks is an iOS class that displays user coach marks with a couple of shapescutout over an existing UI. This approach leverages your actual UI as part of the onboarding process for your user.
Based on the greats project WSCoachMarksView and DDCoachMarks I created this repo to maintain the coach mark projects with the idea to improve the existing project and add some extra functionalities based on each fork and issue for the old proyects.
MPCoachMarks works on any iOS version and is built with ARC. It depends on the following Apple frameworks:
- Foundation.framework
- UIKit.framework
- QuartzCore.framework
CocoaPods is the recommended way to add MPCoachMarks to your project.
- Add a pod entry for MPCoachMarks to your Podfile:
pod 'MPCoachMarks'
- Install the pod(s) by running
pod install
. - Include MPCoachMarks wherever you need it with
#import "MPCoachMarks.h"
.
Alternatively, you can directly add the MPCoachMarks.h
and MPCoachMarks.m
source files to your project.
- Download the latest code version or add the repository as a git submodule to your git-tracked project.
- Open your project in Xcode, than drag and drop
MPCoachMarks.h
andMPCoachMarks.m
onto your project (use the "Product Navigator view"). Make sure to select Copy items when asked if you extracted the code archive outside of your project. - Include MPCoachMarks wherever you need it with
#import "MPCoachMarks.h"
.
Create a new MPCoachMarks instance in your viewDidLoad method and pass in an array of coach mark definitions (each containing a CGRect for the rectangle and its accompanying caption).
- (void)viewDidLoad {
[super viewDidLoad];
// ...
// Setup coach marks
CGRect coachmark1 = CGRectMake(([UIScreen mainScreen].bounds.size.width - 125) / 2, 64, 125, 125);
CGRect coachmark2 = CGRectMake(([UIScreen mainScreen].bounds.size.width - 300) / 2, coachmark1.origin.y + coachmark1.size.height, 300, 80);
CGRect coachmark3 = CGRectMake(2, 20, 45, 45);
// Setup coach marks
NSArray *coachMarks = @[
@{
@"rect": [NSValue valueWithCGRect:coachmark1],
@"caption": @"You can put marks over images",
@"shape": [NSNumber numberWithInteger:SHAPE_CIRCLE],
@"position":[NSNumber numberWithInteger:LABEL_POSITION_BOTTOM],
@"alignment":[NSNumber numberWithInteger:LABEL_ALIGNMENT_RIGHT],
@"showArrow":[NSNumber numberWithBool:YES]
},
@{
@"rect": [NSValue valueWithCGRect:coachmark2],
@"caption": @"Also, we can show buttons"
},
@{
@"rect": [NSValue valueWithCGRect:coachmark3],
@"caption": @"And works with navigations buttons too",
@"shape": [NSNumber numberWithInteger:SHAPE_SQUARE],
}
];
MPCoachMarks *coachMarksView = [[MPCoachMarks alloc] initWithFrame:self.view.bounds coachMarks:coachMarks];
[self.view addSubview:coachMarksView];
[coachMarksView start];
}
Remember to add the coach marks view to the top-most controller. So if you have a navigation controller, use:
MPCoachMarks *coachMarksView = [[MPCoachMarks alloc] initWithFrame:self.navigationController.view.bounds coachMarks:coachMarks];
[self.navigationController.view addSubview:coachMarksView];
[coachMarksView start];
You can configure MPCoachMarks before you present it using the start
method. For example:
coachMarksView.animationDuration = 0.5f;
coachMarksView.enableContinueLabel = NO;
[coachMarksView start];
Example of how to show the coach marks to your user only once (assumes coachMarksView
is instantiated in viewDidLoad
):
- (void)viewDidAppear:(BOOL)animated {
// Show coach marks
BOOL coachMarksShown = [[NSUserDefaults standardUserDefaults] boolForKey:@"MPCoachMarksShown"];
if (coachMarksShown == NO) {
// Don't show again
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"MPCoachMarksShown"];
[[NSUserDefaults standardUserDefaults] synchronize];
// Show coach marks
[coachMarksView start];
// Or show coach marks after a second delay
// [coachMarksView performSelector:@selector(start) withObject:nil afterDelay:1.0f];
}
}
Modify the coach marks.
You can use 3 differents types of shape:
- DEFAULT (or empty)
- SHAPE_CIRCLE
- SHAPE_SQUARE
(Square with borders rounded it's DEFAULT)
You can use 5 differents position of caption label:
- LABEL_POSITION_BOTTOM (or empty)
- LABEL_POSITION_LEFT
- LABEL_POSITION_TOP
- LABEL_POSITION_RIGHT
- LABEL_POSITION_RIGHT_BOTTOM
(LABEL_POSITION_BOTTOM it's default)
You can use 3 differents types of shape:
- LABEL_ALIGNMENT_CENTER (or empty)
- LABEL_ALIGNMENT_LEFT
- LABEL_ALIGNMENT_RIGHT
(LABEL_ALIGNMENT_CENTER it's default)
You can show or hide arrow image (By default it's set NO)
Access the captions label.
Access the continues label.
Access the skip button.
The color of the mask (default: 0,0,0 alpha 0.9).
Transition animation duration to the next coach mark (default: 0.3).
The cutout rectangle radius (default: 2px).
The captions label is set to have a max width of 230px. Number of lines is figured out automatically based on caption contents.
Define how far the captions label appears above or below the cutout (default: 35px).
'Tap to continue' label pops up by default to guide the user at the first coach mark (default: YES).
Text of continue label (default: 'Tap to continue').
Set te position of 'continue label'.
You can use 3 differents position:
- LOCATION_TOP
- LOCATION_CENTER
- LOCATION_BOTTOM
(LOCATION_BOTTOM it's default)
Text of skip button (default: 'Skip').
If you'd like to take a certain action when a specific coach mark comes into view, your view controller can implement the MPCoachMarksViewDelegate.
@interface WSMainViewController : UIViewController <MPCoachMarksViewDelegate>
coachMarksView.delegate = self;
Note: All of the methods are optional. Implement only those that are needed.
- (void)coachMarksView:(MPCoachMarksView*)coachMarksView willNavigateToIndex:(NSUInteger)index
- (void)coachMarksView:(MPCoachMarksView*)coachMarksView didNavigateToIndex:(NSUInteger)index
- (void)coachMarksViewWillCleanup:(MPCoachMarksView*)coachMarksView
- (void)coachMarksViewDidCleanup:(MPCoachMarksView*)coachMarksView
- (void)coachMarksViewDidClicked:(MPCoachMarks *)coachMarksView atIndex:(NSInteger)index
This code is distributed under the terms and conditions of the MIT license.