Изменение изображения UIBarButton из галереи

#swift #uiimageview #uibarbuttonitem

#быстрое #uiimageview #uibarbuttonitem

Вопрос:

У меня есть UIBarButton, и пользователь может изменить изображение, просто выбрав фотографию или изображение из галереи с помощью средства выбора изображений. Моя проблема в плохом масштабе изображения.

Если я использую aspectFit, мой UIBarButton будет выглядеть следующим образом:

введите описание изображения здесь

Если я использую AspectFill, мой UIBarButton будет выглядеть следующим образом:

введите описание изображения здесь

и если я попытаюсь сначала изменить размер изображения, а после установить его, изображение все время будет поцарапано:

введите описание изображения здесь

Это мой код:

     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(_:))))
    }
  

И вот функция для изменения размера изображения:

 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
}
  

Помогите мне, пожалуйста, найти правильный способ решения моей проблемы.

введите описание изображения здесь

Ответ №1:

Насколько я понимаю ваш вопрос. Я нашел решение.

Попробуйте это

 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(_:))))
}
  

Способ изменения размера

 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
    }

}
  

Вывод

введите описание изображения здесь

Ответ №2:

Попробуйте создать пользовательскую кнопку с помощью приведенного ниже кода:

 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)
    ...
}
  

Вам больше не нужна resizedImage(..) функция

Комментарии:

1. я пытаюсь, но у меня не получается. Кнопка больше, а изображение поцарапано. Добавьте еще один скриншот.

2. Можете ли вы повторить попытку с моим измененным ответом? Я добавил imageBtn в containerBtn

Ответ №3:

Вот рабочий код (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
}
  

Действие кнопки здесь

 @objc func btnTapped(_ sender: Any) {
    print("Click Event")
}
  

Расширение для округления

 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;
            }

        }
    }
}
  

Вывод:

введите описание изображения здесь