I’m using normal tap gesture on ‘UIImageView’ when presenting an UIImagePickerController. But I don’t know why the images picked from Photo Library are always coming out to be bad quality(blurred, cropped etc.). When picking from Camera the images come out to be perfectly fine.
Here is complete code for this custom view class.
class ImageEditingView: UIView {
let imageView = UIImageView()
weak var delegate: ViewController!
var croppingRect: CGRect?
var croppedRect: CGRect?
var ratioWidth: CGFloat? {
didSet {
self.setNeedsDisplay()
}
}
var ratioHeight: CGFloat? {
didSet {
self.setNeedsDisplay()
}
}
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
super.draw(rect)
// Drawing code
let padding: CGFloat = 20
self.imageView.frame = CGRect(center: rect.midPoint, size: rect.size - padding)
self.imageView.contentMode = .scaleAspectFill
self.imageView.clipsToBounds = true
self.imageView.isUserInteractionEnabled = true
self.imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(openImagePickerConroller)))
self.addSubview(imageView)
if let imageWidth = ratioWidth, let imageHeight = ratioHeight {
if imageWidth > imageHeight {
let newImageHeight = imageHeight/imageWidth * (rect.size.width - (2 * padding))
let yForCroppedRect = (self.bounds.size.height - newImageHeight)/2
self.croppingRect = CGRect(x: padding, y: yForCroppedRect, width: rect.size.width - (2 * padding), height: newImageHeight)
} else if imageWidth < imageHeight {
let newImageWidth = imageWidth/imageHeight * (rect.size.height - (2 * padding))
let xForCroppedRect = (self.bounds.size.width - newImageWidth)/2
self.croppingRect = CGRect(x: xForCroppedRect, y: padding, width: newImageWidth, height: rect.size.height - (2 * padding))
} else {
self.croppingRect = nil
}
}
let bigRect = CGRect(x: 0, y: 0, width: self.bounds.width, height: self.bounds.height)
let smallRect = self.croppingRect ?? self.imageView.frame
self.croppedRect = smallRect
let pathBigRect = UIBezierPath(rect: bigRect)
let pathSmallRect = UIBezierPath(rect: smallRect)
pathBigRect.append(pathSmallRect)
pathBigRect.usesEvenOddFillRule = true
let fillLayer = CAShapeLayer()
fillLayer.path = pathBigRect.cgPath
fillLayer.fillRule = CAShapeLayerFillRule.evenOdd
fillLayer.fillColor = UIColor.darkGray.cgColor
//fillLayer.opacity = 0.4
self.layer.addSublayer(fillLayer)
}
@objc func openImagePickerConroller() {
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .photoLibrary//.camera
imagePicker.delegate = self
self.delegate.present(imagePicker, animated: true, completion: nil)
}
}
extension ImageEditingView: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let pickedImage = info[.originalImage] as? UIImage {
self.imageView.image = pickedImage
self.ratioWidth = 10
self.ratioHeight = 10
self.delegate.dismiss(animated: true, completion: nil)
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.delegate.dismiss(animated: true, completion: nil)
}
}
extension CGRect {
init(center: CGPoint, size: CGSize) {
let origin = CGPoint(x: center.x - (size.width/2), y: center.y - (size.height/2))
self.init(origin: origin, size: size)
}
var midPoint: CGPoint {
return CGPoint(x: self.midX, y: self.midY)
}
}
extension CGSize {
static func -(size: CGSize, diff: CGFloat) -> CGSize {
let dim = size.width <= size.height ? size.width : size.height
return CGSize(width: dim - diff, height: dim - diff)
}
}
Are you testing on iOS 13.0 beta by any chance? Try it again with the latest iOS 13 beta, which should fix this bug.