Created
July 6, 2020 21:23
-
-
Save BrunoScheltzke/1043061249db079aa3ed77dbb760582f to your computer and use it in GitHub Desktop.
Round image view with option to enable a picker view to select image from camera or gallery
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// RoundImageView.swift | |
// | |
// Created by Bruno Scheltzke on 04/06/20. | |
// Copyright © 2020 Bruno Scheltzke. All rights reserved. | |
// | |
import UIKit | |
protocol RoundImagePickerDelegate { | |
func didSelect(image: UIImage) | |
} | |
@IBDesignable | |
class RoundImageView: UIImageView { | |
var delegate: RoundImagePickerDelegate? | |
@IBInspectable | |
var shouldEdit: Bool = false { | |
didSet { | |
editButton.isHidden = !shouldEdit | |
} | |
} | |
let editButton = UIButton() | |
var imagePicker: ImagePicker! | |
override func awakeFromNib() { | |
super.awakeFromNib() | |
setupImagePicker() | |
layer.borderColor = UIColor.systemBlue.cgColor | |
layer.borderWidth = 1 | |
} | |
private func setupImagePicker() { | |
isUserInteractionEnabled = true | |
editButton.setTitle("Editar", for: .normal) | |
editButton.setTitleColor(.systemBlue, for: .normal) | |
editButton.translatesAutoresizingMaskIntoConstraints = false | |
addSubview(editButton) | |
editButton.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true | |
editButton.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true | |
editButton.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.3).isActive = true | |
editButton.addTarget(self, action: #selector(getImage), for: .touchUpInside) | |
let tap = UITapGestureRecognizer(target: self, action: #selector(getImage)) | |
addGestureRecognizer(tap) | |
let window = UIApplication.shared.windows.first | |
imagePicker = ImagePicker(presentationController: window?.rootViewController, delegate: self) | |
} | |
override func layoutSubviews() { | |
super.layoutSubviews() | |
clipsToBounds = true | |
layer.cornerRadius = frame.size.width/2 | |
} | |
@objc func getImage() { | |
guard shouldEdit else { return } | |
imagePicker.present(from: self) | |
} | |
} | |
extension RoundImageView: ImagePickerDelegate { | |
func didSelect(image: UIImage?) { | |
guard let image = image else { return } | |
self.image = image | |
delegate?.didSelect(image: image) | |
} | |
} | |
public protocol ImagePickerDelegate: class { | |
func didSelect(image: UIImage?) | |
} | |
open class ImagePicker: NSObject { | |
private let pickerController: UIImagePickerController | |
private weak var presentationController: UIViewController? | |
private weak var delegate: ImagePickerDelegate? | |
public init(presentationController: UIViewController?, delegate: ImagePickerDelegate) { | |
self.pickerController = UIImagePickerController() | |
super.init() | |
self.presentationController = presentationController | |
self.delegate = delegate | |
self.pickerController.delegate = self | |
self.pickerController.allowsEditing = true | |
self.pickerController.mediaTypes = ["public.image"] | |
} | |
private func action(for type: UIImagePickerController.SourceType, title: String) -> UIAlertAction? { | |
guard UIImagePickerController.isSourceTypeAvailable(type) else { | |
return nil | |
} | |
return UIAlertAction(title: title, style: .default) { [unowned self] _ in | |
self.pickerController.sourceType = type | |
self.presentationController?.present(self.pickerController, animated: true) | |
} | |
} | |
public func present(from sourceView: UIView) { | |
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) | |
if let action = self.action(for: .camera, title: "Take photo") { | |
alertController.addAction(action) | |
} | |
if let action = self.action(for: .savedPhotosAlbum, title: "Camera roll") { | |
alertController.addAction(action) | |
} | |
if let action = self.action(for: .photoLibrary, title: "Photo library") { | |
alertController.addAction(action) | |
} | |
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) | |
if UIDevice.current.userInterfaceIdiom == .pad { | |
alertController.popoverPresentationController?.sourceView = sourceView | |
alertController.popoverPresentationController?.sourceRect = sourceView.bounds | |
alertController.popoverPresentationController?.permittedArrowDirections = [.down, .up] | |
} | |
self.presentationController?.present(alertController, animated: true) | |
} | |
private func pickerController(_ controller: UIImagePickerController, didSelect image: UIImage?) { | |
controller.dismiss(animated: true, completion: nil) | |
self.delegate?.didSelect(image: image) | |
} | |
} | |
extension ImagePicker: UIImagePickerControllerDelegate { | |
public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { | |
self.pickerController(picker, didSelect: nil) | |
} | |
public func imagePickerController(_ picker: UIImagePickerController, | |
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) { | |
guard let image = info[.editedImage] as? UIImage else { | |
return self.pickerController(picker, didSelect: nil) | |
} | |
self.pickerController(picker, didSelect: image) | |
} | |
} | |
extension ImagePicker: UINavigationControllerDelegate { | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment