我有UIViewController
来保存图片选择器:
let picker = UIImagePickerController()
我将图像选择器称为:
private func showCamera() {
picker.allowsEditing = true
picker.sourceType = .camera
picker.cameraCaptureMode = .photo
picker.modalPresentationStyle = .fullScreen
present(picker, animated: true, completion: nil)
}
当我完成时,我得到一个代表回调:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
DispatchQueue.main.async {
if let croppedImage = info[UIImagePickerControllerEditedImage] as? UIImage {
self.imageView.contentMode = .scaleAspectFill
self.imageView.image = croppedImage
self.dismiss(animated:true, completion: nil)
}
}
}
我在拍摄图像后得到裁剪用户界面,在视频中你可以看到行为:
如您所见,我无法将缩放的矩形滚动到底部或顶部。此行为在iOS 10/11上可在多个设备上重现。
有没有办法通过UIImagePickerController
来解决这个问题?
答案 0 :(得分:0)
不,这个组件已经被淘汰了很长一段时间了。不仅这个有定位的,而且裁剪的矩形通常是不正确的(垂直偏差约20px)。
似乎Apple没有兴趣修复它,你应该创建自己的。这不是太多的工作。首先创建一个接受滚动视图并在滚动视图上显示图像的屏幕。然后确保缩放和平移工作(甚至可能是旋转),这应该很快完成。
然后通过使用视图快照实现最快完成的裁剪部分:
以下内容将从图像视图中创建图像:
func snapshotImageFor(view: UIView) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0.0)
guard let context = UIGraphicsGetCurrentContext() else {
return nil
}
view.layer.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
然后在你的视图控制器中你可以做这个小技巧:
func createSnapshot(inFrame rect: CGRect) -> UIImage? {
let temporaryView = UIView(frame: rect) // This is a view from which the snapshot will occure
temporaryView.clipsToBounds = true
view.addSubview(temporaryView) // We want to put it into hierarchy
guard let viewToSnap = scrollViewContainer else { return nil } // We want to use the superview of the scrollview because using scroll view directly may have some issues.
let originalImageViewFrame = viewToSnap.frame // Preserve previous frame
guard let originalImageViewSuperview = viewToSnap.superview else { return nil } // Preserve previous superview
guard let index = originalImageViewSuperview.subviews.index(of: viewToSnap) else { return nil } // Preserve view hierarchy index
// Now change the frame and put it on the new view
viewToSnap.frame = originalImageViewSuperview.convert(originalImageViewFrame, to: temporaryView)
temporaryView.addSubview(viewToSnap)
// Create snapshot
let croppedImage = snapshotImageFor(view: temporaryView)
// Put everything back the way it was
viewToSnap.frame = originalImageViewFrame // Reset frame
originalImageViewSuperview.insertSubview(viewToSnap, at: index) // Reset superview
temporaryView.removeFromSuperview() // Remove the temporary view
self.croppedImage = croppedImage
return croppedImage
}
这个程序有一些缺点,例如在主线程上执行所有操作,但对于您的特定过程,这应该不是问题。
您可能在某些时候需要对图像输出大小进行一些控制。您可以通过修改快照映像以包含自定义比例来实现最简单的操作:
func snapshotImageFor(view: UIView, scale: CGFloat = 0.0) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, scale)
然后你会打电话给snapshotImageFor(view: view, scale: expectedWidth/view.bounds.width)
。