表面的には、これはデリゲートの問題である必要があると思いましたが、デリゲートを要求した後、正しいものが返されました。
私はすべての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
}
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)
}
}
デリゲートから直接メソッド名をコピーする必要がありました。何らかの理由で、オートコンプリートのメソッドヘッダーが間違っています。
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)
}
デリゲートコードはアクティブなUIViewController内にある必要があることがわかりました。
最初は、次のように正しいデリゲートプロトコルが宣言されたNSObjectのように、コードを別のファイルに含めようとしました。
class PhotoPicker: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
しかし、それはデリゲートメソッドを呼び出したことはありません。
exactと同じコードを取得して、それを呼び出していたUIViewController内に配置して機能させました。
最善の解決策は、ポップアップタイプのビューを作成し、そのViewControllerにコードを保持させることです。
私もこの問題に直面し、以下の解決策を使用して解決しました。現在の完了後にピッカーのデリゲートを設定します。
controller.present(picker, animated: true, completion: {
self.picker.delegate = self
})
これがうまくいくことを願っています!!
デリゲートが呼び出される前に、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!)
}
})
....
}
NSObject
の共通クラスとdelegates
のUIImagePickerController
メソッドが呼び出されていないときに作成しました。
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)
}
}
}
このコードは機能します(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)
}
}
UINavgationControllerDelegate
宣言が抜けていたので、これに賛成票を投じました。このコメントは役に立ちました。
imagePickerController
が呼び出されていませんでした。
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)
}