From cee5bbb4f3dc0abc2a1a3d4ee6cf080614d8d848 Mon Sep 17 00:00:00 2001 From: Ben Guild Date: Sun, 30 Sep 2018 15:12:00 +0900 Subject: [PATCH] Code cleanup. --- BGTableViewRowActionWithImage.h | 41 +++-- BGTableViewRowActionWithImage.m | 147 +++++++++++------- BGTableViewRowActionWithImage.podspec | 2 +- .../AppDelegate.swift | 32 ---- .../ViewController.swift | 54 ++----- 5 files changed, 143 insertions(+), 133 deletions(-) diff --git a/BGTableViewRowActionWithImage.h b/BGTableViewRowActionWithImage.h index f6ec832..0aea233 100644 --- a/BGTableViewRowActionWithImage.h +++ b/BGTableViewRowActionWithImage.h @@ -3,20 +3,43 @@ // BGTableViewRowActionWithImage // // Created by Ben Guild on 8/20/15. -// Copyright (c) 2015-2017 Ben Guild. All rights reserved. +// Copyright (c) 2015-2018 Ben Guild. All rights reserved. // #import @interface BGTableViewRowActionWithImage : UITableViewRowAction -+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style title:(NSString *)title backgroundColor:(UIColor *)backgroundColor image:(UIImage *)image forCellHeight:(NSUInteger)cellHeight handler:(void (^)(UITableViewRowAction *, NSIndexPath *))handler NS_DEPRECATED_IOS(8_0, 11_0); - -+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style title:(NSString *)title titleColor:(UIColor *)titleColor backgroundColor:(UIColor *)backgroundColor image:(UIImage *)image forCellHeight:(NSUInteger)cellHeight handler:(void (^)(UITableViewRowAction *, NSIndexPath *))handler NS_DEPRECATED_IOS(8_0, 11_0); - -+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style title:(NSString *)title backgroundColor:(UIColor *)backgroundColor image:(UIImage *)image forCellHeight:(NSUInteger)cellHeight andFittedWidth:(BOOL)isWidthFitted handler:(void (^)(UITableViewRowAction *, NSIndexPath *))handler NS_DEPRECATED_IOS(8_0, 11_0); - -+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style title:(NSString *)title titleColor:(UIColor *)titleColor backgroundColor:(UIColor *)backgroundColor image:(UIImage *)image forCellHeight:(NSUInteger)cellHeight andFittedWidth:(BOOL)isWidthFitted handler:(void (^)(UITableViewRowAction *, NSIndexPath *))handler NS_DEPRECATED_IOS(8_0, 11_0); - ++ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style + title:(NSString *)title + backgroundColor:(UIColor *)backgroundColor + image:(UIImage *)image + forCellHeight:(NSUInteger)cellHeight + handler:(void (^)(UITableViewRowAction *, NSIndexPath *))handler NS_DEPRECATED_IOS(8_0, 11_0); + ++ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style + title:(NSString *)title + titleColor:(UIColor *)titleColor + backgroundColor:(UIColor *)backgroundColor + image:(UIImage *)image + forCellHeight:(NSUInteger)cellHeight + handler:(void (^)(UITableViewRowAction *, NSIndexPath *))handler NS_DEPRECATED_IOS(8_0, 11_0); + ++ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style + title:(NSString *)title + backgroundColor:(UIColor *)backgroundColor + image:(UIImage *)image + forCellHeight:(NSUInteger)cellHeight + andFittedWidth:(BOOL)isWidthFitted + handler:(void (^)(UITableViewRowAction *, NSIndexPath *))handler NS_DEPRECATED_IOS(8_0, 11_0); + ++ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style + title:(NSString *)title + titleColor:(UIColor *)titleColor + backgroundColor:(UIColor *)backgroundColor + image:(UIImage *)image + forCellHeight:(NSUInteger)cellHeight + andFittedWidth:(BOOL)isWidthFitted + handler:(void (^)(UITableViewRowAction *, NSIndexPath *))handler NS_DEPRECATED_IOS(8_0, 11_0); @end diff --git a/BGTableViewRowActionWithImage.m b/BGTableViewRowActionWithImage.m index a213941..0e50e6d 100644 --- a/BGTableViewRowActionWithImage.m +++ b/BGTableViewRowActionWithImage.m @@ -3,7 +3,7 @@ // BGTableViewRowActionWithImage // // Created by Ben Guild on 8/20/15. -// Copyright (c) 2015-2017 Ben Guild. All rights reserved. +// Copyright (c) 2015-2018 Ben Guild. All rights reserved. // #import "BGTableViewRowActionWithImage.h" @@ -13,11 +13,12 @@ #define fontSize_actuallyUsedUnderImage 13.0f #define margin_horizontal_iOS8AndUp 15.0f -#define margin_vertical_betweenTextAndImage (cellHeight>=64.0f ? 3.0f : 2.0f) +#define margin_vertical_betweenTextAndImage (cellHeight >= 64.0f ? 3.0f : 2.0f) #define fittingMultiplier 0.40f #define imagePaddingHorizontal 20.0 + @implementation BGTableViewRowActionWithImage #pragma mark - Derived constructors @@ -29,7 +30,14 @@ + (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style forCellHeight:(NSUInteger)cellHeight handler:(void (^)(UITableViewRowAction *, NSIndexPath *))handler { - return [self rowActionWithStyle:style title:title titleColor:[UIColor whiteColor] backgroundColor:backgroundColor image:image forCellHeight:cellHeight andFittedWidth:NO handler:handler]; + return [self rowActionWithStyle:style + title:title + titleColor:[UIColor whiteColor] + backgroundColor:backgroundColor + image:image + forCellHeight:cellHeight + andFittedWidth:NO + handler:handler]; } + (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style @@ -40,7 +48,14 @@ + (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style forCellHeight:(NSUInteger)cellHeight handler:(void (^)(UITableViewRowAction *, NSIndexPath *))handler { - return [self rowActionWithStyle:style title:title titleColor:titleColor backgroundColor:backgroundColor image:image forCellHeight:cellHeight andFittedWidth:NO handler:handler]; + return [self rowActionWithStyle:style + title:title + titleColor:titleColor + backgroundColor:backgroundColor + image:image + forCellHeight:cellHeight + andFittedWidth:NO + handler:handler]; } + (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style @@ -51,67 +66,95 @@ + (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style andFittedWidth:(BOOL)isWidthFitted handler:(void (^)(UITableViewRowAction *, NSIndexPath *))handler { - return [self rowActionWithStyle:style title:title titleColor:[UIColor whiteColor] backgroundColor:backgroundColor image:image forCellHeight:cellHeight andFittedWidth:isWidthFitted handler:handler]; + return [self rowActionWithStyle:style + title:title + titleColor:[UIColor whiteColor] + backgroundColor:backgroundColor + image:image + forCellHeight:cellHeight + andFittedWidth:isWidthFitted + handler:handler]; } #pragma mark - Main constructor -+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style title:(NSString *)title titleColor:(UIColor *)titleColor backgroundColor:(UIColor *)backgroundColor image:(UIImage *)image forCellHeight:(NSUInteger)cellHeight andFittedWidth:(BOOL)isWidthFitted handler:(void (^)(UITableViewRowAction *, NSIndexPath *))handler -{ - if (title==nil && image!=nil) - { - CGFloat emptySpaceWidth=[@"\u3000" boundingRectWithSize:CGSizeMake(MAXFLOAT, cellHeight) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:fontSize_actuallyUsedUnderImage] } context:nil].size.width; - - CGFloat number=ceil((imagePaddingHorizontal+image.size.width+imagePaddingHorizontal)/emptySpaceWidth); - title=[@"" stringByPaddingToLength:number withString:@"\u3000" startingAtIndex:0]; - ++ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style + title:(NSString *)title + titleColor:(UIColor *)titleColor + backgroundColor:(UIColor *)backgroundColor + image:(UIImage *)image + forCellHeight:(NSUInteger)cellHeight + andFittedWidth:(BOOL)isWidthFitted + handler:(void (^)(UITableViewRowAction *, NSIndexPath *))handler { + if (title == nil && image != nil) { + CGFloat emptySpaceWidth = [@"\u3000" boundingRectWithSize:CGSizeMake(MAXFLOAT, cellHeight) + options:NSStringDrawingUsesLineFragmentOrigin + attributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:fontSize_actuallyUsedUnderImage] } + context:nil].size.width; + + title = [@"" stringByPaddingToLength:ceil((imagePaddingHorizontal + image.size.width+imagePaddingHorizontal) / emptySpaceWidth) + withString:@"\u3000" + startingAtIndex:0]; } - - __block NSUInteger titleMaximumLineLength=0; - - [title enumerateLinesUsingBlock:^(NSString * _Nonnull line, BOOL * _Nonnull stop) - { - titleMaximumLineLength=MAX(titleMaximumLineLength, [line length]); - + + __block NSUInteger titleMaximumLineLength = 0; + + [title enumerateLinesUsingBlock:^(NSString * _Nonnull line, BOOL * _Nonnull stop) { + titleMaximumLineLength = MAX(titleMaximumLineLength, [line length]); } ]; - - float titleMultiplier=(isWidthFitted ? fittingMultiplier : (fontSize_actuallyUsedUnderImage/fontSize_iOS8AndUpDefault)/1.1f); // NOTE: This isn't exact, but it's close enough in most instances? I tested with full-width Asian characters and it accounts for those pretty well. - - NSString *titleSpaceString=[@"" stringByPaddingToLength:titleMaximumLineLength*titleMultiplier withString:@"\u3000" startingAtIndex:0]; - - BGTableViewRowActionWithImage *rowAction=(BGTableViewRowActionWithImage *)[self rowActionWithStyle:style title:titleSpaceString handler:handler]; - - CGFloat contentWidth=[titleSpaceString boundingRectWithSize:CGSizeMake(MAXFLOAT, cellHeight) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:fontSize_iOS8AndUpDefault] } context:nil].size.width; - - CGSize frameGuess=CGSizeMake(ceilf((margin_horizontal_iOS8AndUp*2)+contentWidth), ceilf(cellHeight)); - - CGSize tripleFrame=CGSizeMake(frameGuess.width*3.0f, frameGuess.height*3.0f); - + + float titleMultiplier = (isWidthFitted ? fittingMultiplier : (fontSize_actuallyUsedUnderImage / fontSize_iOS8AndUpDefault) / 1.1f); + // NOTE: This isn't exact, but it's close enough in most instances? I tested with full-width Asian characters and it accounts for those pretty well. + + NSString *titleSpaceString = [@"" stringByPaddingToLength:titleMaximumLineLength*titleMultiplier + withString:@"\u3000" + startingAtIndex:0]; + + BGTableViewRowActionWithImage *rowAction = (BGTableViewRowActionWithImage *)[self rowActionWithStyle:style + title:titleSpaceString + handler:handler]; + + CGFloat contentWidth = [titleSpaceString boundingRectWithSize:CGSizeMake(MAXFLOAT, cellHeight) + options:NSStringDrawingUsesLineFragmentOrigin + attributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:fontSize_iOS8AndUpDefault] } + context:nil].size.width; + + CGSize frameGuess = CGSizeMake(ceilf((margin_horizontal_iOS8AndUp*2) + contentWidth), ceilf(cellHeight)); + + CGSize tripleFrame = CGSizeMake(frameGuess.width * 3.0f, frameGuess.height * 3.0f); + UIGraphicsBeginImageContextWithOptions(tripleFrame, YES, [[UIScreen mainScreen] scale]); - CGContextRef context=UIGraphicsGetCurrentContext(); - + CGContextRef context = UIGraphicsGetCurrentContext(); + [backgroundColor set]; CGContextFillRect(context, CGRectMake(0, 0, tripleFrame.width, tripleFrame.height)); - - CGSize drawnTextSize=[title boundingRectWithSize:CGSizeMake(MAXFLOAT, cellHeight) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:fontSize_actuallyUsedUnderImage] } context:nil].size; - - CGFloat imageInsetVertical=([image size].height/2.0); - - if ([[title stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length]) - { - imageInsetVertical=([image size].height+margin_vertical_betweenTextAndImage+drawnTextSize.height)/2.0f; - + + CGSize drawnTextSize = [title boundingRectWithSize:CGSizeMake(MAXFLOAT, cellHeight) + options:NSStringDrawingUsesLineFragmentOrigin + attributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:fontSize_actuallyUsedUnderImage] } + context:nil].size; + + CGFloat imageInsetVertical = ([image size].height / 2.0); + + if ([[title stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] > 0) { + imageInsetVertical = ([image size].height + margin_vertical_betweenTextAndImage+drawnTextSize.height) / 2.0f; } - - [image drawAtPoint:CGPointMake((frameGuess.width/2.0f)-([image size].width/2.0f), (frameGuess.height/2.0f)-imageInsetVertical)]; - [title drawInRect:CGRectMake(((frameGuess.width/2.0f)-(drawnTextSize.width/2.0f))*([[UIApplication sharedApplication] userInterfaceLayoutDirection]==UIUserInterfaceLayoutDirectionRightToLeft ? -1 : 1), (frameGuess.height/2.0f)-imageInsetVertical+[image size].height+margin_vertical_betweenTextAndImage, frameGuess.width, frameGuess.height) withAttributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:fontSize_actuallyUsedUnderImage], NSForegroundColorAttributeName: titleColor }]; - + + [image drawAtPoint:CGPointMake((frameGuess.width / 2.0f) - ([image size].width / 2.0f), + (frameGuess.height / 2.0f) - imageInsetVertical)]; + + [title drawInRect:CGRectMake(((frameGuess.width / 2.0f) - (drawnTextSize.width / 2.0f)) * ([[UIApplication sharedApplication] userInterfaceLayoutDirection] == UIUserInterfaceLayoutDirectionRightToLeft ? -1 : 1), + (frameGuess.height / 2.0f) - imageInsetVertical + [image size].height + margin_vertical_betweenTextAndImage, + frameGuess.width, + frameGuess.height) + withAttributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:fontSize_actuallyUsedUnderImage], + NSForegroundColorAttributeName: titleColor }]; + [rowAction setBackgroundColor:[UIColor colorWithPatternImage:UIGraphicsGetImageFromCurrentImageContext()]]; + UIGraphicsEndImageContext(); - //// - + return rowAction; - } @end diff --git a/BGTableViewRowActionWithImage.podspec b/BGTableViewRowActionWithImage.podspec index e18ef5d..9dcbdc7 100644 --- a/BGTableViewRowActionWithImage.podspec +++ b/BGTableViewRowActionWithImage.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "BGTableViewRowActionWithImage" - s.version = "0.4.4" + s.version = "0.4.5" s.homepage = "https://github.com/benguild/BGTableViewRowActionWithImage" s.screenshots = "https://raw.github.com/benguild/BGTableViewRowActionWithImage/master/demo.jpg" s.summary = "A variation on the iOS 8-10 (not supported in 11+) `UITableViewRowAction` to support icons, with text below. Similar to the iOS 9 Mail app." diff --git a/Example/BGTableViewRowActionWithImage/AppDelegate.swift b/Example/BGTableViewRowActionWithImage/AppDelegate.swift index b549558..366c962 100644 --- a/Example/BGTableViewRowActionWithImage/AppDelegate.swift +++ b/Example/BGTableViewRowActionWithImage/AppDelegate.swift @@ -10,37 +10,5 @@ import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - var window: UIWindow? - - - func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { - // Override point for customization after application launch. - return true - } - - func applicationWillResignActive(application: UIApplication) { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. - } - - func applicationDidEnterBackground(application: UIApplication) { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. - } - - func applicationWillEnterForeground(application: UIApplication) { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. - } - - func applicationDidBecomeActive(application: UIApplication) { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. - } - - func applicationWillTerminate(application: UIApplication) { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. - } - - } - diff --git a/Example/BGTableViewRowActionWithImage/ViewController.swift b/Example/BGTableViewRowActionWithImage/ViewController.swift index ecdd435..6d0908c 100644 --- a/Example/BGTableViewRowActionWithImage/ViewController.swift +++ b/Example/BGTableViewRowActionWithImage/ViewController.swift @@ -9,61 +9,37 @@ import UIKit import BGTableViewRowActionWithImage - class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { - @IBOutlet weak var tableView: UITableView! - - + override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view, typically from a nib. - tableView.rowHeight = 80 } - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. - } - + // MARK: - - - // MARK: UITableViewDataSource - func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return 10 } - + func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { - - - let identifier = "Identifier" - - let cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) - - return cell - + return tableView.dequeueReusableCellWithIdentifier("identifier", forIndexPath: indexPath) } - - // MARK: UITableViewDelegate - + + // MARK: - + func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? { - - let image = UIImage(named: "star") - let title: String? = indexPath.row%2==0 ? "action" : nil - let cellHeight = UInt(tableView.rowHeight) - - let action = BGTableViewRowActionWithImage.rowActionWithStyle(UITableViewRowActionStyle.Default, title: title, backgroundColor: .lightGrayColor(), image: image, forCellHeight: cellHeight) { (action, indexPath) in - - + let action = BGTableViewRowActionWithImage.rowActionWithStyle( + UITableViewRowActionStyle.Default, + title: ((indexPath.row % 2) == 0 ? "action" : nil), + backgroundColor: .lightGrayColor(), + image: UIImage(named: "star"), + forCellHeight: UInt(tableView.rowHeight), + ) { (action, indexPath) in print("Selected action on indexPath=\(indexPath.section)/\(indexPath.row)") } - + return [action] - } - } -