问题
I have UIBarButton and user can change image just chose photo or gallery image with image picker. My problem is bad scale image.
If I use AspectFit my UIBarButton look like this:
If I use AspectFill my UIBarButton look like this:
and if I try first change size image and after set it, image all time scratched:
This is my code:
func createPhotoBarButton(image: Data) {
let barbtn = UIBarButtonItem()
var image = UIImage(data:image)
if image == nil {
image = UIImage(named: "photoIcon")
}
let imageView = UIImageView(frame: CGRect(x: 0.0, y: 0.0, width: 35.0, height: 35.0))
imageView.image = image?.resizedImage(newSize: CGSize(width: 35, height: 35))?.withRenderingMode(.alwaysOriginal)
// imageView.image = cropToBounds(image: image!, width: 35, height: 35)
// imageView.image = image
imageView.contentMode = .scaleAspectFill
imageView.layer.cornerRadius = imageView.frame.size.height / 2
imageView.layer.masksToBounds = true
imageView.clipsToBounds = true
self.navigationItem.rightBarButtonItem = barbtn
barbtn.customView = imageView
barbtn.customView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(photoTapped(_:))))
}
And here func for resize image:
func resizedImage(newSize: CGSize) -> UIImage? {
guard size != newSize else { return self }
let hasAlpha = false
let scale: CGFloat = 0.0
UIGraphicsBeginImageContextWithOptions(newSize, !hasAlpha, scale)
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
let newImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
Help me plz find the right way to resolving my problem.
回答1:
As I understand your question. I found a solution.
Try this
func createPhotoBarButton(image: Data) {
let barbtn = UIBarButtonItem()
let imageView = UIImageView(frame: CGRect(x: 0.0, y: 0.0, width: 35.0, height: 35.0))
var image = UIImage(data:image)
if image == nil {
image = UIImage(named: "photoIcon")?.resize(maxWidthHeight: Double(imageView.frame.size.width))
}
imageView.image = image
imageView.contentMode = .scaleAspectFill
imageView.layer.cornerRadius = imageView.frame.size.height / 2
imageView.layer.masksToBounds = true
imageView.clipsToBounds = true
self.navigationItem.rightBarButtonItem = barbtn
barbtn.customView = imageView
barbtn.customView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(photoTapped(_:))))
}
Resize method
extension UIImage {
func resize(maxWidthHeight : Double)-> UIImage? {
let actualHeight = Double(size.height)
let actualWidth = Double(size.width)
var maxWidth = 0.0
var maxHeight = 0.0
if actualWidth > actualHeight {
maxWidth = maxWidthHeight
let per = (100.0 * maxWidthHeight / actualWidth)
maxHeight = (actualHeight * per) / 100.0
}else{
maxHeight = maxWidthHeight
let per = (100.0 * maxWidthHeight / actualHeight)
maxWidth = (actualWidth * per) / 100.0
}
let hasAlpha = true
let scale: CGFloat = 0.0
UIGraphicsBeginImageContextWithOptions(CGSize(width: maxWidth, height: maxHeight), !hasAlpha, scale)
self.draw(in: CGRect(origin: .zero, size: CGSize(width: maxWidth, height: maxHeight)))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
return scaledImage
}
}
Output
回答2:
Try to create a custom button with the code below:
func createPhotoBarButton(image: Data) {
let imageBtnContainer = UIButton()
let imageBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
var image = UIImage(data:image)
if image == nil {
image = UIImage(named: "photoIcon")
}
imageBtn.setImage(image, forState: UIControlState.Normal)
imageBtn.frame = CGRectMake(0, 0, 53, 31)
imageBtn.imageView?.contentMode = .scaleAspectFit
imageBtnContainer.addSubview(imageBtn)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: imageBtnContainer)
...
}
You don't need anymore resizedImage(..)
function
回答3:
Here is working code (swift 4)
override func viewDidLoad() {
let containView = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
let Button : UIButton = UIButton.init(type: .custom)
Button.frame = CGRect(x: 0, y: 0, width: 35, height: 35)
Button.Round = true
Button.setImage(UIImage(named: "photoIcon"), for: .normal)
Button.addTarget(self, action: #selector(btnTapped), for: .touchUpInside)
containView.addSubview(Button)
let rightBarButton = UIBarButtonItem(customView: containView)
self.navigationItem.rightBarButtonItem = rightBarButton
}
Button Action Here
@objc func btnTapped(_ sender: Any) {
print("Click Event")
}
Extension to Round
extension UIView{
@IBInspectable var Round:Bool{
get{
return false
}
set{
if newValue == true {
self.layer.cornerRadius = self.frame.size.height/2;
self.layer.masksToBounds = true;
}
}
}
}
Output:
来源:https://stackoverflow.com/questions/55119953/change-uibarbutton-image-from-gallery