如何在UICollectionViewCell上显示标准复选标记?

我正在devise一个带有UICollectionView的iOS应用程序,我希望用户能够在这个视图中select多个项目。 看来苹果公司在这种情况下使用的标记标记风格。 例如,在下面的图片中,您可以在分享工作表中select多张照片时看到它。

根据文档 ,您负责更新单元的UI以反映其select状态。 我知道在UITableViewCell上,你可以设置accessoryType属性来添加一个复选标记,但我似乎无法findUICollectionViewCell的任何等价物。

有没有一种方法苹果公司提供使用这个复选标记在我的应用程序,除了试图从图像中抓取这个图标?

在这里输入图像说明

我最终重新使用PaintCode复选标记。 以下是他们的样子:

定制的复选标记

他们用vectorgraphics绘制,所以他们会看起来很棒,无论你想要的大小。 这些是30×30。 我还包括一个选项,当一个项目没有被选中时,使用一个灰色的复选标记而不是打开的圆圈。

要使用这些,请将以下类复制到您的项目中。 然后,将UIView添加到故事板或xib,并将其自定义类设置为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 

一种可能性是创build一个UIView,绘制同心圆,然后从您select的字体中选中一个复选标记。 要查找复选标记字符,请转到Xcode中的编辑>特殊字符(或具有该菜单项的任何其他应用程序),然后search“检查”。 当您select其中一个search结果时,您会在右下angular看到字体变化。

在这里输入图像说明

