在我的应用程序中,用户可以打开相机胶卷选择图片或打开相机直接单独拍摄 .
在这两种情况下,所选/拍摄的照片也将保存在本地以供进一步参考 .
缺点是保存操作通常会冻结屏幕直到完成 .
我找到了一个动画in this post,我想在 imagePickerController
前面显示它,但我无法做到 .
class SinglePageViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextFieldDelegate, UINavigationBarDelegate {
var spinner : UIActivityIndicatorView?
lazy var showCameraImagePickerController: UIImagePickerController = {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .camera;
imagePicker.allowsEditing = false
return imagePicker
}()
lazy var showPhotoImagePickerController: UIImagePickerController = {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary;
imagePicker.allowsEditing = false
return imagePicker
}()
@IBOutlet weak var photoButton: UIButton!
@IBAction func onPhotoButton(_ sender: Any) {
self.present(self.showCameraImagePickerController, animated: true, completion: nil)
}
@IBOutlet weak var galleryButton: UIButton!
@IBAction func onGalleryButton(_ sender: Any) {
self.present(self.showPhotoImagePickerController, animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
//start animation
let screenSize: CGRect = UIScreen.main.bounds
spinner = UIActivityIndicatorView(frame: CGRect(x: screenSize.width/2 - 150, y: screenSize.height/2 - 150, width: 300, height: 300))
spinner?.isHidden = false
spinner?.startAnimating()
spinner?.color = UIColor.red
switch picker {
case showCameraImagePickerController:
// snap pic, save to doc, save to album
self.showCameraImagePickerController.view.addSubview(spinner!)
timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: false, block: {_ in
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
if self.saveImage(imageName: "\(self.titleLabel.text!).png", image: image){
// additionally save to photo album
UIImageWriteToSavedPhotosAlbum(image!, self, #selector(self.image(_:didFinishSavingWithError:contextInfo:)), nil)
print("saved \(self.titleLabel.text!).png")
self.imageView.image = image
}
})
case showPhotoImagePickerController:
//switch pic, save to doc. no album
self.showPhotoImagePickerController.view.addSubview(spinner!)
timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: false, block: {_ in
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
if self.saveImage(imageName: "\(self.titleLabel.text!).png", image: image){
print("saved new \(self.titleLabel.text!).png")
self.imageView.image = image
self.spinner?.stopAnimating()
self.spinner?.removeFromSuperview()
self.spinner = nil
self.showPhotoImagePickerController.dismiss(animated: true, completion: nil)
} else {
self.spinner?.stopAnimating()
self.spinner?.removeFromSuperview()
self.spinner = nil
self.showPhotoImagePickerController.dismiss(animated: true, completion: nil)
}
})
default:
return
}
}
@objc func image(_ image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeRawPointer) {
spinner?.stopAnimating()
spinner?.removeFromSuperview()
spinner = nil
self.showCameraImagePickerController.dismiss(animated: true, completion: nil)
}
func saveImage(imageName: String, image: UIImage?) -> Bool {
//create an instance of the FileManager
let fileManager = FileManager.default
//get the image path
let imagePath = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent(imgDir+imageName)
print(imagePath)
//get the image we took with camera
let image = rotateImage(image: image!)
//get the PNG data for this image
let data = UIImagePNGRepresentation(image)
//store it in the document directory
if fileManager.createFile(atPath: imagePath as String, contents: data, attributes: nil){
newItem?.image = true
return true
} else {
print("error while saving")
return false
}
}
你可以看到我尝试使用 bringSubView(toFront:)
和 zPosition
但没有结果 .
以下this similar question我查看了cameraOverlayView的文档,但它说只有当imagePicker以相机模式呈现时它才有效,这不包括我打开照片库时的情况
我最近也尝试使用一种解决方法,这意味着我尽快解除了imagePickerController并在之后更新了图像,但由于app结构的一些变化,这不再是最优的 .
编辑
为了让自己更清楚,我将再次说明我需要的东西:显示imagePicker的微调器动画 in front ,只要我点击一张照片来选择它,直到我完成保存,然后关闭imagePicker . 我想首先解除选择器然后在主视图中显示微调器时保存 .
EDIT2使用答案中的新代码更新了代码 . 唯一的问题是,如果我没有放一个计时器,微调器只会在保存过程结束时显示自己一小段时间(用断点检查) . 这导致在保存过程的几秒钟内没有动画,并且在解除imagePicker之前只是在最后显示微调器 . 只需加一个0.1秒的延迟就会立即触发微调器并获得预期的行为(保存时动画) . 不知道为什么
1 回答
请参阅一个完整的示例,其中微调器将在保存图像时显示,一旦完成保存,微调器将被删除 .