Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I display the standard checkmark on a UICollectionViewCell?

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?

enter image description here

like image 631
Chris Vasselli Avatar asked Sep 24 '13 09:09

Chris Vasselli


1 Answers

I ended up recreating the checkmarks using PaintCode. Here's what they look like:

Custom-made checkmarks

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 
like image 93
Chris Vasselli Avatar answered Oct 03 '22 21:10

Chris Vasselli