web-dev-qa-db-ja.com

UIImagePickerControllerデリゲートは呼び出されませんSwift 3

表面的には、これはデリゲートの問題である必要があると思いましたが、デリゲートを要求した後、正しいものが返されました。

私はすべてのUIImagePickerControllerのものを処理するためにImagePickerクラスを作成しました。デリゲートメソッドを呼び出す必要があるまで、すべてが機能します。写真を選択した後、imagePickerは終了しますが、didFinishPickingMediaWithInfoメソッドが呼び出されることはありません。助けてください!ありがとう:)

func selectPhoto() {
    imagePicker.delegate = self //Delegate gets set here

    let photoAsk = UIAlertController.init( //Ask user if they want to take picture or choose one
        title: "Edit Profile Picture",
        message: nil,
        preferredStyle: .alert)
    let cameraAction = UIAlertAction.init(
        title: "Take Photo",
        style: .default) { (UIAlertAction) in
            if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
                self.imagePicker.sourceType = .camera
                UIApplication.topViewController()!.present(self.imagePicker, animated: true, completion:nil)
            } else {
                print("Cannot access camera in simulator.")
                return
            }
    }
    let photoLibraryAction = UIAlertAction.init(
        title: "Photo Library",
        style: .default) { (UIAlertAction) in
            self.imagePicker.sourceType = .photoLibrary
            UIApplication.topViewController()!.present(self.imagePicker, animated: true, completion:nil)
            print("UIImagePickerDelegate: \(self.imagePicker.delegate.debugDescription)") // <--THIS PRINTS OUT "AppName.ImagePicker: 0x145d7bdf0>", and the class name is ImagePicker
    }
    let cancelAction = UIAlertAction.init(
        title: "Cancel",
        style: .cancel) { (UIAlertAction) in return }

    photoAsk.addAction(cameraAction)
    photoAsk.addAction(photoLibraryAction)
    photoAsk.addAction(cancelAction)

    imagePicker.mediaTypes = [kUTTypeImage as String]

    UIApplication.topViewController()?.present(photoAsk, animated: true, completion: nil)
    }
}

これは決して呼び出されません:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    print("Image picked.") //NEVER PRINTS
}
12
Clayton Cohn

細部

  • Xcode 9.2、Swift 4
  • Xcode 10.2.1(10E1001)、Swift 5

解決

extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        dismiss(animated: true, completion: nil)
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        print("\(info)")
        if let image = info[.originalImage] as? UIImage {
            imageView?.image = image
            dismiss(animated: true, completion: nil)
        }
    }
}

使用法

let imagePickerController = UIImagePickerController()
imagePickerController.allowsEditing = false
imagePickerController.sourceType = .photoLibrary
imagePickerController.delegate = self
present(imagePickerController, animated: true, completion: nil)

完全なサンプル

追加することを忘れないでくださいここでのソリューションコード(上記を参照)

import UIKit

class ViewController: UIViewController {

    private weak var imageView: UIImageView?

    override func viewDidLoad() {
        super.viewDidLoad()
        let stackView = UIStackView(frame: .zero)
        stackView.axis = .vertical
        stackView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(stackView)
        stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true

        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFit
        imageView.translatesAutoresizingMaskIntoConstraints = false
        stackView.addArrangedSubview(imageView)
        imageView.widthAnchor.constraint(equalToConstant: 200).isActive = true
        imageView.heightAnchor.constraint(equalToConstant: 200).isActive = true
        self.imageView = imageView

        let button = UIButton(frame: .zero)
        button.setTitle("Button", for: .normal)
        button.setTitleColor(.blue, for: .normal)
        button.addTarget(self, action: #selector(showImages), for: .touchUpInside)
        stackView.addArrangedSubview(button)
    }

    @IBAction func showImages(_ sender: AnyObject) {
        let imagePickerController = UIImagePickerController()
        imagePickerController.allowsEditing = false
        imagePickerController.sourceType = .photoLibrary
        imagePickerController.delegate = self
        present(imagePickerController, animated: true, completion: nil)
    }
}
11

デリゲートから直接メソッド名をコピーする必要がありました。何らかの理由で、オートコンプリートのメソッドヘッダーが間違っています。

public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
        //save image
        //display image
    }
    self.dismiss(animated: true, completion: nil)
}

public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    self.dismiss(animated: true, completion: nil)
}
8
Dustin Spengler

デリゲートコードはアクティブなUIViewController内にある必要があることがわかりました。

最初は、次のように正しいデリゲートプロトコルが宣言されたNSObjectのように、コードを別のファイルに含めようとしました。

class PhotoPicker: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

しかし、それはデリゲートメソッドを呼び出したことはありません。

exactと同じコードを取得して、それを呼び出していたUIViewController内に配置して機能させました。

最善の解決策は、ポップアップタイプのビューを作成し、そのViewControllerにコードを保持させることです。

3
Nico teWinkel

私もこの問題に直面し、以下の解決策を使用して解決しました。現在の完了後にピッカーのデリゲートを設定します。

