I need to display a profile pic of every user corresponding to his name in a UITableView. Until the image is downloaded I need to show an image with his name's first alphabet like in the GMail app. How to do this programmatically in Swift for iOS?
-
Something like this but for Swift http://stackoverflow.com/questions/23122088/colored-boxed-with-letters-a-la-gmail – Lakhshya Bansal Dec 05 '15 at 07:33
-
Do you want 1 initial ... then just create your own images, A - Z – DogCoffee Dec 05 '15 at 07:41
-
Yes I want just one initial. I thought of reducing the app size so no images. – Lakhshya Bansal Dec 05 '15 at 09:00
-
Did my solution work for you? – FredLoh Dec 05 '15 at 12:04
-
http://www.paintcodeapp.com – DogCoffee Dec 05 '15 at 20:14
-
This is great but sucks when used with other languages like Japanese where initials make no sense at all – GorillaApe Oct 03 '16 at 10:29
10 Answers
"NO NEED ANY FRAMEWORK"
"Its Work Wonderfully"
@IBOutlet weak var IBtxtFieldName:UITextField!
@IBOutlet weak var IBtxtFieldSurname:UITextField!
@IBOutlet weak var IBImgViewUserProfile:UIImageView!
@IBAction func IBbtnShowTapped(sender: UIButton)
{
let lblNameInitialize = UILabel()
lblNameInitialize.frame.size = CGSize(width: 100.0, height: 100.0)
lblNameInitialize.textColor = UIColor.whiteColor()
lblNameInitialize.text = String(IBtxtFieldName.text!.characters.first!) + String(IBtxtFieldSurname.text!.characters.first!)
lblNameInitialize.textAlignment = NSTextAlignment.Center
lblNameInitialize.backgroundColor = UIColor.blackColor()
lblNameInitialize.layer.cornerRadius = 50.0
UIGraphicsBeginImageContext(lblNameInitialize.frame.size)
lblNameInitialize.layer.renderInContext(UIGraphicsGetCurrentContext()!)
IBImgViewUserProfile.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
}
"SWIFT 3.0"
@IBAction func IBbtnShowTapped(sender: UIButton)
{
let lblNameInitialize = UILabel()
lblNameInitialize.frame.size = CGSize(width: 100.0, height: 100.0)
lblNameInitialize.textColor = UIColor.white
lblNameInitialize.text = String(IBtxtFieldName.text!.characters.first!) + String(IBtxtFieldSurname.text!.characters.first!)
lblNameInitialize.textAlignment = NSTextAlignment.center
lblNameInitialize.backgroundColor = UIColor.black
lblNameInitialize.layer.cornerRadius = 50.0
UIGraphicsBeginImageContext(lblNameInitialize.frame.size)
lblNameInitialize.layer.render(in: UIGraphicsGetCurrentContext()!)
IBImgViewUserProfile.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
}

- 448
- 3
- 12
-
-
Great. It works..!! But, why it is blurry effect ?? Can't we make clean text ?? – Manann Sseth Jul 13 '17 at 12:44
-
1To prevent the blur, set the scale: let scale = UIScreen.main.scale UIGraphicsBeginImageContextWithOptions(lblNameInitialize.bounds.size, false, scale) – Matan Guttman Aug 23 '17 at 12:15
-
the text is to small at the center, how do i increase the size? – Oluwatobi Omotayo Jan 13 '18 at 16:44
-
I did that by reducing the CGSize values, like half the size, updating the cornerRadius as well. Nice answer – Oluwatobi Omotayo Jan 13 '18 at 17:06
-
For me its not round.. Fixed it by adding `layer.masksToBounds = true` – John Smith Jul 21 '18 at 22:33
This is perfect for the UIImageView: https://github.com/bachonk/UIImageView-Letters. Basically, it creates a UIImage with, at the center, the initial letter of the first and last word of the input. The background color can be random or assigned.
Here's an example of what this category can do:
[EDIT]
You may also want to check this out: https://github.com/bofiaza/IPImage

- 1,952
- 2
- 31
- 39
Using FredLoh's suggestion :
I made a UILabel(nameInitialLabel) in the storyboard. Adjusted it's dimensions and font.
func setDefaultImage(name: String) {
nameInitialLabel.text = String(name[name.startIndex])
nameInitialLabel.backgroundColor = pickColor(name[name.startIndex])
nameInitialLabel.enabled = true
}
func pickColor(alphabet: Character) -> UIColor {
let alphabetColors = [0x5A8770, 0xB2B7BB, 0x6FA9AB, 0xF5AF29, 0x0088B9, 0xF18636, 0xD93A37, 0xA6B12E, 0x5C9BBC, 0xF5888D, 0x9A89B5, 0x407887, 0x9A89B5, 0x5A8770, 0xD33F33, 0xA2B01F, 0xF0B126, 0x0087BF, 0xF18636, 0x0087BF, 0xB2B7BB, 0x72ACAE, 0x9C8AB4, 0x5A8770, 0xEEB424, 0x407887]
let str = String(alphabet).unicodeScalars
let unicode = Int(str[str.startIndex].value)
if 65...90 ~= unicode {
let hex = alphabetColors[unicode - 65]
return UIColor(red: CGFloat(Double((hex >> 16) & 0xFF)) / 255.0, green: CGFloat(Double((hex >> 8) & 0xFF)) / 255.0, blue: CGFloat(Double((hex >> 0) & 0xFF)) / 255.0, alpha: 1.0)
}
return UIColor.blackColor()
}
I've extracted the alphabetColors mapping array from https://github.com/uttesh/ngletteravatar

