Right now I am able to have the user successfully take a picture using the camera and have their picture be uploaded into a imageview. However, if the user leaves that view controller when they eventually return the photo is no longer in that imageview. Is there anyway I am able to save the photo so that once a picture is taken and put into that imageview it is there until the user takes a different picture to replace it?
import UIKit
class ArsenalViewController: UIViewController,
UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var ball1: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func addPhoto1(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera){
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.camera
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
ball1.contentMode = .scaleToFill
ball1.image = pickedImage
}
picker.dismiss(animated: true, completion: nil)
}
First you need to save the image data somewhere (i.e. UserDefaults, Core Data, a database) and then retrieve it. UserDefaults is easy, try this:
//Encoding
let imageData:NSData = UIImageJPEGRepresentation(pickedImage!)! as NSData
//Saved image
UserDefaults.standard.set(imageData, forKey: "savedImage")
//Decode
if let data = UserDefaults.standard.object(forKey: "savedImage") as! NSData{
myImageView.image = UIImage(data: data as Data)
}
Encoding and saving image should happen right after updating your image and decoding should be done once the view has loaded all of its elements (viewDidAppear method).
After encoding and saving the image once, you can decode it anytime, even if the user left the VC and came back.
Related
I have a view that opens another view Controller as popover
the popover uses an image picker and displays the chosen image in an imageView.
The parent also has an imageView with an IBoutlet named profiler and before dismissing the popover i would like the parent view to get the chosen image.
How would i go about accessing parent and sending the image from the popover to the parent view
below is code from the popover view controller:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
picker.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: - Delegates
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
{
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage //2
myImageView.contentMode = .scaleAspectFit //3
myImageView.image = chosenImage //4
myImageView.layer.borderWidth = 1
myImageView.layer.masksToBounds = false
myImageView.layer.borderColor = UIColor.black.cgColor
myImageView.layer.cornerRadius = myImageView.frame.height/4
myImageView.clipsToBounds = true
dismiss(animated:true, completion: nil) //5
}
thanks for any help rendered
Use a callback closure, it's less effort than delegate/protocol
In the popover view controller add a property
weak var callback : ((UIImage) -> ())?
Call it in didFinishPickingMediaWithInfo before dismiss
callback?(chosenImage)
In the parent view controller after creating the controller add
popoverViewController.callback = { image in
// do something with the image
}
popoverViewController is the popover view controller instance
you should create protocol
protocol PopOverImagePickerDelegate: NSObjectProtocol {
func didSelect(image: UIImage)
}
inside your PopoverViewController create
weak var delegate: PopOverImagePickerDelegate?
before navigating to PopoverViewController from ParentViewController set
popOverViewController.delegate = self
and then create
extension ParentViewController: PopOverImagePickerDelegate {
func didSelect(image: UIImage) {
//do stuff
}
}
and when image picked inside PopoverViewController just call
self.delegate?.didSelect(image: image)
As a beginner in writing swift code, I am getting error in the following code:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = self.collectionView?.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! CollectionViewCell
// Configure the cell
let imageURL = NSURL(string: usersImageArray[indexPath.row])
print("The image url is \(imageURL)")
let imageData = NSData(contentsOf: imageURL as! URL)
cell.userImage.image = UIImage(data: imageData as! Data)
cell.userName.text = usersNameArray[indexPath.row]
return cell
}
The imageURL does contain an image url and the imageData does contain image Data but still I get "fatal error: unexpectedly found nil while unwrapping an Optional value"
I have seen and read other questions and answers and tried but still I can not find the problem. What exactly is causing the error though it does contain the URL and image data?
UPDATED:
My CollectionViewCell Class:
import UIKit
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var userImage: UIImageView!
#IBOutlet weak var userName: UILabel!
override func layoutSubviews() {
super.layoutSubviews()
self.makeImageRound()
}
func makeImageRound(){
self.userImage.layer.masksToBounds = true
self.userImage.layer.cornerRadius = self.userImage.frame.size.width/2.0
}
}
You have given the URL like this : optional(imageurl), it takes as it is , so you should avoid optional(. ) , to avoid this use '!' After userimagearray[indexpath.row]!
Try this and print imageurl and then see what happens
Try this
if imagedata == nil{
//give some image
}
else{
//give imagedata here
}
And take reuseidentifier = "cell"
Not cell whatever you take in a storyboard tableviewcell
i´m developing an app that has a lot of view controllers and did set the back ground image with code, but i have to copy and paste that block of code in every view controller, how can i type it once and call it to reuse the code in every view controller..Thanks A lot.
var imageView: UIImageView!
let image = UIImage(named: "backGroundImage.png")!
override func loadView() {
super.loadView()
self.imageView = UIImageView(frame: CGRectZero)
self.imageView.contentMode = .ScaleAspectFill
self.imageView.image = image
self.view.addSubview(imageView)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.imageView.frame = self.view.bounds
}
What you can do is make a parent UIViewController class and have all of your view controllers inherit from that class. Somethig like this:
class MyParentViewController: UIViewController {
var imageView: UIImageView!
let image = UIImage()
override func viewDidLoad() {
super.viewDidLoad()
self.imageView = UIImageView(frame: CGRectZero)
self.imageView.contentMode = .ScaleAspectFill
self.imageView.image = image
self.view.addSubview(imageView)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.imageView.frame = self.view.bounds
}
}
And then your child view controllers that enherit from this class would look something like this:
class MyViewController: MyParentViewController {
overide func viewDidLoad() {
image = UIImage(named:"My image name")
super.viewDidLoad()
}
}
Now, here is really the way you should do it
However, having multiple view controllers that are all the same probably isnt a good idea. I would just keep only the parent view controller (rename it obviously) and just change the value of "image" in the segue that leads to the view to whatever image you want. This would eliminate the need to have a ton of view controllers, and will make it easier to add more images in the future if you want.
Here's how I would do it:
protocol ImageViewBackground {
var backgroundImageView: UIImageView? {get set}
mutating func setBackgroundImage(image: UIImage)
}
extension ImageViewBackground where Self: UIViewController {
mutating func setBackgroundImage(image: UIImage) {
let backgroundImageView = self.backgroundImageView ?? setupImageView()
backgroundImageView.image = image
}
mutating func setupImageView() -> UIImageView {
let imageView = UIImageView(frame: self.view.frame)
imageView.contentMode = .ScaleAspectFill
view.addSubview(imageView)
backgroundImageView = backgroundImageView
return imageView
}
}
Then just make any UIViewController adhere to the protocol like so:
class ViewController: UIViewController, ImageViewBackground {
var backgroundImageView: UIImageView?
}
Then you can call setBackgroundImage from anywhere in your VC without having to make a generic subclass just for the background image.
My code:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
self.image = image
self.imageStatusLabel.text = "There is a picture"
self.imageStatusLabel.textColor = UIColor.blue()
picker.dismiss(animated: true, completion: nil)
}
And this is the error:
Cannot override 'imagePickerController' which has been marked unavailable: APIs deprecated as of iOS 7 and earlier are unavailable in Swift
Well, I've tried to use the newer function:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
// But no image in the parameters
}
But then, there is no image in the parameters and I can get the image.
What should I do?
You have to use the info parameter and make a cast to UIImage. Don't forget that you have to put a "Privacy - Photo Library Usage Description" and a "Privacy - Camera Usage Description" in the info.plist file and fill the values with a string explaining the reason for request the access to photo library and camera.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
pictureImageView.contentMode = .scaleToFill
pictureImageView.image = pickedImage
}
picker.dismiss(animated: true, completion: nil)
}
To use imagePickerController in Swift3 you need add a row with key: Privacy - Photo Library Usage Description and value is a string (e.g: "Access to your photos") to Info.plist file and let's try below:
class YourController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let imagePickerButton: UIButton = {
let btn = UIButton(frame: CGRect(x: 10, y: 10, width: 100, height: 100))
btn.setTitle("Choose a Photo", for: .normal)
btn.setTitleColor(.white, for: .normal)
btn.backgroundColor = .blue
btn.addTarget(self, action: #selector(handlePickerDidTap), for: .touchUpInside)
return btn
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(imagePickerButton)
}
func handlePickerDidTap() {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.allowsEditing = true
present(imagePickerController, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
print("photo is selected")
// do some thing here
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
}
Hope it help!
You get the image from the passed info dictionary, see the keys in the documentation
You probably want either
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
or
let image = info[UIImagePickerControllerEditedImage] as? UIImage
import UIKit
import Photos
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var imageView: UIImageView!
#IBAction func selectPhotoLibrary(_ sender: Any) {
let picker = UIImagePickerController()
picker.delegate = self
if UIImagePickerController.isSourceTypeAvailable(.camera) {
picker.sourceType = .camera
} else{
print("Kamera desteklenmiyor.")
}
present(picker, animated: true, completion:nil)
}
#IBAction func selectPhotoCamera(_ sender: Any) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .photoLibrary
present(picker, animated: true, completion:nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
picker.dismiss(animated: true, completion:nil)
guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else { return }
guard let imageData = UIImageJPEGRepresentation(image, 0.8) else { return }
self.imageView.image = image
print(imageData)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion:nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Read more for usage detail --> https://medium.com/#yakupad/swift-uiimagepickercontroller-kullanımı-91771ed4c1d6
I am calling to all swift developers here. I am struggling last 3 days with this topic. Is there a way to pick an image from image picker (local photo library of iPhone) and upload it to server? I can't figure out how to do this....just tons of outdated code or nothin.
You should try to use a UIImagePickerController like this
#IBAction func takePhoto(sender: UIButton) {
let picker = UIImagePickerController()
picker.delegate = self;
picker.allowsEditing = true;
picker.sourceType = .PhotoLibrary;
self.presentViewController(picker animated:true completion:nil);
}
Then you can get the image in imagePickerController(_:didFinishPickingMediaWithInfo:) method from UIImagePickerControllerDelegate
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let chosenImage = info[UIImagePickerControllerEditedImage] as! UIImage
UploadImage(chosenImage)
picker.dismissViewControllerAnimated(true, completion: nil);
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
picker.dismissViewControllerAnimated(true, completion: nil);
}
Finally you upload the image. Example using HTTP POST Check this answer
function UploadImage(image : UIImage) {
var imageData = UIImagePNGRepresentation(image)
if imageData == nil {
print("image not valid")
return
}
// Upload
....
}
Note This answer is directly written in the reply, please change any invalid code.