This repository has been archived by the owner on Jun 27, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 24
/
BGTableViewRowActionWithImage.m
162 lines (129 loc) · 7.79 KB
/
BGTableViewRowActionWithImage.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//
// BGTableViewRowActionWithImage.m
// BGTableViewRowActionWithImage
//
// Created by Ben Guild on 8/20/15.
// Copyright (c) 2015-2018 Ben Guild. All rights reserved.
//
#import "BGTableViewRowActionWithImage.h"
#define fontSize_iOS8AndUpDefault 18.0f
#define fontSize_actuallyUsedUnderImage 13.0f
#define margin_horizontal_iOS8AndUp 15.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
+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style
title:(NSString *)title
backgroundColor:(UIColor *)backgroundColor
image:(UIImage *)image
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];
}
+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style
title:(NSString *)title
titleColor:(UIColor *)titleColor
backgroundColor:(UIColor *)backgroundColor
image:(UIImage *)image
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];
}
+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style
title:(NSString *)title
backgroundColor:(UIColor *)backgroundColor
image:(UIImage *)image
forCellHeight:(NSUInteger)cellHeight
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];
}
#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;
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]);
}];
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();
[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] > 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 }];
[rowAction setBackgroundColor:[UIColor colorWithPatternImage:UIGraphicsGetImageFromCurrentImageContext()]];
UIGraphicsEndImageContext();
return rowAction;
}
@end