Make images with name initials like Gmail in Swift programmatically for iOS

后端 未结 8 2205
孤城傲影
孤城傲影 2021-02-05 18:03

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 l

相关标签:
8条回答
  • 2021-02-05 18:27

    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

    0 讨论(0)
  • 2021-02-05 18:30

    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)
        }
    }
    
    0 讨论(0)
  • 2021-02-05 18:32

    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

    0 讨论(0)
  • 2021-02-05 18:33

    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!

    0 讨论(0)
  • 2021-02-05 18:34

    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

    0 讨论(0)
  • 2021-02-05 18:38

    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)
    }
    
    0 讨论(0)
提交回复
热议问题