controller.present(picker, animated: true, completion: {
            self.picker.delegate = self
        })

これがうまくいくことを願っています!!

3
iDev750

デリゲートが呼び出される前に、UIImagePickerControllerがリリースされていないことを確認する必要があります。

私はすべてのUIImagePickerControllerのものを処理するためにImagePickerクラスを作成しました。

私は同様のクラスを作成しましたが、

func onButtonDidTap(sender: UIButton) {
.....
    let picker = VLImagePickerController()
    picker.show(fromSender: sender, handler: { (image: UIImage?) -> (Void) in
        if (image != nil) {
            self.setImage(image!)
        }
    })
....
}

私にとってはうまくいきませんでした。 「picker」は、「handler」が呼び出される前にリリースされました。

私は永続的な参照を作成しましたが、うまくいきました:

let picker = VLImagePickerController()

    func onButtonDidTap(sender: UIButton) {
    .....
            //let picker = VLImagePickerController()
            picker.show(fromSender: sender, handler: { (image: UIImage?) -> (Void) in
                if (image != nil) {
                    self.setImage(image!)
                }
            })
    ....
        }
2
Victor_Z

NSObjectの共通クラスとdelegatesUIImagePickerControllerメソッドが呼び出されていないときに作成しました。

5時間のブレインストーミングの後、最後に、ソリューションを取得します。カメラからキャプチャされた画像中にメモリ割り当て解除に関連する問題のようです。

解決策:1つの単語で、共通のクラス参照をグローバルに定義します。

public typealias CameraBlock = (UIImage?, Bool) -> Void

class HSCameraOverlay: NSObject {

    var pickerController = UIImagePickerController()
    private var completionBlock: CameraBlock!
    var presentationController: UIViewController?

    public init(presentationController: UIViewController) {
        super.init()
        self.presentationController = presentationController
    }


    public func present(completionBlock: @escaping CameraBlock) {
        guard UIImagePickerController.isSourceTypeAvailable(.camera) else {
            return
        }

        self.pickerController = UIImagePickerController()
        self.pickerController.delegate = self
        self.pickerController.allowsEditing = true
        self.pickerController.sourceType = .camera
        self.completionBlock = completionBlock
        self.presentationController?.present(self.pickerController, animated: true, completion: nil)
    }
}


extension HSCameraOverlay: UIImagePickerControllerDelegate,UINavigationControllerDelegate {

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        self.completionBlock?(nil,false)
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        guard let image = info[.originalImage] as? UIImage else {
            self.completionBlock?(nil,false)
            return
        }
        self.completionBlock?(image,true)
        pickerController.dismiss(animated:true, completion: nil)
    }
}

機能しないコード:

class AuthViewController: UIViewController{

@IBAction func actionLoginTap(_ sender: UIControl) {

    let overlay = HSCameraOverlay(presentationController:self)

        overlay.present { (image, status) in
            print(image,status)
        }
    }
}

作業コード:

class AuthViewController: UIViewController{

lazy var overlay = HSCameraOverlay(presentationController:self)

@IBAction func actionLoginTap(_ sender: UIControl) {

        overlay.present { (image, status) in
            print(image,status)
        }
    }
}
1
IMHiteshSurani

このコードは機能します(viewWillAppearにピッカーを表示するため、何度も再表示されますが、これはコードを小さく保つためです)。これと何が違うのか見てみます。それはあなたのトップビューコントローラーと関係があるかもしれませんか?アプリケーションのトップビューコントローラに移動するのではなく、ビューコントローラからピッカーを表示するだけではどうですか。また、デリゲートコールバックを取得したら、ビューコントローラーを閉じる必要があります。

import UIKit
import MobileCoreServices

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    let imagePicker = UIImagePickerController()

    override func viewDidLoad() {
        super.viewDidLoad()
        imagePicker.mediaTypes = [kUTTypeImage as String]
        imagePicker.delegate = self
    }

    override func viewDidAppear(_ animated: Bool) { // keeps reopening, do not this in your code. 
        present(imagePicker, animated: true, completion: nil)
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        imagePicker.dismiss(animated: true, completion: nil)
    }
}
1
possen

UINavgationControllerDelegate宣言が抜けていたので、これに賛成票を投じました。このコメントは役に立ちました。

imagePickerControllerが呼び出されていませんでした。

0
Eric Stevenson

Swift 4.2 ViewControllerに応じて追加

 UIImagePickerControllerDelegate,UINavigationControllerDelegate 
   @IBOutlet weak var ImagePhoto: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func btnPhotoTap(_ sender: Any) {

        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self  
        imagePicker.sourceType = .photoLibrary // Or .camera as you require
        imagePicker.allowsEditing = true
        self.present(imagePicker, animated: true, completion: nil)
    }
    //MARK:-imagePickerControllerDelegate
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let image1 =  info[UIImagePickerController.InfoKey.editedImage] as? UIImage
        self.ImagePhoto.image = image1
        self.dismiss(animated: true, completion: nil)
    }
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {

        print("Cancel")
        self.dismiss(animated: true, completion: nil)
 }
0
user3263340