Add getImageWithString to NCUtils and remove UIImageView+Letters

Signed-off-by: Marcel Müller <marcel-mueller@gmx.de>
This commit is contained in:
Marcel Müller 2023-03-09 16:04:46 +01:00
Родитель 62e3ca3bad
Коммит a22c9f0993
5 изменённых файлов: 68 добавлений и 350 удалений

Просмотреть файл

@ -174,7 +174,6 @@
2C62AFB624C1A449007E460A /* Share.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2C62AFB524C1A449007E460A /* Share.storyboard */; }; 2C62AFB624C1A449007E460A /* Share.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2C62AFB524C1A449007E460A /* Share.storyboard */; };
2C62AFB924C1A4E6007E460A /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C62AFB824C1A4E6007E460A /* ShareViewController.m */; }; 2C62AFB924C1A4E6007E460A /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C62AFB824C1A4E6007E460A /* ShareViewController.m */; };
2C62AFBB24C1B7B1007E460A /* NCDatabaseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C40281422832EED0000DDFC /* NCDatabaseManager.m */; }; 2C62AFBB24C1B7B1007E460A /* NCDatabaseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C40281422832EED0000DDFC /* NCDatabaseManager.m */; };
2C62AFDF24C1BD8D007E460A /* UIImageView+Letters.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C92195B1F58530B008AC1A3 /* UIImageView+Letters.m */; };
2C62AFFA24C1BDA5007E460A /* NCChatMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA15540208E350300CE8EF0 /* NCChatMessage.m */; }; 2C62AFFA24C1BDA5007E460A /* NCChatMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA15540208E350300CE8EF0 /* NCChatMessage.m */; };
2C62AFFD24C1BDA5007E460A /* NCMessageParameter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C43BA7521309A1000B3068A /* NCMessageParameter.m */; }; 2C62AFFD24C1BDA5007E460A /* NCMessageParameter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C43BA7521309A1000B3068A /* NCMessageParameter.m */; };
2C62AFFF24C1BDAA007E460A /* NCUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA1CCCC1F181741002FE6A2 /* NCUser.m */; }; 2C62AFFF24C1BDAA007E460A /* NCUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA1CCCC1F181741002FE6A2 /* NCUser.m */; };
@ -220,7 +219,6 @@
2C90E5CF1EDF23A00093D85A /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C90E5CE1EDF23A00093D85A /* WebKit.framework */; }; 2C90E5CF1EDF23A00093D85A /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C90E5CE1EDF23A00093D85A /* WebKit.framework */; };
2C90E5D31EE80C870093D85A /* AuthenticationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C90E5D11EE80C870093D85A /* AuthenticationViewController.m */; }; 2C90E5D31EE80C870093D85A /* AuthenticationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C90E5D11EE80C870093D85A /* AuthenticationViewController.m */; };
2C9200C32474262C0050084F /* UIBarButtonItem+Badge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C9200C22474262C0050084F /* UIBarButtonItem+Badge.m */; }; 2C9200C32474262C0050084F /* UIBarButtonItem+Badge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C9200C22474262C0050084F /* UIBarButtonItem+Badge.m */; };
2C92195C1F58530B008AC1A3 /* UIImageView+Letters.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C92195B1F58530B008AC1A3 /* UIImageView+Letters.m */; };
2C98F77921622445001A6A73 /* RoomSearchTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C98F77821622445001A6A73 /* RoomSearchTableViewController.m */; }; 2C98F77921622445001A6A73 /* RoomSearchTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C98F77821622445001A6A73 /* RoomSearchTableViewController.m */; };
2C98F77D216231D3001A6A73 /* RoomTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C98F77C216231D3001A6A73 /* RoomTableViewCell.xib */; }; 2C98F77D216231D3001A6A73 /* RoomTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C98F77C216231D3001A6A73 /* RoomTableViewCell.xib */; };
2C9B0B98217F6DBA00A4752C /* NCNotificationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C9B0B97217F6DBA00A4752C /* NCNotificationController.m */; }; 2C9B0B98217F6DBA00A4752C /* NCNotificationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C9B0B97217F6DBA00A4752C /* NCNotificationController.m */; };
@ -281,7 +279,6 @@
2CC0016924A25C3400A20167 /* NCMessageParameter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C43BA7521309A1000B3068A /* NCMessageParameter.m */; }; 2CC0016924A25C3400A20167 /* NCMessageParameter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C43BA7521309A1000B3068A /* NCMessageParameter.m */; };
2CC0017324A3795B00A20167 /* NCImageSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CBF82BC1FD5AE0A00636459 /* NCImageSessionManager.m */; }; 2CC0017324A3795B00A20167 /* NCImageSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CBF82BC1FD5AE0A00636459 /* NCImageSessionManager.m */; };
2CC0017424A3796400A20167 /* NCAPISessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CBF82B51FD0939600636459 /* NCAPISessionManager.m */; }; 2CC0017424A3796400A20167 /* NCAPISessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CBF82B51FD0939600636459 /* NCAPISessionManager.m */; };
2CC0019A24A37A7C00A20167 /* UIImageView+Letters.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C92195B1F58530B008AC1A3 /* UIImageView+Letters.m */; };
2CC001B724A37A9A00A20167 /* NCUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA1CCCC1F181741002FE6A2 /* NCUser.m */; }; 2CC001B724A37A9A00A20167 /* NCUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA1CCCC1F181741002FE6A2 /* NCUser.m */; };
2CC001C124A37AC500A20167 /* NCNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C9B0B9B217F756B00A4752C /* NCNotification.m */; }; 2CC001C124A37AC500A20167 /* NCNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C9B0B9B217F756B00A4752C /* NCNotification.m */; };
2CC001C224A37AC500A20167 /* NCPushNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CBF82AD1FC888FC00636459 /* NCPushNotification.m */; }; 2CC001C224A37AC500A20167 /* NCPushNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CBF82AD1FC888FC00636459 /* NCPushNotification.m */; };
@ -624,8 +621,6 @@
2C90E5D11EE80C870093D85A /* AuthenticationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AuthenticationViewController.m; sourceTree = "<group>"; }; 2C90E5D11EE80C870093D85A /* AuthenticationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AuthenticationViewController.m; sourceTree = "<group>"; };
2C9200C12474262C0050084F /* UIBarButtonItem+Badge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIBarButtonItem+Badge.h"; sourceTree = "<group>"; }; 2C9200C12474262C0050084F /* UIBarButtonItem+Badge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIBarButtonItem+Badge.h"; sourceTree = "<group>"; };
2C9200C22474262C0050084F /* UIBarButtonItem+Badge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIBarButtonItem+Badge.m"; sourceTree = "<group>"; }; 2C9200C22474262C0050084F /* UIBarButtonItem+Badge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIBarButtonItem+Badge.m"; sourceTree = "<group>"; };
2C92195A1F58530B008AC1A3 /* UIImageView+Letters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImageView+Letters.h"; sourceTree = "<group>"; };
2C92195B1F58530B008AC1A3 /* UIImageView+Letters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImageView+Letters.m"; sourceTree = "<group>"; };
2C928BD2268A06BB00729332 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; }; 2C928BD2268A06BB00729332 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; };
2C928BD3268A06BB00729332 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 2C928BD3268A06BB00729332 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/InfoPlist.strings; sourceTree = "<group>"; };
2C928BD4268A0AAD00729332 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Localizable.strings; sourceTree = "<group>"; }; 2C928BD4268A0AAD00729332 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Localizable.strings; sourceTree = "<group>"; };
@ -965,7 +960,6 @@
2C20269D236832D300DFC89B /* FTPopOverMenu */, 2C20269D236832D300DFC89B /* FTPopOverMenu */,
2CB302F92264775E0053078A /* SlackTextViewController */, 2CB302F92264775E0053078A /* SlackTextViewController */,
2C4E758C214B942D003910D5 /* Firefox */, 2C4E758C214B942D003910D5 /* Firefox */,
2C9219591F58530B008AC1A3 /* UIImageView+Letters */,
2C4D7D601F2F7C2C00FF4A0D /* AppRTC */, 2C4D7D601F2F7C2C00FF4A0D /* AppRTC */,
); );
name = ThirdParty; name = ThirdParty;
@ -1354,16 +1348,6 @@
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
2C9219591F58530B008AC1A3 /* UIImageView+Letters */ = {
isa = PBXGroup;
children = (
2C92195A1F58530B008AC1A3 /* UIImageView+Letters.h */,
2C92195B1F58530B008AC1A3 /* UIImageView+Letters.m */,
);
name = "UIImageView+Letters";
path = "ThirdParty/UIImageView+Letters";
sourceTree = "<group>";
};
2C9B0B99217F6E3400A4752C /* Notifications */ = { 2C9B0B99217F6E3400A4752C /* Notifications */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -2059,7 +2043,6 @@
2CB304192264775E0053078A /* SLKInputAccessoryView.m in Sources */, 2CB304192264775E0053078A /* SLKInputAccessoryView.m in Sources */,
2CA1CC911F014354002FE6A2 /* NCConnectionController.m in Sources */, 2CA1CC911F014354002FE6A2 /* NCConnectionController.m in Sources */,
1FB6678F28CE381300D29F8D /* SubtitleTableViewCell.swift in Sources */, 1FB6678F28CE381300D29F8D /* SubtitleTableViewCell.swift in Sources */,
2C92195C1F58530B008AC1A3 /* UIImageView+Letters.m in Sources */,
1F24B5A228E0648600654457 /* ReferenceGithubView.swift in Sources */, 1F24B5A228E0648600654457 /* ReferenceGithubView.swift in Sources */,
2C4D7D691F2F7DBC00FF4A0D /* ARDSettingsModel.m in Sources */, 2C4D7D691F2F7DBC00FF4A0D /* ARDSettingsModel.m in Sources */,
2CB6ACBC26385A3800D3D641 /* ShareLocationViewController.m in Sources */, 2CB6ACBC26385A3800D3D641 /* ShareLocationViewController.m in Sources */,
@ -2091,7 +2074,6 @@
1F1C0D7F29A7F33600D17C6D /* NCNotificationAction.swift in Sources */, 1F1C0D7F29A7F33600D17C6D /* NCNotificationAction.swift in Sources */,
2C4446FC265D5C5800DF1DBC /* NCRoomParticipants.m in Sources */, 2C4446FC265D5C5800DF1DBC /* NCRoomParticipants.m in Sources */,
2CB6ACDC2641483800D3D641 /* NCMessageLocationParameter.m in Sources */, 2CB6ACDC2641483800D3D641 /* NCMessageLocationParameter.m in Sources */,
2C62AFDF24C1BD8D007E460A /* UIImageView+Letters.m in Sources */,
2C1ABD8925769E7D00AEDFB6 /* ShareItem.m in Sources */, 2C1ABD8925769E7D00AEDFB6 /* ShareItem.m in Sources */,
2C62B02E24C1BDD7007E460A /* PlaceholderView.m in Sources */, 2C62B02E24C1BDD7007E460A /* PlaceholderView.m in Sources */,
2C62B01024C1BDC5007E460A /* NCRoom.m in Sources */, 2C62B01024C1BDC5007E460A /* NCRoom.m in Sources */,
@ -2139,7 +2121,6 @@
1F1C999D2909846400EACF02 /* BGTaskHelper.swift in Sources */, 1F1C999D2909846400EACF02 /* BGTaskHelper.swift in Sources */,
2C4446F4265D51A600DF1DBC /* NCPushNotificationsUtils.m in Sources */, 2C4446F4265D51A600DF1DBC /* NCPushNotificationsUtils.m in Sources */,
1FA38C9129A4B3C6008871B8 /* NCNotificationAction.swift in Sources */, 1FA38C9129A4B3C6008871B8 /* NCNotificationAction.swift in Sources */,
2CC0019A24A37A7C00A20167 /* UIImageView+Letters.m in Sources */,
2C4446DE2658158000DF1DBC /* NCChatBlock.m in Sources */, 2C4446DE2658158000DF1DBC /* NCChatBlock.m in Sources */,
2C5BFBF3288AA37F00E75118 /* NCPoll.m in Sources */, 2C5BFBF3288AA37F00E75118 /* NCPoll.m in Sources */,
2C4446D9265814D100DF1DBC /* ServerCapabilities.m in Sources */, 2C4446D9265814D100DF1DBC /* ServerCapabilities.m in Sources */,

Просмотреть файл

@ -49,6 +49,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (UIImage *)blurImageFromImage:(UIImage *)image; + (UIImage *)blurImageFromImage:(UIImage *)image;
+ (UIImage *)roundedImageFromImage:(UIImage *)image; + (UIImage *)roundedImageFromImage:(UIImage *)image;
+ (UIImage *)getImageWithString:(NSString *)string withBackgroundColor:(UIColor *)color withBounds:(CGRect)bounds isCircular:(BOOL)isCircular;
+ (UIColor *)searchbarBGColorForColor:(UIColor *)color; + (UIColor *)searchbarBGColorForColor:(UIColor *)color;

Просмотреть файл

@ -272,6 +272,73 @@ static NSString *const nextcloudScheme = @"nextcloud:";
return resultImage; return resultImage;
} }
+ (UIImage *)getImageWithString:(NSString *)string withBackgroundColor:(UIColor *)color withBounds:(CGRect)bounds isCircular:(BOOL)isCircular
{
// Based on the "UIImageView+Letters" library from Tom Bachant
CGFloat fontSize = CGRectGetWidth(bounds) * 0.5;
NSDictionary *textAttributes = @{
NSFontAttributeName: [UIFont boldSystemFontOfSize:fontSize],
NSForegroundColorAttributeName: [UIColor whiteColor]
};
NSMutableString *displayString = [NSMutableString stringWithString:@""];
NSMutableArray *words = [[string componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] mutableCopy];
//
// Get first letter of the first word
//
if ([words count]) {
NSString *firstWord = [words firstObject];
if ([firstWord length]) {
// Get character range to handle emoji (emojis consist of 2 characters in sequence)
NSRange firstLetterRange = [firstWord rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, 1)];
[displayString appendString:[firstWord substringWithRange:firstLetterRange]];
}
}
CGFloat scale = [UIScreen mainScreen].scale;
CGSize size = CGSizeMake(floorf(bounds.size.width * scale) / scale, floorf(bounds.size.height * scale) / scale);
UIGraphicsBeginImageContextWithOptions(size, NO, scale);
CGContextRef context = UIGraphicsGetCurrentContext();
if (isCircular) {
//
// Clip context to a circle
//
CGPathRef path = CGPathCreateWithEllipseInRect(bounds, NULL);
CGContextAddPath(context, path);
CGContextClip(context);
CGPathRelease(path);
}
//
// Fill background of context
//
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height));
//
// Draw text in the context
//
NSString *text = [displayString uppercaseString];
CGSize textSize = [text sizeWithAttributes:textAttributes];
[text drawInRect:CGRectMake(bounds.size.width/2 - textSize.width/2,
bounds.size.height/2 - textSize.height/2,
textSize.width,
textSize.height)
withAttributes:textAttributes];
UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshot;
}
+ (UIColor *)searchbarBGColorForColor:(UIColor *)color + (UIColor *)searchbarBGColorForColor:(UIColor *)color
{ {
CGFloat luma = [self calculateLumaFromColor:color]; CGFloat luma = [self calculateLumaFromColor:color];

Просмотреть файл

@ -1,77 +0,0 @@
//
// UIImageView+Letters.h
//
// Created by Tom Bachant on 6/17/14.
// Copyright (c) 2014 Tom Bachant. All rights reserved.
//
// Some code attributed to Nick Lockwood on 25/08/2013.
// Copyright (c) 2013 Charcoal Design
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIKit.h>
@interface UIImageView (Letters)
/**
Sets the image property of the view based on initial text. A random background color is automatically generated.
@param string The string used to generate the initials. This should be a user's full name if available
*/
- (void)setImageWithString:(NSString *)string;
/**
Sets the image property of the view based on initial text and a specified background color.
@param string The string used to generate the initials. This should be a user's full name if available
@param color (optional) This optional paramter sets the background of the image. If not provided, a random color will be generated
*/
- (void)setImageWithString:(NSString *)string color:(UIColor *)color;
/**
Sets the image property of the view based on initial text, a specified background color, and a circular clipping
@param string The string used to generate the initials. This should be a user's full name if available
@param color (optional) This optional paramter sets the background of the image. If not provided, a random color will be generated
@param isCircular This boolean will determine if the image view will be clipped to a circular shape
*/
- (void)setImageWithString:(NSString *)string color:(UIColor *)color circular:(BOOL)isCircular;
/**
Sets the image property of the view based on initial text, a specified background color, a custom font, and a circular clipping
@param string The string used to generate the initials. This should be a user's full name if available
@param color (optional) This optional paramter sets the background of the image. If not provided, a random color will be generated
@param isCircular This boolean will determine if the image view will be clipped to a circular shape
@param fontName This will use a custom font attribute. If not provided, it will default to system font
*/
- (void)setImageWithString:(NSString *)string color:(UIColor *)color circular:(BOOL)isCircular fontName:(NSString *)fontName;
/**
Sets the image property of the view based on initial text, a specified background color, custom text attributes, and a circular clipping
@param string The string used to generate the initials. This should be a user's full name if available
@param color (optional) This optional paramter sets the background of the image. If not provided, a random color will be generated
@param isCircular This boolean will determine if the image view will be clipped to a circular shape
@param textAttributes This dictionary allows you to specify font, text color, shadow properties, etc., for the letters text, using the keys found in NSAttributedString.h
*/
- (void)setImageWithString:(NSString *)string color:(UIColor *)color circular:(BOOL)isCircular textAttributes:(NSDictionary *)textAttributes;
@end

Просмотреть файл

@ -1,254 +0,0 @@
//
// UIImageView+Letters.m
//
// Created by Tom Bachant on 6/17/14.
// Copyright (c) 2014 Tom Bachant. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "UIImageView+Letters.h"
#import <CommonCrypto/CommonDigest.h>
// This multiplier sets the font size based on the view bounds
static const CGFloat kFontResizingProportion = 0.5f;
@interface UIImageView (LettersPrivate)
- (UIImage *)imageSnapshotFromText:(NSString *)text backgroundColor:(UIColor *)color circular:(BOOL)isCircular textAttributes:(NSDictionary *)attributes;
@end
@implementation UIImageView (Letters)
- (void)setImageWithString:(NSString *)string {
[self setImageWithString:string color:nil circular:NO textAttributes:nil];
}
- (void)setImageWithString:(NSString *)string color:(UIColor *)color {
[self setImageWithString:string color:color circular:NO textAttributes:nil];
}
- (void)setImageWithString:(NSString *)string color:(UIColor *)color circular:(BOOL)isCircular {
[self setImageWithString:string color:color circular:isCircular textAttributes:nil];
}
- (void)setImageWithString:(NSString *)string color:(UIColor *)color circular:(BOOL)isCircular fontName:(NSString *)fontName {
[self setImageWithString:string color:color circular:isCircular textAttributes:@{
NSFontAttributeName:[self fontForFontName:fontName],
NSForegroundColorAttributeName: [UIColor whiteColor]
}];
}
- (void)setImageWithString:(NSString *)string color:(UIColor *)color circular:(BOOL)isCircular textAttributes:(NSDictionary *)textAttributes {
if (!textAttributes) {
textAttributes = @{
NSFontAttributeName: [self fontForFontName:nil],
NSForegroundColorAttributeName: [UIColor whiteColor]
};
}
NSMutableString *displayString = [NSMutableString stringWithString:@""];
NSMutableArray *words = [[string componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] mutableCopy];
//
// Get first letter of the first word
//
if ([words count]) {
NSString *firstWord = [words firstObject];
if ([firstWord length]) {
// Get character range to handle emoji (emojis consist of 2 characters in sequence)
NSRange firstLetterRange = [firstWord rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, 1)];
[displayString appendString:[firstWord substringWithRange:firstLetterRange]];
}
}
UIColor *backgroundColor = color ? color : [self colorFromString:string];
self.image = [self imageSnapshotFromText:[displayString uppercaseString] backgroundColor:backgroundColor circular:isCircular textAttributes:textAttributes];
}
#pragma mark - Helpers
- (UIFont *)fontForFontName:(NSString *)fontName {
CGFloat fontSize = CGRectGetWidth(self.bounds) * kFontResizingProportion;
if (fontName) {
return [UIFont fontWithName:fontName size:fontSize];
}
else {
return [UIFont boldSystemFontOfSize:fontSize];
}
}
- (UIColor *)randomColor {
srand48(arc4random());
float red = 0.0;
while (red < 0.1 || red > 0.84) {
red = drand48();
}
float green = 0.0;
while (green < 0.1 || green > 0.84) {
green = drand48();
}
float blue = 0.0;
while (blue < 0.1 || blue > 0.84) {
blue = drand48();
}
return [UIColor colorWithRed:red green:green blue:blue alpha:1.0f];
}
- (UIColor *)colorFromString:(NSString *)string {
const char *cStr = [string UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, (int)strlen(cStr), result );
NSInteger seedMd5Int = [[NSString stringWithFormat:
@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
] hash];
int maxRange = INT_MAX;
float h = (float) (seedMd5Int / maxRange * 360);
float s = 90.0f;
float l = 65.0f;
float alpha = 1.0f;
if (s < 0.0f || s > 100.0f) {
NSLog(@"Color parameter outside of expected range - Saturation");
}
if (l < 0.0f || l > 100.0f) {
NSLog(@"Color parameter outside of expected range - Luminance");
}
if (alpha < 0.0f || alpha > 1.0f) {
NSLog(@"Color parameter outside of expected range - Alpha");
}
// Formula needs all values between 0 - 1.
h = fmodf(h, 360.0f);//h % 360;
h = h / 360.0f;
s = s / 100.0f;
l = l / 100.0f;
float q;
if (l < 0.5) {
q = l * (1 + s);
} else {
q = (l + s) - (s * l);
}
float p = 2 * l - q;
int r = round(MAX(0, [self HueToRGBp:p q:q h:h + (1.0f / 3.0f)] * 256));
int g = round(MAX(0, [self HueToRGBp:p q:q h:h] * 256));
int b = round(MAX(0, [self HueToRGBp:p q:q h:h - (1.0f / 3.0f)] * 256));
return [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1];
}
- (float)HueToRGBp:(float)p q:(float)q h:(float)h {
if (h < 0) {
h += 1;
}
if (h > 1) {
h -= 1;
}
if (6 * h < 1) {
return p + ((q - p) * 6 * h);
}
if (2 * h < 1) {
return q;
}
if (3 * h < 2) {
return p + ((q - p) * 6 * ((2.0f / 3.0f) - h));
}
return p;
}
- (UIImage *)imageSnapshotFromText:(NSString *)text backgroundColor:(UIColor *)color circular:(BOOL)isCircular textAttributes:(NSDictionary *)textAttributes {
CGFloat scale = [UIScreen mainScreen].scale;
CGSize size = self.bounds.size;
if (self.contentMode == UIViewContentModeScaleToFill ||
self.contentMode == UIViewContentModeScaleAspectFill ||
self.contentMode == UIViewContentModeScaleAspectFit ||
self.contentMode == UIViewContentModeRedraw)
{
size.width = floorf(size.width * scale) / scale;
size.height = floorf(size.height * scale) / scale;
}
UIGraphicsBeginImageContextWithOptions(size, NO, scale);
CGContextRef context = UIGraphicsGetCurrentContext();
if (isCircular) {
//
// Clip context to a circle
//
CGPathRef path = CGPathCreateWithEllipseInRect(self.bounds, NULL);
CGContextAddPath(context, path);
CGContextClip(context);
CGPathRelease(path);
}
//
// Fill background of context
//
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height));
//
// Draw text in the context
//
CGSize textSize = [text sizeWithAttributes:textAttributes];
CGRect bounds = self.bounds;
[text drawInRect:CGRectMake(bounds.size.width/2 - textSize.width/2,
bounds.size.height/2 - textSize.height/2,
textSize.width,
textSize.height)
withAttributes:textAttributes];
UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshot;
}
@end