UICollectionView not showing images after unhiding it - ios

I have an UICollectionView that starts hidden in the viewDidLoad, then when an image is added with the UIImagePicker delegate the collection goes "unhidden" and then reloads, here is the code below
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
self.imagesToSend.append(pickedImage)
}
self.imagenesCollectionView.isHidden = false
self.imagenesCollectionView.reloadData()
dismiss(animated: true, completion:nil)
}
the problem is that when the collection shows it doesn't show any image, I have to add a second image so the image can show, I want the collection to show when there are images and to hide when there aren't images, until now the hiding functionality its working fine, but not the showing one.

Try adding
self.imagenesCollectionView.isHidden = false
self.imagenesCollectionView.reloadData()
in dismiss completion handler. Like
dismiss(animated: true, completion:{
self.imagenesCollectionView.isHidden = false
self.imagenesCollectionView.reloadData()
})
Edit 1:
Instead of reloading collection view in completion. add collection view reload in viewWillAppear method based on the array data availability.
eg:
if self.imagesToSend.count > 0 {
self.imagenesCollectionView.isHidden = false
self.imagenesCollectionView.reloadData()
} else {
self.imagenesCollectionView.isHidden = true
}

Try to use the methods setNeedsLayout or setNeedsDisplay. They are related to the view update, and maybe you need to use them on the collectionView or on the imageView itself.

Related

How To Perform Segue After Picking Image

I would like to perform a segue just after the user chooses an image (by clicking on the image view).
I have already checked the segue id and successfully managed to connect both view controllers.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// Executed when we select an image from the photo library.
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
// Sets the image to the image view (not really relevant because
// we push the user to the DetailVC, but let's leave it).
self.imageView.image = image
// Closing the image picker.
self.dismiss(animated: true, completion: nil)
// Performing segue (It doesn't perform!).
print("It gets to this point, but doesn't perform.")
self.performSegue(withIdentifier: "showDetail", sender: nil)
}
}
The program sets the image to the image view, gets to that print statement just after the "perform" function, but the segue is not performed.
in storyboard select the view controller which has the imageview, at the top there is yellowcircle right click drag from there to the view controller you want to segue to and give its identifier an ID = “segueID”
then edit your didfinishpicking method like this
if let img = info[.originalImage] as? uiimage{
myimageview.image = img
dismiss(animated: true) {
self.performSegue(withIdentifier: “segueID”, sender: self)}}
I believe the problem lies that you are dismissing your view/view controller before performing segue
// Closing the image picker.
self.dismiss(animated: true, completion: nil)
Have you tried:
Setting the sender to self?
Making sure that your segue is the correct type. (I know you checked the name and you probably would have gotten an error if you got the name wrong, in this case I mean "push" vs "show detail" etc)
Adding a prepareForSegue function to make sure that the segue is actually getting called
Building up on #Loren Rogers answer:
// Closing the image picker.
self.dismiss(animated: true, completion: nil)
You're not actually dismissing the UIImagePickerController. Like Loren mentioned, you're dismissing the ViewController. This is because self is a reference to the ViewController.
Replace self with picker like so:
// Closing the image picker.
picker.dismiss(animated: true, completion: nil)

How to dismiss a view controller in a navigation controller, without dismissing the whole stack

Basically I have tab bar controller with two tabs, each holds a separate navigation controller, each with a couple of views (see below).
In the "top" navigation controller (held in the right tab), I can choose an image, and then am taken to the rightmost screen to preview the image...
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerEditedImage] as? UIImage {
let previewController = self.storyboard?.instantiateViewController(withIdentifier: "previewVC") as! PreviewViewController
previewController.img = image
previewController.navigationItem.setHidesBackButton(true, animated: false)
self.navigationController?.pushViewController(previewController, animated: true)
self.dismiss(animated: true, completion: nil)
}
}
...where I tap "post". This uploads the image and calls self.tabBarController?.selectedIndex = 0
That simply takes me to the image feed, which is in the "bottom" navigation controller (left tab). So far so good. However, the preview screen is still displayed in the "right" tab, when I need the upload screen to be displayed after I post.
If I call self.dismiss(animated: true, completion: nil) when I tap post, the entire navigation controller is dismissed and I'm taken back to the login screen.
So I'm trying to dismiss the preview controller so the upload controller is shown as the default view in the right tab, without dismissing the entire stack in that navigation controller.
How can I do this?
If you use navigation controllers to add view controllers to the navigation stack (push), you can remove them by calling a pop function. When you present view controllers modally, you call dismiss to remove the view controller.
The delegate function gives you the (image picker) view controller and you should dismiss that, not the view controller that is the delegate (usually the presenting view controller). Maybe try something like this:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerEditedImage] as? UIImage {
let previewController = self.storyboard?.instantiateViewController(withIdentifier: "previewVC") as! PreviewViewController
previewController.img = image
previewController.navigationItem.setHidesBackButton(true, animated: false)
self.navigationController?.pushViewController(previewController, animated: true)
picker.dismiss(animated: true, completion: nil)
}
}

How to enable a currently disabled button in Swift

I have an action button in my iOS application (using Swift 3), which I guess is technically a toolbar item.
I presently disable the button in viewWillAppear() with
actionButton.isEnabled = false
I then try to enable it after an image has been selected:
func imagePickerController(_: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.image = image
imageView.contentMode = .scaleAspectFit
}
dismiss(animated: true, completion: nil)
actionButton.isEnabled = true
print("selected an image in picker")
}
And I can see that my print statement occurs as well as the image being selected and activity view controller dismissing, just as expected. HOWEVER, my actionButton stays disabled.
Any ideas why? I'm very new to Swift!
viewWillAppear() is called every time, before your view controller loads. When you dismiss your imagePicker, and go back to presenting your original viewController that viewWillAppear() would be called again, and it would override your actionButton.isEnable = true to being false again. If I were you, I would disable the button in viewDidLoad(), which is called only once.
try to execute the code that changes the UI in the main thread like this:
DispatchQueue.main.async {
actionButton.isEnabled = true
}

How do I set an image to my imageView without the imagePickerController hiding it?

Ideally I'm looking to set the image returned from my camera to an imageView, but without dismissing the controller so it seamlessley fills the screen. Below is my code: I am setting the image property that is returned to my image view after dismissing the imagepickercontroller - how do I set this so the image sets to the image view over the imagepickercontrooler without having to dismiss the imagepickercontroller. Ideally I'd like the image to set to the imageView and for my VC to display that without having to dismiss the imagepicker. Cheers
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let IMG: UIImage = info[UIImagePickerControllerOriginalImage] as! UIImage
self.dismissViewControllerAnimated(false) { () -> Void in
imageArray.append(IMG)
self.imageView0.image = IMG
}
}
Simple: self.imageView0.image = IMG
If you want to save image also in array try this way:
imageArray.append(IMG)
but do not use this inside dismissViewControllerAnimated.

Instagram camera page

I have implemented the camera roll when I click the middle button just like in instagram using the function ShouldSelectViewController. And if I hit cancel, it goes back to the tab before. The problem I m having now is that, I would like to show another view controller with the selected image. Is there any function that can me to solve this?
Thank you
If you're using UIImagePickerController, there is a delegate method you can implement to handle what happens after a picture is selected.
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
//do something with the image
}
}
You can segue to another view controller in this method via the regular patterns. For example, let's say you decide to put the image in another view controller called AnotherViewController.
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
let vc = storyboard!.instantiateViewControllerWithIdentifier("anotherViewController") as! AnotherViewController
vc.imageToDisplay = image
presentViewControllerAnimated(vc, animated: true)
}

Resources