我在我的项目中实现了一个photopicker,它的工作与否,使用相同的代码,这取决于我实现它的方式。在我的第一种方法中,我使用了一个自定义的UIAlertAction类并在那里做所有的东西,让我的主控制器更亮,但是拾取器委托从未被调用,而是在控制台中输出错误消息( [发现]发现扩展时遇到的错误:错误域= PlugInKit代码= 13"查询已取消" UserInfo = {NSLocalizedDescription =查询已取消} )我想讨论我实施选择器的方式是是对还是为什么?或者,如果它是来自苹果的错误。我已经谷歌搜索了一段时间并检查堆栈溢出中的所有相关问题,除了将选择器代码放在我的主控制器中之外,任何事情都对我有用。
这是我的主控制器的代码,当它没有调用委托时:
第一种让我犯错并且不会给代表打电话的方法
import UIKit
import MobileCoreServices
import Photos
class ViewController: UIViewController {
@IBOutlet weak var lblMain: UILabel!
@IBOutlet weak var buttonsBottom: NSLayoutConstraint!
@IBOutlet weak var imgFromUser: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
hideButtons()
}
override func viewDidAppear(_ animated: Bool) {
showButtons()
checkPermission()
}
func checkPermission() {
let photoAuthorizationStatus = PHPhotoLibrary.authorizationStatus()
switch photoAuthorizationStatus {
case .authorized: print("Access is granted by user")
case .notDetermined: PHPhotoLibrary.requestAuthorization({
(newStatus) in
print("status is \(newStatus)")
if newStatus == PHAuthorizationStatus.authorized { print("success") }
})
case .restricted: print("User do not have access to photo album.")
case .denied: print("User has denied the permission.")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func hideButtons()
{
buttonsBottom.constant += self.view.frame.size.height * 0.15
}
func showButtons(){
UIView.animate(withDuration: 0.5) {
}
UIView.animate(withDuration: 0.5, animations: {
self.buttonsBottom.constant = 0
self.view.layoutIfNeeded()
}) { (completed) in
self.lblMain.text = firstController.lblMain
}
}
@IBAction func addImagePressed(_ sender: Any) {
let alertViewController : AlertAction = AlertAction.init(controller: self, type: .photoGallery)
self.present((alertViewController.setType(alert: .photoGallery)), animated: true, completion: nil)
}
}
这是我自定义的AlertAction类,它实现了picker&导航委托,创建UIImagePickerController,设置委托,创建警报操作并将其设置为呈现主视图控制器,将其添加到UIAlertController并返回到呈现它的主视图控制器:
import UIKit
import Photos
class AlertAction: UIAlertAction {
var destinationController : ViewController?
var imagePicker = UIImagePickerController()
convenience init(controller : ViewController, type : type) {
self.init()
destinationController = controller
//Init picker
imagePicker.delegate = self
imagePicker.sourceType = type == .photoGallery ? UIImagePickerControllerSourceType.photoLibrary : UIImagePickerControllerSourceType.camera
imagePicker.allowsEditing = false
}
enum type {
case camera
case photoGallery
}
var alertType : type = .camera
func setType(alert : type) -> UIAlertController {
alertType = alert
return alertType == .camera ? newAlert() : newAlert()
}
func newAlert() -> UIAlertController{
//set alert text
let alertText = alertType == .camera ? AlertText.typeCamera : AlertText.typeGalery
let myAlert = UIAlertController(title: AlertText.title, message: "", preferredStyle: .actionSheet)
if alertType == .camera {
myAlert.addAction(getCameraAction(alertText: alertText))
return myAlert
}
else{
myAlert.addAction(getGalleryAction(alertText: alertText))
return myAlert
}
}
func getCameraAction(alertText : String) -> UIAlertAction{
let cameraAction = UIAlertAction(title : alertText, style : .default) { (action) in
if UIImagePickerController.isSourceTypeAvailable(.camera) {
self.destinationController!.present(self.imagePicker, animated: true, completion: nil)
}
}
return cameraAction
}
func getGalleryAction(alertText : String) -> UIAlertAction{
let photoLibraryAction = UIAlertAction(title: alertText, style: .default) { (action) in
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
self.destinationController!.present(self.imagePicker, animated: true, completion: nil)
}
}
return photoLibraryAction
}
}
extension AlertAction : UIImagePickerControllerDelegate {
@objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let mediaType = info[UIImagePickerControllerMediaType] as! NSString
if mediaType.isEqual(to: kCIAttributeTypeImage as String){
destinationController!.imgFromUser.image = info[UIImagePickerControllerOriginalImage] as? UIImage
}
destinationController!.dismiss(animated: true, completion: nil)
}
@objc func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
destinationController!.dismiss(animated: true, completion: nil)
}
}
extension AlertAction : UINavigationControllerDelegate {
}
阅读一段时间后,我一直在尝试这个自定义课程中所有可行的解决方案,但没有任何效果。 然后我尝试在我的主视图控制器中实现一个选择器创建方法,它工作。 所以我的问题非常简单,为什么只有在主视图控制器中执行所有编码工作但不在自定义类中工作时才调用委托方法?
以下是我目前正在使用和运作的代码:
第二种方法有效,同一ViewController中的所有代码
import UIKit
import MobileCoreServices
import Photos
class ViewController: UIViewController {
@IBOutlet weak var lblMain: UILabel!
@IBOutlet weak var buttonsBottom: NSLayoutConstraint!
@IBOutlet weak var imgFromUser: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
hideButtons()
}
override func viewDidAppear(_ animated: Bool) {
showButtons()
checkPermission()
}
func checkPermission() {
let photoAuthorizationStatus = PHPhotoLibrary.authorizationStatus()
switch photoAuthorizationStatus {
case .authorized: print("Access is granted by user")
case .notDetermined: PHPhotoLibrary.requestAuthorization({
(newStatus) in
print("status is \(newStatus)")
if newStatus == PHAuthorizationStatus.authorized { print("success") }
})
case .restricted: print("User do not have access to photo album.")
case .denied: print("User has denied the permission.")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func hideButtons()
{
buttonsBottom.constant += self.view.frame.size.height * 0.15
}
func showButtons(){
UIView.animate(withDuration: 0.5) {
}
UIView.animate(withDuration: 0.5, animations: {
self.buttonsBottom.constant = 0
self.view.layoutIfNeeded()
}) { (completed) in
self.lblMain.text = firstController.lblMain
}
}
@IBAction func addImagePressed(_ sender: Any) {
self.present(addPicker(), animated: true, completion: nil)
}
//MARK: Picker methods
func addPicker()->UIAlertController{
let alertText = AlertText.typeGalery
let myAlert = UIAlertController(title: AlertText.title, message: "", preferredStyle: .actionSheet)
let cameraAction = UIAlertAction(title : alertText, style : .default) { (action) in
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}
}
myAlert.addAction(cameraAction)
return myAlert
}
}
extension ViewController : UIImagePickerControllerDelegate {
@objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let mediaType = info[UIImagePickerControllerMediaType] as! NSString
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage{
self.imgFromUser.image = image
}
if mediaType.isEqual(to: kCIAttributeTypeImage as String){
self.imgFromUser.image = info[UIImagePickerControllerOriginalImage] as? UIImage
}
self.dismiss(animated: true, completion: nil)
}
@objc func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.dismiss(animated: true, completion: nil)
}
}
extension ViewController : UINavigationControllerDelegate {
}
更新:发现扩展时遇到错误 [发现]错误:错误域= PlugInKit代码= 13"查询已取消" UserInfo = {NSLocalizedDescription = query canceled} 仍然出现在我的第二个实现中,但只有当我在选择器委托方法和环境varibable OS_ACTIVITY_MODE = disable之前删除@objc但是代码仍然有效且委托是正确调用(在第二个实现中)所以基本上这个错误与代码功能无关并且没有描述任何有用的东西