I'm designing an iOS app with a UICollectionView, and I'd like users to be able to select multiple items within this view. It seems there's a standard style of checkmark Apple uses in this kind of situation. For example, in the image below you can see it when selecting multiple photos in a share sheet.
According to the documentation, you are responsible for updating the UI of your cells to reflect their selection state. I know on a UITableViewCell you can set the accessoryType property to add a checkmark, but I can't seem to find any equivalent for a UICollectionViewCell.
Is there a way Apple provides to use this checkmark in my app, besides trying to rip this icon out of a screenshot?
I ended up recreating the checkmarks using PaintCode. Here's what they look like:
They're drawn with vector graphics, so they'll look great at whatever size you want. These are 30x30. I also included an option to use a grayed-out checkmark instead of the open circle when an item is not selected.
To use these, copy the following class into your project. Then, add a UIView to your storyboard or xib, and set its custom class to SSCheckMark.
SSCheckMark.h
#import <UIKit/UIKit.h> typedef NS_ENUM( NSUInteger, SSCheckMarkStyle ) { SSCheckMarkStyleOpenCircle, SSCheckMarkStyleGrayedOut }; @interface SSCheckMark : UIView @property (readwrite) bool checked; @property (readwrite) SSCheckMarkStyle checkMarkStyle; @end
SSCheckMark.m
#import "SSCheckMark.h" @implementation SSCheckMark - (void) drawRect:(CGRect)rect { [super drawRect:rect]; if ( self.checked ) [self drawRectChecked:rect]; else { if ( self.checkMarkStyle == SSCheckMarkStyleOpenCircle ) [self drawRectOpenCircle:rect]; else if ( self.checkMarkStyle == SSCheckMarkStyleGrayedOut ) [self drawRectGrayedOut:rect]; } } - (void) setChecked:(bool)checked { _checked = checked; [self setNeedsDisplay]; } - (void) setCheckMarkStyle:(SSCheckMarkStyle)checkMarkStyle { _checkMarkStyle = checkMarkStyle; [self setNeedsDisplay]; } - (void) drawRectChecked: (CGRect) rect { //// General Declarations CGContextRef context = UIGraphicsGetCurrentContext(); //// Color Declarations UIColor* checkmarkBlue2 = [UIColor colorWithRed: 0.078 green: 0.435 blue: 0.875 alpha: 1]; //// Shadow Declarations UIColor* shadow2 = [UIColor blackColor]; CGSize shadow2Offset = CGSizeMake(0.1, -0.1); CGFloat shadow2BlurRadius = 2.5; //// Frames CGRect frame = self.bounds; //// Subframes CGRect group = CGRectMake(CGRectGetMinX(frame) + 3, CGRectGetMinY(frame) + 3, CGRectGetWidth(frame) - 6, CGRectGetHeight(frame) - 6); //// Group { //// CheckedOval Drawing UIBezierPath* checkedOvalPath = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(CGRectGetMinX(group) + floor(CGRectGetWidth(group) * 0.00000 + 0.5), CGRectGetMinY(group) + floor(CGRectGetHeight(group) * 0.00000 + 0.5), floor(CGRectGetWidth(group) * 1.00000 + 0.5) - floor(CGRectGetWidth(group) * 0.00000 + 0.5), floor(CGRectGetHeight(group) * 1.00000 + 0.5) - floor(CGRectGetHeight(group) * 0.00000 + 0.5))]; CGContextSaveGState(context); CGContextSetShadowWithColor(context, shadow2Offset, shadow2BlurRadius, shadow2.CGColor); [checkmarkBlue2 setFill]; [checkedOvalPath fill]; CGContextRestoreGState(context); [[UIColor whiteColor] setStroke]; checkedOvalPath.lineWidth = 1; [checkedOvalPath stroke]; //// Bezier Drawing UIBezierPath* bezierPath = [UIBezierPath bezierPath]; [bezierPath moveToPoint: CGPointMake(CGRectGetMinX(group) + 0.27083 * CGRectGetWidth(group), CGRectGetMinY(group) + 0.54167 * CGRectGetHeight(group))]; [bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(group) + 0.41667 * CGRectGetWidth(group), CGRectGetMinY(group) + 0.68750 * CGRectGetHeight(group))]; [bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(group) + 0.75000 * CGRectGetWidth(group), CGRectGetMinY(group) + 0.35417 * CGRectGetHeight(group))]; bezierPath.lineCapStyle = kCGLineCapSquare; [[UIColor whiteColor] setStroke]; bezierPath.lineWidth = 1.3; [bezierPath stroke]; } } - (void) drawRectGrayedOut: (CGRect) rect { //// General Declarations CGContextRef context = UIGraphicsGetCurrentContext(); //// Color Declarations UIColor* grayTranslucent = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 0.6]; //// Shadow Declarations UIColor* shadow2 = [UIColor blackColor]; CGSize shadow2Offset = CGSizeMake(0.1, -0.1); CGFloat shadow2BlurRadius = 2.5; //// Frames CGRect frame = self.bounds; //// Subframes CGRect group = CGRectMake(CGRectGetMinX(frame) + 3, CGRectGetMinY(frame) + 3, CGRectGetWidth(frame) - 6, CGRectGetHeight(frame) - 6); //// Group { //// UncheckedOval Drawing UIBezierPath* uncheckedOvalPath = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(CGRectGetMinX(group) + floor(CGRectGetWidth(group) * 0.00000 + 0.5), CGRectGetMinY(group) + floor(CGRectGetHeight(group) * 0.00000 + 0.5), floor(CGRectGetWidth(group) * 1.00000 + 0.5) - floor(CGRectGetWidth(group) * 0.00000 + 0.5), floor(CGRectGetHeight(group) * 1.00000 + 0.5) - floor(CGRectGetHeight(group) * 0.00000 + 0.5))]; CGContextSaveGState(context); CGContextSetShadowWithColor(context, shadow2Offset, shadow2BlurRadius, shadow2.CGColor); [grayTranslucent setFill]; [uncheckedOvalPath fill]; CGContextRestoreGState(context); [[UIColor whiteColor] setStroke]; uncheckedOvalPath.lineWidth = 1; [uncheckedOvalPath stroke]; //// Bezier Drawing UIBezierPath* bezierPath = [UIBezierPath bezierPath]; [bezierPath moveToPoint: CGPointMake(CGRectGetMinX(group) + 0.27083 * CGRectGetWidth(group), CGRectGetMinY(group) + 0.54167 * CGRectGetHeight(group))]; [bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(group) + 0.41667 * CGRectGetWidth(group), CGRectGetMinY(group) + 0.68750 * CGRectGetHeight(group))]; [bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(group) + 0.75000 * CGRectGetWidth(group), CGRectGetMinY(group) + 0.35417 * CGRectGetHeight(group))]; bezierPath.lineCapStyle = kCGLineCapSquare; [[UIColor whiteColor] setStroke]; bezierPath.lineWidth = 1.3; [bezierPath stroke]; } } - (void) drawRectOpenCircle: (CGRect) rect { //// General Declarations CGContextRef context = UIGraphicsGetCurrentContext(); //// Shadow Declarations UIColor* shadow = [UIColor blackColor]; CGSize shadowOffset = CGSizeMake(0.1, -0.1); CGFloat shadowBlurRadius = 0.5; UIColor* shadow2 = [UIColor blackColor]; CGSize shadow2Offset = CGSizeMake(0.1, -0.1); CGFloat shadow2BlurRadius = 2.5; //// Frames CGRect frame = self.bounds; //// Subframes CGRect group = CGRectMake(CGRectGetMinX(frame) + 3, CGRectGetMinY(frame) + 3, CGRectGetWidth(frame) - 6, CGRectGetHeight(frame) - 6); //// Group { //// EmptyOval Drawing UIBezierPath* emptyOvalPath = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(CGRectGetMinX(group) + floor(CGRectGetWidth(group) * 0.00000 + 0.5), CGRectGetMinY(group) + floor(CGRectGetHeight(group) * 0.00000 + 0.5), floor(CGRectGetWidth(group) * 1.00000 + 0.5) - floor(CGRectGetWidth(group) * 0.00000 + 0.5), floor(CGRectGetHeight(group) * 1.00000 + 0.5) - floor(CGRectGetHeight(group) * 0.00000 + 0.5))]; CGContextSaveGState(context); CGContextSetShadowWithColor(context, shadow2Offset, shadow2BlurRadius, shadow2.CGColor); CGContextRestoreGState(context); CGContextSaveGState(context); CGContextSetShadowWithColor(context, shadowOffset, shadowBlurRadius, shadow.CGColor); [[UIColor whiteColor] setStroke]; emptyOvalPath.lineWidth = 1; [emptyOvalPath stroke]; CGContextRestoreGState(context); } } @end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With