So right now I am trying to get the collection view Cells to use the photo library to update photos. Here is my code:
import UIKit
class viewCellVC: UICollectionViewCell, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var bookImage: UIImageView!
#IBAction func addImage(_ sender: Any) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
imagePicker.allowsEditing = false
self.window?.rootViewController?.present(imagePicker, animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
bookImage.image = image
picker.dismiss(animated: true, completion: nil)
}
}
However, when I attempt to run the code and update the pictures, the simulator fails to open the photo library and I instead get the following error message(doesn't end the app, just fails to run the photo library):
2017-08-07 21:35:31.709183-0500 ChuBookElf[2817:66569] Warning: Attempt to present <UIImagePickerController: 0x7f907e0bf800> on <ChuBookElf.ViewController: 0x7f907de072c0> whose view is not in the window hierarchy!
Can somebody tell my what I am doing wrong? I've been on this for hours now.
For Reference, here is what the collection view cell looks like
For starters, you are creating the imagePicker in a UICollectionViewCell.
You should create the imagePicker in the ViewController that contains the said UICollectionView along with the delegate methods. Then, in didFinishPickingMediaWithInfo, set the selected image to the appropriate collectionViewCell and reload your collectionView
Related
could you please help me with UIImagePickerController
I have 12 ImageViews in 1 ViewController. I need help so that each ImageView could pick different photos from Library. Someone told me to use Tags for them but I can't make it work cause i'm new in Swift.
Enable User Interaction Enabled for each UIImageView on a Storyboard.
Add TapGestureRecogniser to each UIImageView. Connect each TapGestureRecogniser with IBAction.
#IBAction func tap(_ sender: UITapGestureRecognizer) {
currentImageView = sender.view as! UIImageView
let picker = UIImagePickerController()
picker.delegate = self
self.present(picker, animated: true, completion: nil)
}
Define variable to store current UIImageView
private var currentImageView: UIImageView? = nil
Handle image selection and assign the image to currentImageView
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[UIImagePickerController.InfoKey.originalImage]
currentImageView?.image = image as! UIImage
self.dismiss(animated: true, completion: nil)
}
It's not about the swift. You set up a "tag" number in the Interface builder (or in the code. There is a .tag property on the UIResponder descendants).
After that you make a switch in your callback method like
To make it a bit clearer:
let picker: UIImagePicker! = {
// setup your image picker here, don't forget to set the proper delegate
}()
var lastSender: AnyObject?
func onTouch(_ sender: AnyObject?) {
// add checks for the sender here
lastSender = sender
present(picker, animated: true, completion: *Your Completion*)
}
Delegate:
in
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
let image = *Get Image From Info*
lastSender?.image = image
i want import image in ios from library but i have error
value of type 'viewcontroller' has no member 'present'
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func Alert(sender: AnyObject) {
let nextController = UIImagePickerController()
self.present(nextController, animated: true, completion: nil)
}}
Here's my stripped working code. I use two pickers - one for camera, one for library - because of some odd iOS bug with tint color. To avoid "massive view controller" issues, I tend to move everything possible related to a a UIImagePickerController into a separate file and extension.
class OpenViewController: UIViewController {
let pickerLibrary = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
pickerLibrary.delegate = self
}
}
extension OpenViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#objc func showImagePicker() {
pickerLibrary.allowsEditing = false
pickerLibrary.sourceType = .photoLibrary
present(pickerLibrary,
animated: true,
completion: nil)
pickerLibrary.popoverPresentationController?.sourceView = self.view
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: false, completion: nil)
}
}
While the present code looks correct, I notice several things you didn't post in your code. Maybe because you just didn't post it, but I would definitely check these things:
Are you setting ViewController to be a delegate?
Are you setting ViewController.view to be the source view? This may not be needed for iPhone, but definite helps with iPad.
Have you includes everything needed to be working for UIImagePickerControllerDelegate, UINavigationControllerDelegate?
Now as your error suggests, something else is likely the issue - a UIViewController can present another view controller. In this case you've given us no way to duplicate that error. In other words, I'm assuming that (1) You are seeing a UIButton attached to Alert() - BTW, Swift conventions use lower case for that - and (2) You've proven that when that button is tapped, `Alert() is actually executed.
I have a UIImageView that has my "profile image" inside. When I tap on this, it calls a function that presents my UIImagePickerController. This works fine. My issue is that my delegate methods simple aren't being called. When I add breakpoints, it doesn't hit them at all. I have used the exact same method elsewhere in my project and it works fine so there's nothing wrong with my info.plist file. Does anybody know what I'm doing wrong? Thank you...
extension ChatLogController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
profileImageView.image = image
self.dismiss(animated: true, completion: nil)
}
#objc func handlePresentImagePicker() {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
self.present(imagePicker, animated: true, completion: nil)
}
}
I realised that the issue was that I was using a custom transition (a transition that involved me being able to swipe right to dismiss my controller). Once I commented all of the code related to that, everything worked fine. Very unfortunate that I have to get rid of my transition but hey, it now works!
Have such part of my storyboard:
So I want present from UserProfileController: UIViewController "Мой профиль", which is modal, (on the top on image) UIImageViewController.
My code:
extension UserProfileController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBAction func imagePressed(_ sender: Any) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
self.present(imagePickerController, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else {
return
}
picker.dismiss(animated: true, completion: nil)
userProfileImageView.image = image
}
}
Well, imagePickerController presented, but after I choose image I have dismissed both controllers (imagePickerController and parent - UserProfileControler).
What am I doing wrong? Thanks
P.S. May be problem is I'm showing "SideMenuNavigationController" as modal? (so advised in SideMenu framework documentation)
Try to create you UIImagePickerController reference in your class (as a variable)
// to choose an image from the Camera Roll
fileprivate lazy var imagePicker: UIImagePickerController = {
let picker: UIImagePickerController = UIImagePickerController()
picker.allowsEditing = false
picker.sourceType = .savedPhotosAlbum
picker.delegate = self
return picker
}()
I am trying to make an image uploader on my ios app.
EDIT 7
This question is now more clearly asked here: Present Modal for Image Select Erases UI
END OF EDIT 7
The first thing I am trying to do is enable the user to select an image that they want for upload.
EDIT 6
I have simplified all the code to simply one button press. The Modal presentation deletes the previous page's UI. How I prevent this.
import UIKit
class AddImageToStandViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func loadImageButtonTapped(sender: UIButton) {
let imagePicker = UIImagePickerController()
imagePicker.allowsEditing = false
imagePicker.sourceType = .PhotoLibrary
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
I have found that the selection works just fine and does not destroy the UI if I push/segue from a different to this controller.
END OF EDIT 6
Below this is the other methods that I have tried before this
So far, this code enables a user to press a button and choose a photo from their photos. But, after they click the photo it just returns them to an empty View except the navbar at the bottom.
It seems my user is being returned, not to the view that they came from, but to a separate empty view. How do I return the user to the view that they came from?
import UIKit
class CreateStandViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var image: UIImageView!
...
#IBAction func selectPicture(sender: AnyObject) {
let ImagePicker = UIImagePickerController()
ImagePicker.delegate = self
ImagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(ImagePicker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
image.image = info[UIImagePickerControllerOriginalImage] as? UIImage
self.dismissViewControllerAnimated(true, completion: nil)
}
...
let me know if there is any more information that I should give.
EDIT 1
this code has the same effect
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
image.image = info[UIImagePickerControllerOriginalImage] as? UIImage
picker.dismissViewControllerAnimated(true, completion: nil)
}
I have tried adding this line below but I get an error stating that CreateStandViewController.Type cannot be converted to the expected UIViewController.
self.presentViewController(CreateStandViewController, animated: true, completion: nil)
EDIT 2
This code below doesnt error but also changes nothing
let createStandController = CreateStandViewController()
self.presentViewController(createStandController, animated: true, completion: nil)
EDIT 3
I have literally copied all the code from here: http://www.codingexplorer.com/choosing-images-with-uiimagepickercontroller-in-swift/ and now have:
import UIKit
class CreateStandViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var imageView: UIImageView!
let imagePicker = UIImagePickerController()
#IBAction func loadImageButtonTapped(sender: UIButton) {
imagePicker.allowsEditing = false
imagePicker.sourceType = .PhotoLibrary
presentViewController(imagePicker, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
}
// MARK: - UIImagePickerControllerDelegate Methods
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.contentMode = .ScaleAspectFit
imageView.image = pickedImage
}
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
}
This has the same issue as before. When the image is selected I am sent back to a view that is white with the navbar at the bottom.
EDIT 4
I have run the same code in its own separate project as a stand alone view controller and it works. There is some code that I have in the background of my app that is killing the functionality of the code (maybe). I am guessing it may have something to do with the navbar?
EDIT 5
I removed the tab bar at the bottom by seguing to the image selecting view via a present Modally segue, but it had no effect.
Just replace your
self.dismissViewControllerAnimated(true, completion: nil)
with
picker.dismissViewControllerAnimated(true, completion: nil)
I think you will get the point after that