15

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?

enter image description here enter image description here

Cœur
  • 37,241
  • 25
  • 195
  • 267
Lakhshya Bansal
  • 293
  • 1
  • 2
  • 13

10 Answers10

20

enter image description here

"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()
}
Er.Gopal Vasani
  • 448
  • 3
  • 12
13

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: enter image description here

[EDIT]

You may also want to check this out: https://github.com/bofiaza/IPImage

yoninja
  • 1,952
  • 2
  • 31
  • 39
8

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

Lakhshya Bansal
  • 293
  • 1
  • 2
  • 13
4

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
    }

Reference

Manav
  • 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
2

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)
}
Community
  • 1
  • 1
FredLoh
  • 1,804
  • 18
  • 27
2

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)
    }
}
Matthew Mitchell
  • 514
  • 4
  • 14
1

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!

1

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
     }
stoikokolev
  • 484
  • 5
  • 9
0

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

ayushn21
  • 305
  • 2
  • 7
0

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

  • 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