我正在开发适用于iOS的照片编辑扩展程序,该扩展程序捆绑在提供相同照片编辑功能的容器应用程序中。
为了重用代码,我有一个视图控制器类,该类采用必需的PHContentEditingController
协议,并将其子类化,以用作应用程序扩展的主界面和作为应用程序扩展的“工作屏幕”容器应用。
在编辑扩展名上, ,该控制器的方法由“照片”应用程序的编辑会话调用,如Apple文档和您可以在网上找到的各种教程中所述。> 另一方面,在容器应用程序上,
,我首先通过PHAsset
类获得了UIImagePickerController
实例,并直接像这样在“工作”视图控制器上手动启动编辑会话:
// 'work' is my view controller which adopts
// `PHContentEditingController`. 'workNavigation'
// embeds it.
let options = PHContentEditingInputRequestOptions()
options.canHandleAdjustmentData = { (adjustmentData) in
return work.canHandle(adjustmentData)
}
asset.requestContentEditingInput(with: options, completionHandler: { [weak self] (input, options) in
// (Called on the Main thread on iOS 10.0 and above)
guard let this = self else {
return
}
guard let editingInput = input else {
return
}
work.asset = asset
work.startContentEditing(with: editingInput, placeholderImage: editingInput.displaySizeImage!)
this.present(workNavigation, animated: true, completion: nil)
})
用户完成编辑后,工作视图控制器会自行调用finishContentEditing(completionHandler:
来完成会话:
self.finishContentEditing(completionHandler: {(output) in
// nil output results in "Revert" prompt.
// non-nil output results in "Modify" prompt.
let library = PHPhotoLibrary.shared()
library.performChanges({
let request = PHAssetChangeRequest(for: self.asset)
request.contentEditingOutput = output
}, completionHandler: {(didSave, error) in
if let error = error {
// handle error...
} else if didSave {
// proceed after saving...
} else {
// proceed after cancellation...
}
})
})
在编辑会话中,用户可以“清除”作为调整数据传递的先前编辑,从而有效地将图像恢复为原始状态。
我注意到,如果我通过以finishContentEditing(completionHandler:)
作为参数(而不是有效的nil
对象)调用传递给PHContentEditingOutput
的完成处理程序来完成编辑,则Photos框架将提示用户“还原”图像而不是“修改”图像:
func finishContentEditing(completionHandler: @escaping (PHContentEditingOutput?) -> Void) {
guard let editingInput = self.editingInput, let inputURL = editingInput.fullSizeImageURL else {
return completionHandler(nil)
}
if editingInput.adjustmentData != nil && hasUnsavedEdits == false {
// We began with non-nil adjustment data but now have
// no outstanding edits - means REVERT:
return completionHandler(nil)
}
// (...proceed with writing output to url...)
但是,这仅在从容器应用程序运行时有效。如果我尝试通过扩展使用相同的技巧(即,加载包含先前编辑内容的图像,请重置它们,然后点击“完成”),我收到可怕的“无法保存更改” 消息...
从照片编辑扩展程序内将以前的编辑还原为图像的正确方法是什么?
答案 0 :(得分:0)
几个月后,仍然没有答案,因此我勉强采用了这种解决方法(相对于错误警报,它还是更好的选择):
当用户从“照片”扩展程序用户界面中点击“完成”,并且该图像未应用任何编辑(因为用户重置了先前的编辑,或者未对全新的图像应用任何更改),请执行以下操作finishContentEditing(completionHandler:)
中的操作:
创建根本没有可见变化(“空效果”)的调整数据,并将其存档为Data
。
使用上方的“无效效果”数据创建一个PHAdjustmentData
实例,并正确设置formatVersion
和formatIdentifier
。
根据会话开始时传递的编辑输入(通常)创建一个PHContentEditingOutput
实例,并设置上面创建的调整数据。
从编辑输入的inputURL
属性中读取未修改的图像,并将其未修改写入由PHContentEditingOutput
实例的{{1} }属性。
调用renderedContentURL
块,并传递编辑输出实例(通常)。
结果:图像以其原始状态保存(未应用任何效果),并且没有警报或错误发生。
缺点::图书馆资产仍处于“已编辑”状态(因为我们传递了非零的编辑输出和调整数据,因此没有其他选择),因此下次用户尝试时要从Photos.app编辑它,将显示红色的“还原”按钮:
但是,选择“还原”将导致图像数据
-
更新资料我检查了内置的“标记”扩展程序的作用:
...这与我上面的解决方法一致,所以我想这是最好的选择。