I want to add uiimagepickercontroller to a VC but I chnage the button to bar button then
I got an error after change the btnClickMe for UIButton to UIBarButtonItem I didn't understand the Error what seems the problem ?
value type UIBarButtonItem has no member 'Frame'
I deleted the frame but it didn't works
class ViewController: UIViewController,UIAlertViewDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate,UIPopoverControllerDelegate
{
#IBOutlet weak var btnClickMe: UIButton!
#IBOutlet weak var imageView: UIImageView!
var picker:UIImagePickerController?=UIImagePickerController()
var popover:UIPopoverController?=nil
override func viewDidLoad()
{
super.viewDidLoad()
picker!.delegate=self
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func btnImagePickerClicked(sender: AnyObject)
{
let alert:UIAlertController=UIAlertController(title: "Choose Image", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
let cameraAction = UIAlertAction(title: "Camera", style: UIAlertActionStyle.Default)
{
UIAlertAction in
self.openCamera()
}
let gallaryAction = UIAlertAction(title: "Gallary", style: UIAlertActionStyle.Default)
{
UIAlertAction in
self.openGallary()
}
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel)
{
UIAlertAction in
}
// Add the actions
picker?.delegate = self
alert.addAction(cameraAction)
alert.addAction(gallaryAction)
alert.addAction(cancelAction)
// Present the controller
if UIDevice.currentDevice().userInterfaceIdiom == .Phone
{
self.presentViewController(alert, animated: true, completion: nil)
}
else
{
popover=UIPopoverController(contentViewController: alert)
popover!.presentPopoverFromRect(btnClickMe.frame, inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
}
}
func openCamera()
{
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera))
{
picker!.sourceType = UIImagePickerControllerSourceType.Camera
self .presentViewController(picker!, animated: true, completion: nil)
}
else
{
openGallary()
}
}
func openGallary()
{
picker!.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
if UIDevice.currentDevice().userInterfaceIdiom == .Phone
{
self.presentViewController(picker!, animated: true, completion: nil)
}
else
{
popover=UIPopoverController(contentViewController: picker!)
popover!.presentPopoverFromRect(btnClickMe.frame, inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
}
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
{
picker .dismissViewControllerAnimated(true, completion: nil)
imageView.image=info[UIImagePickerControllerOriginalImage] as? UIImage
}
func imagePickerControllerDidCancel(picker: UIImagePickerController)
{
print("picker cancel.")
}
}
UIPopoverController has been deprecated in iOS 9. Xcode probably shows this warning:
'UIPopoverController' was deprecated in iOS 9.0: UIPopoverController is deprecated. Popovers are now implementd as UIViewController presentations. Use a modal presentation style of UIModalPresentationPopover and UIPopoverPresentationController.
However, if you still want to use it, you need to use the presentPopoverFromBarButtonItem method instead of presentPopoverFromRect, as UIBarButtonItems don't have a frame property.
Related
I cannot seem to get the alert view to popup at startup of my view. Code is below.
import UIKit
class StartController: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
self.view.backgroundColor = UIColor.white;
startTest();
}
func startTest()
{
let alerta = UIAlertController(title: "Invalid Test", message: "Testing alert controller", preferredStyle: UIAlertControllerStyle.alert);
alerta.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil));
self.present(alerta, animated: true, completion: nil);
}
}
the issue is that in viewDidLoad the view hierarchy is not fully set. If you use viewDidAppear, then the hierarchy is set.
If you really want to call this alert in viewDidLoad you can do so by wrapping your presentation call in this GCD block to cause a slight delay
DispatchQueue.main.async {
// Run UI Updates or call completion block
startTest()
}
or use in
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
startTest()
}
Call the startTest() in viewDidAppear method. It works for me.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
startTest()
}
func startTest()
{
let alerta = UIAlertController(title: "Invalid Test", message: "Testing alert controller", preferredStyle: UIAlertControllerStyle.alert);
alerta.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil));
self.present(alerta, animated: true, completion: nil);
}
Just try to put it on viewDidAppear: method
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
startTest()
}
In my FirstVC I understand how to work with the UIImagePickerController, load the camera, take a photo, display it inside 1 imageView (still within the FirstVC) and then pass that image to an imageView inside the SecondVC via prepareForSegue to be shown over there.
What I need help with is having multiple imageViews inside FirstVC so that once a user takes the first picture it loads into the 1st imageView, then second picture the 2nd imageView, 3 pic to 3rd imageView, and 4th pic to 4th imageView. Afterwards an alert would appear that would say the user can't take any more pics and the user would press a nextSceneButton to be taken be taken to the SecondVC which would display the 4 chosen images that they just took.
I always used UIImagePickerController but I just got acquainted with AVFoundation. Should I use AVFoundation or UIImagePicker for this task?
Here is my UIImagePickerController code with only one imageView inside the FirstVC:
import UIKit
class FirstViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var nextSceneButton: UIButton!
//nextSceneButton is connected in StoryBoards and triggers the segue to the SecondVC
let imagePicker = UIImagePickerController()
var image: UIImage?
//MARK:- Custom Function
func noCamera(){
let alertVC = UIAlertController(title: "No Camera", message: "Sorry, this device has no camera", preferredStyle: .Alert)
let okAction = UIAlertAction(title: "OK", style:.Default, handler: nil)
alertVC.addAction(okAction)
presentViewController(alertVC, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//MARK:- Buttons
#IBAction func libraryButtonPressed(sender: UIButton) {
imagePicker.allowsEditing = false
imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
presentViewController(imagePicker, animated: true, completion: nil)
}
#IBAction func photoButtonPressed(sender: UIButton) {
if (UIImagePickerController.availableCaptureModesForCameraDevice(UIImagePickerControllerCameraDevice.Rear) != nil){
imagePicker.allowsEditing = false
imagePicker.sourceType = UIImagePickerControllerSourceType.Camera
imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureMode.Photo
imagePicker.cameraDevice = UIImagePickerControllerCameraDevice.Rear
presentViewController(imagePicker, animated: true, completion: nil)
}else{
noCamera()
}
}
//MARK:- ImagePickerController Delegates
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
self.image = chosenImage
imageView.image = self.image
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
picker.dismissViewControllerAnimated(true, completion: nil)
}
//MARK:- Segue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == “fromPhotoVcToSecondVC” {
let secondVC = segue.destinationViewController as! SecondViewController
secondVC.image = self.image
}
}
}//end class
You can add a count property and hold your images in an array :
var count = 0
var imageViews:[UIImageView]
Every time you take a photo and delegate gets called load the respective imageview :
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
self.imageViews[count].image = chosenImage
count +=1
dismissViewControllerAnimated(true, completion: nil)
}
Then if all photos are taken alert the user :
#IBAction func photoButtonPressed(sender: UIButton) {
if count < imageViews.count {
//present UiimagePicker
} else {
// alert no more pictures allowed
}
}
I've 2 VC :
The first VC with 1 button when tapped >> 2 options post image form cam or library
Second VC chosen image form VC1 segued to the second VC
I tried to figured This the error without any success
fatal error: unexpectedly found nil while unwrapping an Optional value
pointed at
imageView.image=info[UIImagePickerControllerOriginalImage] as? UIImage
I uploaded the project in dropbox https://www.dropbox.com/s/w7blbnyac9qyxgw/segImage.zip?dl=0
VC1
class ViewController:UIViewController,UIAlertViewDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate,UIPopoverControllerDelegate
{
#IBOutlet weak var btnClickMe: UIButton!
#IBOutlet weak var imageView: UIImageView!
var picker:UIImagePickerController?=UIImagePickerController()
var popover:UIPopoverController?=nil
override func viewDidLoad()
{
super.viewDidLoad()
picker!.delegate=self
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "" ) {
let destVC : second = segue.destinationViewController as! second
destVC.pics = imageView.image!
}
}
#IBAction func btnImagePickerClicked(sender: AnyObject)
{
let alert:UIAlertController=UIAlertController(title: "Choose Image", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
let cameraAction = UIAlertAction(title: "Camera", style: UIAlertActionStyle.Default)
{
UIAlertAction in
self.openCamera()
}
let gallaryAction = UIAlertAction(title: "Gallary", style: UIAlertActionStyle.Default)
{
UIAlertAction in
self.openGallary()
}
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel)
{
UIAlertAction in
}
// Add the actions
picker?.delegate = self
alert.addAction(cameraAction)
alert.addAction(gallaryAction)
alert.addAction(cancelAction)
// Present the controller
if UIDevice.currentDevice().userInterfaceIdiom == .Phone
{
self.presentViewController(alert, animated: true, completion: nil)
}
else
{
popover=UIPopoverController(contentViewController: alert)
popover!.presentPopoverFromRect(btnClickMe.frame, inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
}
}
func openCamera()
{
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera))
{
picker!.sourceType = UIImagePickerControllerSourceType.Camera
self .presentViewController(picker!, animated: true, completion: nil)
}
else
{
openGallary()
}
}
func openGallary()
{
picker!.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
if UIDevice.currentDevice().userInterfaceIdiom == .Phone
{
self.presentViewController(picker!, animated: true, completion: nil)
}
else
{
popover=UIPopoverController(contentViewController: picker!)
popover!.presentPopoverFromRect(btnClickMe.frame, inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
}
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
{
picker .dismissViewControllerAnimated(true, completion: nil)
imageView.image=info[UIImagePickerControllerOriginalImage] as? UIImage
}
func imagePickerControllerDidCancel(picker: UIImagePickerController)
{
print("picker cancel.")
}
}
second VC
class second: UIViewController {
var pics = UIImage()
#IBOutlet var image: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
if let img = UIImage(named: "pics")
{
self.image.image = img
}
}
Your storyboard wiring is wrong.
The image should really be set on an instance of second rather than an instance of ViewController. Notice that the crash is happening in ViewController and not second
This code:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
{
picker .dismissViewControllerAnimated(true, completion: nil)
imageView.image=info[UIImagePickerControllerOriginalImage] as? UIImage
}
is attempting to set an imageView.image in ViewController. If you look at the Storyboard, there is no UIImageView in ViewController.
The way that you've defined imageView on ViewController is what makes this crash:
#IBOutlet weak var imageView: UIImageView!
With the ! there, you are saying, "This will never be nil." Well, that's obviously not the case because since this IBOutlet isn't wired to a UIImageView then it is nil. And thus, when you try to access it, BOOM!
To fix this:
Segue to second when the user picks an image
Set the selected image on second's image.imageView property
Other suggestion:
- Use consistency in naming, eg second vs SecondViewController
I've tried exhaustively to find the answer to this problem. In the app that I am creating the user will click addImage button and then select an image from the photo library (or camera) from ImagePickerController and then that selected image gets passed to an image view on a second view controller.
I know how to do this when the image view is on the same view as the addImage button but can't figure out how to properly use a segue to pass the image to the second view. Hopefully, someone can help me sort this out.
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate{
var newImage = UIImage(named: "")
#IBOutlet var imageView: UIImageView!
var imagePicker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func addImage(sender: UIButton) {
var alert = UIAlertController(title: "Please Get An Image", message: "Choose from below", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Camera", style: .Default, handler: {(action) -> Void in
self.imagePicker.sourceType = UIImagePickerControllerSourceType.Camera
self.presentViewController(self.imagePicker, animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "Photo Library", style: .Default, handler: {(action) -> Void in
self.imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(self.imagePicker, animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .Default, handler: {(action) -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
}))
self.presentViewController(alert, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
newImage = image
//not sure about this next line here...
performSegueWithIdentifier("VC2", sender: self)
self.dismissViewControllerAnimated(true, completion: nil)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var secondViewController: VC2 = segue.destinationViewController as! VC2
secondViewController.imageView.image = newImage
}
}// end of app
you should not pass the UIImage by using the UIImageView object because this is not a Good idea to pass the image like this, Instead you can create UIImage object in SecondViewController simple pass the UIImage object to that and in SecondVC use this image object like this
override func viewDidLoad() {
super.viewDidLoad()
if imageView != nil {
imageView.image = newImage
}
}
OK susan, so when you click "Use Photo" in the preview part of the camera, that's where you want to implement to segue to the second VC.
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
newImage = image
dismissViewControllerAnimated(true, completion: { () -> Void in
//Will call segue name
self.performSegueWithIdentifier("Your_Segue_name", sender: self)
})
}
EDIT: The above code will segue after you've confirmed that you want to use the image.
In your second VC, have a holder to hold then sent that holder image to your UIImageView. In your 1st VC, sent the image to transfer to the holder image.
Your SecondVC:
#IBOutlet var imgView: UIImageView!
var holderImage: UIImage?
In your viewDidLoad()
imgView.image = holderImage.image
Make sure the segue has its identifier set as "VC2". Also, instead of setting
secondViewController.imageView.image = newImage
expose a property on your secondViewController that takes the image. Set the property with the image in prepareForSegue.
secondViewController.image = newImage
Then, in viewDidLoad on secondViewController set its imageView with the value from the property.
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = image
}
In your code the ImageView on the second controller doesn't exist yet because of the view life cycle.
You can also set a breakpoint in prepareForSegue to make sure it's being called properly and the second controller is being set properly.
I've looked all over for a solution but haven't been able to find one. I want to be able to select an Image from the UIImagePicker and have that image go to an ImageView in a Second View Controller. I have a button that triggers an AlertView with options to get photos from camera or library. It works fine if I want the selected image to go to an image view on the first view but I can't get it to work to have it go to a second view. Any suggestions would be greatfully appreciated. `
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate{
var newImage = UIImage(named: "")
#IBAction func libraryBtn(sender: AnyObject) {
imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
presentViewController(imagePicker, animated: true, completion: nil)
}
#IBOutlet var imageView: UIImageView!
var imagePicker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = UIImage(named: "beach.jpg" )
imagePicker.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func addButton(sender: UIButton) {
var alert = UIAlertController(title: "Please Get An Image", message: "Choose from below", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Camera", style: .Default, handler: {(action) -> Void in
self.imagePicker.sourceType = UIImagePickerControllerSourceType.Camera
self.presentViewController(self.imagePicker, animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "Photo Library", style: .Default, handler: {(action) -> Void in
self.imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(self.imagePicker, animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .Default, handler: {(action) -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
}))
self.presentViewController(alert, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
newImage = image
performSegueWithIdentifier("VC2", sender: self)
self.dismissViewControllerAnimated(true, completion: nil)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var secondViewController: VC2 = segue.destinationViewController as! VC2
secondViewController.imageView.image = newImage
}
}
I dont know Swift but I do know ObjC, so I will try to explain:
Class 2 .h :
#property (nonatomic, strong) UIImageView *myImageViewer;
Class 1 .m :
mySecondViewController.myImageViewer = [UIImageView new];
[mySecondViewController.myImageViewer setImage: newImage];
First you need to make the ImageView global to be able to access from other controllers. Then after you picked the newImage, you initialize memory to myImageViewer and give it the newImage you just picked, then load the viewController.
Hope this is what you needed to hear?