I am trying to get a navigation bar similar to the one in iOS messages app. This is what I have, and it creates a bit of a circle shape but gets cut off. If you were to recreate the centered image from Messages how would you?
let imageView = UIImageView(image: UIImage(named: "test-image"))
imageView.contentMode = .scaleAspectFit
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
imageView.frame = titleView.bounds
imageView.layer.masksToBounds = true
imageView.layer.cornerRadius = imageView.frame.height / 2
titleView.addSubview(imageView)
self.navigationItem.titleView = titleView
The current outcome with this snippet:
The desired outcome:
Please excuse my eggs ;) It's my favorite test pic
CodePudding user response:
Set image view content mode .scaleAspectFill
imageView.contentMode = .scaleAspectFill
CodePudding user response:
The following is what I have done.
Using a subclass of UIView
to make a circular image. Note that I'm assuming the original image is horizontally-long, which meanns that the diameter of the cutout will be the height of the image.
import UIKit
class DrawView: UIView {
var image: UIImage
init(frame: CGRect, image: UIImage){
self.image = image
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
image.draw(at: CGPoint.zero)
}
func makeClipImage() -> UIImage? {
var tempImage = UIImage()
let selfFrame = self.bounds
let center = CGPoint(x: selfFrame.size.width * 0.5, y: selfFrame.size.height * 0.5)
let circlePath = UIBezierPath(arcCenter: center, radius: selfFrame.height / 2.0, startAngle: 0.0, endAngle: .pi * 2.0, clockwise: true)
circlePath.close()
let screenScale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(selfFrame.size, false, screenScale)
circlePath.addClip()
image.draw(in: CGRect(origin: CGPoint.zero, size: image.size))
tempImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return tempImage
}
}
I have Jeniffer Garner as a guest as shown below. The image size 480 px X 180 px.
Next, I use the cutout from the subclass above with the view controller (UIViewController
) to form the navigation bar as follows.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let image = UIImage(named: "jenniferGarner.jpg") {
let rect = CGRect(origin: CGPoint(x: 0, y: 100), size: image.size)
let drawView = DrawView(frame: rect, image: image)
if let circleImage = drawView.makeClipImage() {
// The image size is still the same as the original except that the area outside the cutout circle is transparent //
let imageView = UIImageView(image: circleImage)
imageView.contentMode = .scaleAspectFill
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
titleView.backgroundColor = UIColor.green
imageView.frame = titleView.bounds
imageView.layer.masksToBounds = true
imageView.layer.cornerRadius = imageView.frame.height / 2
titleView.addSubview(imageView)
self.navigationItem.titleView = titleView
}
}
}
}
Note that I've intentionally set the background color of 'titleView' to UIColor.green
. The following is the result.