Hilaj S L
Hilaj S L

Reputation: 2046

How to set rounded profile picture image(from url string) to UIBarButton item in iOS Swift

Hi I'm working on an iOS Swift project in which I want to show users profile picture in the navigation bar as rounded. I tried lot of sample code, but it is not making rounded curve. Please help me.

I have tried these codes,

var image = UIImage()
if let userImage = UserProfile.image {
   let imageUrl = self.dmcCommon.convertStringToImageURL(url: userImage)
   let data = (try? Data(contentsOf: imageUrl as URL))!
   image = UIImage(data: data)!
} else {
   image = UIImage(named: "Me")!
}

let v = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
v.image = image
v.layer.masksToBounds = true
v.layer.cornerRadius = 20

let rightBtn = UIBarButtonItem(customView: v)
self.navigationItem.rightBarButtonItem = rightBtn

And the result is like this, enter image description here Here the image is not getting round also it taking full width not as I gave.

Later I tried another solution, which is,

let button = UIButton()
button.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
var image = UIImage()
if let userImage = UserProfile.image {
   let imageUrl = self.dmcCommon.convertStringToImageURL(url: userImage)
   let data = (try? Data(contentsOf: imageUrl as URL))!
   image = UIImage(data: data)!
} else {
   image = UIImage(named: "Me")!
}
UIGraphicsBeginImageContextWithOptions(button.frame.size, false, image.scale)
let rect  = CGRect(x:0, y:0, width:button.frame.size.width, height:button.frame.size.height)
UIBezierPath(roundedRect: rect, cornerRadius: rect.width/2).addClip()
image.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()

button.addTarget(self, action:#selector(self.navToMe), for: UIControl.Event.touchUpInside)
let color = UIColor(patternImage: newImage)
button.backgroundColor = color
button.layer.cornerRadius = 0.5 * button.bounds.size.width
let barButton = UIBarButtonItem()
barButton.customView = button
self.navigationItem.rightBarButtonItems = [notificationButton, barButton]

And the result is, enter image description here

In second solution it working but the image is redrawing like mirroring to down. Please help me how to place rounded profile picture in UIBarButtonItems.

Upvotes: 0

Views: 1242

Answers (3)

matt
matt

Reputation: 535140

You do not need a custom button or an image view. And do not use corner rounding. Just draw the target image into the desired size with clipping to a circle and use that as the bar button item’s image.

Upvotes: 1

kvs
kvs

Reputation: 186

Try this

    let frame = CGRect(x: 0, y: 0, width: 30, height: 30)
    let customView = UIView(frame: frame)
    let imageView = UIImageView(image: UIImage(named: "turtle"))
    imageView.frame = frame
    imageView.layer.cornerRadius = imageView.frame.height * 0.5
    imageView.layer.masksToBounds = true
    customView.addSubview(imageView)
    navigationItem.rightBarButtonItems = [
        UIBarButtonItem(systemItem: .action), UIBarButtonItem(customView: customView)
    ]

enter image description here

Instead of UIImage(name:) use your UIImage(data:) constructor

Upvotes: 1

Sayooj
Sayooj

Reputation: 375

I've used the following approch,

let button = UIButton(type: .system)
button.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
button.layer.cornerRadius = 15
button.clipsToBounds = true
button.imageView?.contentMode = .scaleAspectFit

let imageData = try? Data(contentsOf: URL(string : "https://www.w3schools.com/howto/img_avatar.png")!)

if let imageData = imageData , let image =  UIImage(data: imageData)?.resizeImage(to: button.frame.size) {
    button.setBackgroundImage(image, for: .normal)
}
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)

To resize the image

extension UIImage {
    func resizeImage(to size: CGSize) -> UIImage {
       return UIGraphicsImageRenderer(size: size).image { _ in
           draw(in: CGRect(origin: .zero, size: size))
    }
}}

enter image description here

In the above example, I've used Data(contentsOf: URL) to load image from the internet, but it is better to fetch the image asynchronously. Check this for more details.

Upvotes: 4

Related Questions