Chris Vasellis的很好的解决scheme的Swift 3版本:

 import UIKit enum SSCheckMarkStyle : UInt { case OpenCircle case GrayedOut } class SSCheckMark: UIView { private var checkedBool: Bool = false // choose whether you like open or grayed out non-selected items private var checkMarkStyleReal: SSCheckMarkStyle=SSCheckMarkStyle.GrayedOut var checked: Bool { get { return self.checkedBool } set(checked) { self.checkedBool = checked self.setNeedsDisplay() } } var checkMarkStyle: SSCheckMarkStyle { get { return self.checkMarkStyleReal } set(checkMarkStyle) { self.checkMarkStyleReal = checkMarkStyle self.setNeedsDisplay() } } override func draw(_ rect: CGRect) { super.draw(rect) if self.checked { self.drawRectChecked(rect: rect) } else { if self.checkMarkStyle == SSCheckMarkStyle.OpenCircle { self.drawRectOpenCircle(rect: rect) } else if self.checkMarkStyle == SSCheckMarkStyle.GrayedOut { self.drawRectGrayedOut(rect: rect) } } } func drawRectChecked(rect: CGRect) { let context = UIGraphicsGetCurrentContext() let checkmarkBlue2 = UIColor(red: 0.078, green: 0.435, blue: 0.875, alpha: 1) let shadow2 = UIColor.black let shadow2Offset = CGSize(width: 0.1, height: -0.1) let shadow2BlurRadius = 2.5 let frame = self.bounds let group = CGRect(x: frame.minX + 3, y: frame.minY + 3, width: frame.width - 6, height: frame.height - 6) let checkedOvalPath = UIBezierPath(ovalIn: CGRect(x: group.minX + floor(group.width * 0.00000 + 0.5), y: group.minY + floor(group.height * 0.00000 + 0.5), width: floor(group.width * 1.00000 + 0.5) - floor(group.width * 0.00000 + 0.5), height: floor(group.height * 1.00000 + 0.5) - floor(group.height * 0.00000 + 0.5))) context!.saveGState() context!.setShadow(offset: shadow2Offset, blur: CGFloat(shadow2BlurRadius), color: shadow2.cgColor) checkmarkBlue2.setFill() checkedOvalPath.fill() context!.restoreGState() UIColor.white.setStroke() checkedOvalPath.lineWidth = 1 checkedOvalPath.stroke() let bezierPath = UIBezierPath() bezierPath.move(to: CGPoint(x: group.minX + 0.27083 * group.width, y: group.minY + 0.54167 * group.height)) bezierPath.addLine(to: CGPoint(x: group.minX + 0.41667 * group.width, y: group.minY + 0.68750 * group.height)) bezierPath.addLine(to: CGPoint(x: group.minX + 0.75000 * group.width, y: group.minY + 0.35417 * group.height)) bezierPath.lineCapStyle = CGLineCap.square UIColor.white.setStroke() bezierPath.lineWidth = 1.3 bezierPath.stroke() } func drawRectGrayedOut(rect: CGRect) { let context = UIGraphicsGetCurrentContext() let grayTranslucent = UIColor(red: 1, green: 1, blue: 1, alpha: 0.6) let shadow2 = UIColor.black let shadow2Offset = CGSize(width: 0.1, height: -0.1) let shadow2BlurRadius = 2.5 let frame = self.bounds let group = CGRect(x: frame.minX + 3, y: frame.minY + 3, width: frame.width - 6, height: frame.height - 6) let uncheckedOvalPath = UIBezierPath(ovalIn: CGRect(x: group.minX + floor(group.width * 0.00000 + 0.5), y: group.minY + floor(group.height * 0.00000 + 0.5), width: floor(group.width * 1.00000 + 0.5) - floor(group.width * 0.00000 + 0.5), height: floor(group.height * 1.00000 + 0.5) - floor(group.height * 0.00000 + 0.5))) context!.saveGState() context!.setShadow(offset: shadow2Offset, blur: CGFloat(shadow2BlurRadius), color: shadow2.cgColor) grayTranslucent.setFill() uncheckedOvalPath.fill() context!.restoreGState() UIColor.white.setStroke() uncheckedOvalPath.lineWidth = 1 uncheckedOvalPath.stroke() let bezierPath = UIBezierPath() bezierPath.move(to: CGPoint(x: group.minX + 0.27083 * group.width, y: group.minY + 0.54167 * group.height)) bezierPath.addLine(to: CGPoint(x: group.minX + 0.41667 * group.width, y: group.minY + 0.68750 * group.height)) bezierPath.addLine(to: CGPoint(x: group.minX + 0.75000 * group.width, y: group.minY + 0.35417 * group.height)) bezierPath.lineCapStyle = CGLineCap.square UIColor.white.setStroke() bezierPath.lineWidth = 1.3 bezierPath.stroke() } func drawRectOpenCircle(rect: CGRect) { let context = UIGraphicsGetCurrentContext() let shadow = UIColor.black let shadowOffset = CGSize(width: 0.1, height: -0.1) let shadowBlurRadius = 0.5 let shadow2 = UIColor.black let shadow2Offset = CGSize(width: 0.1, height: -0.1) let shadow2BlurRadius = 2.5 let frame = self.bounds let group = CGRect(x: frame.minX + 3, y: frame.minY + 3, width: frame.width - 6, height: frame.height - 6) let emptyOvalPath = UIBezierPath(ovalIn: CGRect(x: group.minX + floor(group.width * 0.00000 + 0.5), y: group.minY + floor(group.height * 0.00000 + 0.5), width: floor(group.width * 1.00000 + 0.5) - floor(group.width * 0.00000 + 0.5), height: floor(group.height * 1.00000 + 0.5) - floor(group.height * 0.00000 + 0.5))) context!.saveGState() context!.setShadow(offset: shadow2Offset, blur: CGFloat(shadow2BlurRadius), color: shadow2.cgColor) context!.restoreGState() context!.saveGState() context!.setShadow(offset: shadowOffset, blur: CGFloat(shadowBlurRadius), color: shadow.cgColor) UIColor.white.setStroke() emptyOvalPath.lineWidth = 1 emptyOvalPath.stroke() context!.restoreGState() } } 

要在你的代码中使用它,用上面的内容创build一个名为SSCheckMark.swift的文件,并将其分配给你的View。 我在CollectionViewCells中使用它,为此我创build了一个自定义类(代码简化了很多):

 class myCollectionViewCell: UICollectionViewCell { var checkmarkView: SSCheckMark! override init(frame: CGRect) { super.init(frame: frame) checkmarkView = SSCheckMark(frame: CGRect(x: frame.width-40, y: 10, width: 35, height: 35)) checkmarkView.backgroundColor = UIColor.white myView.addSubview(checkmarkView) } } 

而在我的UIViewController,我有这个:

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell:ProductCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath) as! myCollectionViewCell cell.checkmarkView.checked = myBoolValue return cell }