- 293
- 1
- 2
- 13
Updated :
func imageWith(name: String?) -> UIImage? {
let frame = CGRect(x: 0, y: 0, width: 50, height: 50)
let nameLabel = UILabel(frame: frame)
nameLabel.textAlignment = .center
nameLabel.backgroundColor = .lightGray
nameLabel.textColor = .white
nameLabel.font = UIFont.boldSystemFont(ofSize: 20)
var initials = ""
if let initialsArray = name?.components(separatedBy: " ") {
if let firstWord = initialsArray.first {
if let firstLetter = firstWord.first {
initials += String(firstLetter).capitalized }
}
if initialsArray.count > 1, let lastWord = initialsArray.last {
if let lastLetter = lastWord.first { initials += String(lastLetter).capitalized
}
}
} else {
return nil
}
nameLabel.text = initials
UIGraphicsBeginImageContext(frame.size)
if let currentContext = UIGraphicsGetCurrentContext() {
nameLabel.layer.render(in: currentContext)
let nameImage = UIGraphicsGetImageFromCurrentImageContext()
return nameImage
}
return nil
}

- 2,284
- 1
- 14
- 27
-
Interestingly, identical code was posted here https://swift.programmingpedia.net/en/tutorial/10915/generate-uiimage-of-initials-from-string and https://www.programming-books.io/essential/swift/initialsimagefactory-bb3b2084b76942d19272b698076537c8. Please don't forget to add a proper attribution if you reference material written by others. – Martin R Nov 23 '19 at 21:33
Add the code from here. I suggest you also add SnapKit
Add this code to however you are generating cells:
let profileView = UIView()
cell.addSubview(profileView)
profileView.snp_makeConstraints { (make) -> Void in
make.left.equalTo(cell).offset(10)
make.centerY.equalTo(cell)
make.height.width.equalTo(30)
//Your color
profileView.backgroundColor = UIColor.greenColor()
let firstLetter = UILabel()
profileView.addSubview(firstLetter)
firstLetter.text = yourString[0]
//Add constraint for it, I suggest using SnapKit in which case
firstLetter.snp_makeConstraints { (make) -> Void in
make.center.equalTo(profileView)
}
Simple little extension, can be customised as needed.
public extension UIImageView {
func addInitials(first: String, second: String) {
let initials = UILabel(frame: CGRect(x: 0, y: 0, width: self.bounds.width, height: self.bounds.height))
initials.center = CGPoint(x: self.bounds.width / 2, y: self.bounds.height / 2)
initials.textAlignment = .center
initials.text = first + " " + second
initials.textColor = .black
self.addSubview(initials)
}
}

- 514
- 4
- 14
You can use https://github.com/bofiaza/IPImage, but you must to do some corrections in function generateImage()
.
Change this code in source file:
public func generateImage() -> UIImage? {
let view = setupView()
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0.0)
view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
print(image ?? "No image")
return image
}
on this:
public func generateImage() -> UIImage? {
let view = setupView()
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0.0)
defer { UIGraphicsEndImageContext() }
guard let currentContext = UIGraphicsGetCurrentContext() else {
return nil
}
view.layer.render(in: currentContext)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
print(image ?? "No image")
return image
}
It will be work correctly!

- 99
- 1
- 4
I updated Manav's answer
func imageWith(name: String?) -> UIImage? {
let frame = CGRect(x: 0, y: 0, width: 50, height: 50)
let nameLabel = UILabel(frame: frame)
nameLabel.textAlignment = .center
nameLabel.backgroundColor = .lightGray
nameLabel.textColor = .darkGray
nameLabel.font = UIFont.boldSystemFont(ofSize: 20)
guard let initialsArray = name?.components(separatedBy: " "),
initialsArray.count > 1,
let firstWord = initialsArray.first,
let firstLetter = firstWord.first,
let lastWord = initialsArray.last,
let lastLetter = lastWord.first else { return nil }
nameLabel.text = "\(firstLetter.uppercased())\(lastLetter.uppercased())"
UIGraphicsBeginImageContext(frame.size)
if let currentContext = UIGraphicsGetCurrentContext() {
nameLabel.layer.render(in: currentContext)
let nameImage = UIGraphicsGetImageFromCurrentImageContext()
return nameImage
}
return nil
}

- 484
- 5
- 9
I've written a Swift library for this : https://github.com/ayushn21/AvatarImageView
It's highly customisable and uses a protocol oriented approach to get it's data and configuration

- 305
- 2
- 7
Just create a view (UIView or UIImageview) and add a UILabel inside (centered vertically and horizontally)

- 1
- 1
- 3
-
As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 06 '22 at 19:49