Swift UIButton background image not being set by UIImagePicker - swift

I am able to select an Image from the PhotoLibrary but the background image of my UIButton does not change. The println in didFinishPickingImage and imagePickerControllerDidCancel does not show in the console so I do not think those functions are being called.
class AddTeamTableViewController: UITableViewController, UITextFieldDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIAlertViewDelegate {
var picker:UIImagePickerController? = UIImagePickerController()
#IBOutlet var teamNumber: UITextField!
#IBOutlet var schoolName: UITextField!
#IBOutlet var teamImage: UIButton!
#IBAction func cancelButton(sender: AnyObject) {
dismissViewControllerAnimated(true, completion: nil)
}
#IBAction func addTeam(sender: AnyObject) {
var newTeam = Team()
var onlineTeam = PFObject(className: "Team")
// add new team to the list
newTeam.name = teamNumber.text
newTeam.schoolName = schoolName.text
teamList.append(newTeam)
// add online
onlineTeam["name"] = newTeam.name
onlineTeam["fromUser"] = PFUser.currentUser()
onlineTeam["schoolName"] = newTeam.schoolName
onlineTeam.save()
//close the view
dismissViewControllerAnimated(true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return 1
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true;
}
#IBAction func pickImage(sender: AnyObject) {
var image = UIImagePickerController()
image.delegate = self
var alert:UIAlertController = UIAlertController(title: "Choose Image", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
var cameraAction = UIAlertAction(title: "Camera", style: UIAlertActionStyle.Default) {
UIAlertAction in
self.openCamera()
}
var galleryAction = UIAlertAction(title: "Gallery", style: UIAlertActionStyle.Default) {
UIAlertAction in
self.openGallery()
}
var cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) {
UIAlertAction in
}
alert.addAction(cameraAction)
alert.addAction(galleryAction)
alert.addAction(cancelAction)
self.presentViewController(alert, animated: true, completion: nil)
/*
alert.delegate = self
alert.message = "Choose Image Source"
alert.addButtonWithTitle("Camera")
alert.addButtonWithTitle("Photo Library")
alert.show()
*/
//image.sourceType = UIImagePickerControllerSourceType.Camera
//image.allowsEditing = false
//self.presentViewController(image, animated: true, completion: nil)
}
func openCamera() {
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)) {
picker!.sourceType = UIImagePickerControllerSourceType.Camera
self.presentViewController(picker!, animated: true, completion: nil)
} else {
openGallery()
}
}
func openGallery() {
picker!.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(picker!, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
println("Image selected")
self.dismissViewControllerAnimated(true, completion: nil)
teamImage.setBackgroundImage(image, forState: UIControlState.Normal)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController!) {
println("picker cancel")
}
}

The button doesn't seem initialized
let teamImage: UIButton = UIButton(frame: CGRect(x: 0, y: 0, width: 380, height: 300))
let imageTest = UIImage(named: "Hypnotoad")
teamImage.setTitle("HypnotoadTitle", forState: .Normal)
teamImage.setBackgroundImage(imageTest, forState: .Normal)
tested this in a Playground and works ok.

I figured it out. I had 2 different variables of type UIImagePickerController and I was saving to the wrong one. I deleted the first var picker declaration and combined the code to just one UIImagePickerController and it works as intended.

Related

Error in Table View Controller When using a segue Fatal error: Index out of range

I've ran into a problem and i cant resolve it
TableViewController:
var items: [String?] = ["door","table","chair"]
var givenDescription: [String?] = ["Change the description using
class TableViewController: UITableViewController, UIToolbarDelegate {
the edit option"]
#IBOutlet var myTableView: UITableView!
override func viewDidAppear(_ animated: Bool) {
myTableView.reloadData()
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
cell.textLabel?.text = items[indexPath.row]
cell.detailTextLabel?.text = givenDescription[indexPath.row]
return cell
}
ViewController:
import UIKit
import MobileCoreServices
class AddViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var newPic: Bool?
//Outlets
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var addName: UITextField!
#IBOutlet weak var addDescription: UITextField!
#IBAction func addImage(_ sender: Any) {
let myAlert = UIAlertController(title: "Select Image From", message: "", preferredStyle: .actionSheet)
let cameraAction = UIAlertAction(title: "Camera", style: .default, handler: nil)
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.camera
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
self.newPic = true
}
let cameraRoll = UIAlertAction(title: "Camera Roll", style: .default, handler: nil)
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
self.newPic = false
}
myAlert.addAction(cameraAction)
myAlert.addAction(cameraRoll)
self.present(myAlert, animated: true)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let mediaType = info[UIImagePickerControllerMediaType] as! NSString
if mediaType.isEqual(to: kUTTypeImage as String) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
imageView.image = image
if newPic == true {
UIImageWriteToSavedPhotosAlbum(image, self, #selector(imageError), nil)
}
}
self.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.dismiss(animated: true, completion: nil)
}
#objc func imageError(image: UIImage, didFinishSavingWithError error: NSErrorPointer, contextInfo:UnsafeRawPointer) {
if error != nil {
let alert = UIAlertController(title: "Save Failed", message: "Failed to save image", preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "Okay", style: .cancel, handler: nil)
alert.addAction(cancelAction)
self.present(alert, animated: true, completion: nil)
}
}
//Action
#IBAction func create(_ sender: Any) {
if (addName.text != "") {
items.append(addName.text!)
addName.text = ""
}
if (addDescription.text != "") {
givenDescription.append(addDescription.text!)
addDescription.text = ""
}
self.navigationController?.popViewController(animated: true)
}
}
You can "fix" the create function in several ways, for example like this:
#IBAction func create(_ sender: Any) {
if (addName.text != "" && addDescription.text != "") {
items.append(addName.text!)
addName.text = ""
givenDescription.append(addDescription.text!)
addDescription.text = ""
}
self.navigationController?.popViewController(animated: true)
}
but a much better option is to create a simple struct
struct Item {
var name: String
var itemDescription: String
}
and use it instead
#IBAction func create(_ sender: Any) {
if (addName.text != "" && addDescription.text != "") { //or just check one depending on if one is more important
let item = Item(name: addName.text!, itemDescription: addDescription.text!)
items.append(item)
}
self.navigationController?.popViewController(animated: true)
}
and the items array is defined as
var items: [Item]()
andd for your table view
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
let item = items[indexPath.row]
cell.textLabel?.text = item.name
cell.detailTextLabel?.text = item.itemDescription
return cell
}
This was the answer so simple.
#IBAction func create(_ sender: Any) {
if (addName.text != "" && addDescription.text != "") {
items.append(addName.text!)
addName.text = ""
givenDescription.append(addDescription.text!)
addDescription.text = ""
}
self.navigationController?.popViewController(animated: true)
}

Swift Unexpectedly found nil while unwrapping an Optional value while pass image to another ViewController

I have two VCs. The first one contains an imagePicker from gallery and a callback function that sends and image to the chatLog... I want to send the selected photo to the 2nd VC
if let selectedImage = selectedImageFromPicker {
//self.callback?(selectedImage)
detailImageViewController.aImage = selectedImage
}
I created the 2nd VC as controller for PreviewImage with buttons cancel or accept. I tried to pass the image displayed on the 2nd VC back to 1st VC this way but it shows me:
Fatal error: Unexpectedly found nil while unwrapping an Optional value.
How can I fix that?
var t : EVTPhotoTekingHelper!
#objc func actionSend() {
if aImage != nil{
t.callback?(aImage!)
}
else {
print("nil")
}
dismiss(animated: true, completion: nil)
}
UPDATED:
My 1st VC
typealias PhotoTekingHelperCallBack = (UIImage?) -> ()
class EVTPhotoTekingHelper: NSObject {
// View controller on which AlertViewController and UIImageViewController are present
weak var viewController: UIViewController!
var imagePickerController: UIImagePickerController?
var callback: PhotoTekingHelperCallBack?
var photoTakinHelper: EVTPhotoTekingHelper!
// MARK: - Initialization
init(viewController: UIViewController, callback: #escaping PhotoTekingHelperCallBack) {
self.viewController = viewController
self.callback = callback
super.init()
showPhotoSourceSelection()
}
func showPhotoSourceSelection() {
let alertController = UIAlertController.init(title: nil,
message: "Message?",
preferredStyle: .actionSheet)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
let photoLibraryAction = UIAlertAction(title: "from library", style: .default) { (action) in
self.showImagePickerController(sourceType: .photoLibrary)
}
alertController.addAction(cancelAction)
alertController.addAction(photoLibraryAction)
if UIImagePickerController.isFlashAvailable(for: .rear) {
let cameraAction = UIAlertAction.init(title: "from camera", style: .default, handler: { (action) in
self.showImagePickerController(sourceType: .camera)
})
alertController.addAction(cameraAction)
}
viewController.present(alertController, animated: true, completion: nil)
}
func showImagePickerController(sourceType: UIImagePickerControllerSourceType) {
imagePickerController = UIImagePickerController.init()
imagePickerController!.sourceType = sourceType
imagePickerController!.delegate = self
viewController.present(imagePickerController!, animated: true, completion: nil)
}
}
Extension from 1st VC
extension EVTPhotoTekingHelper: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var selectedImageFromPicker: UIImage?
if let editedImage = info[UIImagePickerControllerEditedImage] as? UIImage {
selectedImageFromPicker = editedImage
} else if let originImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
selectedImageFromPicker = originImage
}
let detailImageViewController = EVImagePreviewController()
let ncDetailImageViewController = UINavigationController(rootViewController: detailImageViewController)
if let selectedImage = selectedImageFromPicker {
//self.callback?(selectedImage)
detailImageViewController.aImage = selectedImage
}
viewController.dismiss(animated: false, completion: nil)
viewController.parent?.present(ncDetailImageViewController, animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
viewController.dismiss(animated: false, completion: nil)
}
}
My 2nd VC
class EVImagePreviewController: UIViewController, UIScrollViewDelegate {
var t : EVTPhotoTekingHelper!
var aImageView: UIImageView!
var aImage: UIImage!
private var aScrollView: UIScrollView!
override func viewDidAppear(_ animated: Bool) {
aImageView = UIImageView(frame: CGRect(x: 0, y: 75, width: (aImage?.size.width)!, height: (aImage?.size.height)!))
aImageView.contentMode = .scaleAspectFit
aImageView.image = aImage
aScrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height))
aScrollView.backgroundColor = .clear
aScrollView.contentSize = CGSize(width: view.frame.size.width, height: view.frame.height)
aScrollView.minimumZoomScale = 0.2
aScrollView.maximumZoomScale = 2.3
aScrollView.clipsToBounds = true
aScrollView.delegate = self
aScrollView.addSubview(aImageView)
view.addSubview(aScrollView)
aImageView.center = CGPoint(x: aScrollView.bounds.midX, y: aScrollView.bounds.midY - 35)
}
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Add", style: .plain, target: self, action: #selector(actionSend))
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(actionBack))
}
// MARK: - IBAction
#objc func actionBack() {
dismiss(animated: false, completion: nil)
}
#objc func actionSend() {
print("\(t)")
if aImage != nil{
t.callback?(aImage!)
}
else {
print("nil")
}
//self.callback?(aImage)
dismiss(animated: true, completion: nil)
}
// MARK: - UIScrollViewDelegate
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return aImageView
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
let subView = scrollView.subviews[0]
let offsetX = max((scrollView.bounds.width - scrollView.contentSize.width) * 0.5, 0.0)
let offsetY = max((scrollView.bounds.height - scrollView.contentSize.height) * 0.5, 0.0)
subView.center = CGPoint(x: scrollView.contentSize.width * 0.5 + offsetX, y: scrollView.contentSize.height * 0.5 + offsetY)
}
}
Here you dismiss your first view controller before you present your 2nd one from the parent of your first view controller:
viewController.dismiss(animated: false, completion: nil)
To me so far doesn't make sense. Its not clear where is the callback implementation is.
My guess that the nil exception is not for the UIImage for sure. its somewhere
inside your callback implementation.

How to pass the variable from a ViewController Class to other Struct?

I have no idea how to pass the data from the class to another struct. This is my ViewController.swift file. And I have another file called Meme.swift which is used to save the struct. I tried to put the struct in ViewController.swift file as well as Meme.swift file but I cannot access the value like topTextField.text and lowTextField.text and use them in the struct. Can anyone help me with this?
ViewController:
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UITextFieldDelegate {
#IBOutlet weak var cameraButton: UIBarButtonItem!
#IBOutlet weak var bottomTextField: UITextField!
#IBOutlet weak var topTextField: UITextField!
#IBOutlet weak var imagePickerView: UIImageView!
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var actionButton: UIBarButtonItem!
let bottomTextFieldDelegate = BottomTextFieldDelegate()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
topTextField.text = "TOP"
bottomTextField.text = "BOTTOM"
topTextField.delegate = self
bottomTextField.delegate = self.bottomTextFieldDelegate
}
func textFieldDidBeginEditing(_ textField: UITextField) {
topTextField.text = ""
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.view.endEditing(true)
textField.resignFirstResponder()
actionButton.isEnabled = true
return true
}
#IBAction func shareAction(_ sender: Any) {
let image = generateMemedImage()
let controller = UIActivityViewController(activityItems: [image as Any], applicationActivities: nil)
self.present(controller, animated: true, completion: nil)
controller.completionWithItemsHandler = {(activityType: UIActivityType?, completed:Bool, returnedItems:[Any]?, error: Error?) in
if !completed {
debugPrint("cancelled")
return
}else{
self.save()
self.dismiss(animated: true, completion: nil)
}
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
cameraButton.isEnabled = UIImagePickerController.isSourceTypeAvailable(.camera)
configureTextField(textField: topTextField)
configureTextField(textField: bottomTextField)
topTextField.textAlignment = .center
bottomTextField.textAlignment = .center
subscribeToKeyboardNotifications()
actionButton.isEnabled = false
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
unsubscribeFromKeyboardNotifications()
}
func configureTextField(textField: UITextField) {
textField.defaultTextAttributes = memeTextAttributes
}
func save() -> Meme {
// Create the meme
let memedImage = generateMemedImage()
let meme = Meme(topText: topTextField.text!, bottomText: bottomTextField.text!, originalImage: imageView.image!, memedImage: memedImage)
return meme
}
func generateMemedImage() -> UIImage {
// TODO: Hide toolbar and navbar
navigationController?.setToolbarHidden(true, animated: true)
self.navigationController?.isNavigationBarHidden = true
// Render view to an image
UIGraphicsBeginImageContext(self.view.frame.size)
view.drawHierarchy(in: self.view.frame, afterScreenUpdates: true)
let memedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
// TODO: Show toolbar and navbar
navigationController?.setToolbarHidden(false, animated: false)
self.navigationController?.isNavigationBarHidden = false
return memedImage
}
func keyboardWillShow(_ notification:Notification) {
view.frame.origin.y = 0 - getKeyboardHeight(notification)
}
func keyboardWillHide(_ notification:Notification) {
view.frame.origin.y = 0
}
func getKeyboardHeight(_ notification:Notification) -> CGFloat { //getting the height of keyboard and use it for func keyboardWillShow to relocate
//the keyboard using keyboardWillShow function
let userInfo = notification.userInfo
let keyboardSize = userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue // of CGRect
return keyboardSize.cgRectValue.height
}
func subscribeToKeyboardNotifications() { //setting up the obeserver to be notified when keyboard is shown or not, then execute keyboardWillShow function
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: .UIKeyboardWillHide, object: nil)
}
func unsubscribeFromKeyboardNotifications() { //unsubscribe the notification
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
}
//setting the arributes of the text
let memeTextAttributes:[String:Any] = [
NSStrokeColorAttributeName: UIColor.black,
NSForegroundColorAttributeName: UIColor.white,
NSFontAttributeName: UIFont(name: "HelveticaNeue-CondensedBlack", size: 40)!,
NSStrokeWidthAttributeName: 3,]
#IBAction func pickAnImageFromAlbum(_ sender: Any) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
present(imagePicker, animated: true, completion: nil)
}
#IBAction func pickAnImageFromCamera(_ sender: Any) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .camera
present(imagePicker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
imagePickerView.image = image
imagePickerView.contentMode = .scaleAspectFit
dismiss(animated: true, completion: nil)
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController){
dismiss(animated: true, completion: nil)
}
}
BottomFieldDelegate:
import Foundation
import UIKit
class BottomTextFieldDelegate: NSObject, UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
textField.text = ""
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
let viewController = ViewController()
textField.resignFirstResponder()
viewController.view.endEditing(true)
let actionButton = viewController.actionButton
actionButton?.isEnabled = true
return true
}
}
First u need to move this function like save() and generateMemedImage() into your ViewController class and then you can access topTextField.text and lowTextField.text
Modify your struct like below, and do not put nsobject in struct
struct Meme {
var topText: String
var bottomText: String
var memedImage: UIImage
var originalImage: UIImage
init(topText: String, bottomText: String, originalImage: UIImage, memedImage: UIImage) {
self.topText = topText
self.bottomText = bottomText
self.originalImage = originalImage
self.memedImage = memedImage
}
}
Remove save() from Meme struct and put that code in your Viewcontroller file.
Modify your function which return Meme struct object.
func save() -> Meme {
// Create the meme
let meme = Meme(topText: topTextField.text!, bottomText: bottomTextField.text!, originalImage: imageView.image!, memedImage: memedImage)
return meme
}
And you can store in Array like below.
let array:[Meme] = []
array.append(save())

Update a collection view in an other view

For school I have to make an iOS application. I would like to use an UICollectionView in an other View. I use the following code, but when I use self.libraryCollectionView.reloadData(), the collectionView function is not called. The CollectionView with the name libraryCollectionView should hold an gallery of Images.
Here you can see the code I wrote.
import UIKit
class CoverViewController: UIViewController, UICollectionViewDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UICollectionViewDataSource {
// MARK: Properties
#IBOutlet weak var photoImageView: UIImageView!
#IBOutlet weak var typeLabel: UILabel!
#IBOutlet weak var libraryCollectionView: UICollectionView!
var cover: Cover?
var images = [UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
// Set up views if editing an existing Cover.
if let cover = cover {
photoImageView.image = cover.image
typeLabel.text = cover.type
}
libraryCollectionView.delegate = self
libraryCollectionView.dataSource = self
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
#IBAction func addImage(_ sender: UIBarButtonItem) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet);
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: { (action) in
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.sourceType = .camera
self.present(imagePicker, animated: true, completion: nil)
}
}))
alert.addAction(UIAlertAction(title: "Photo Library", style: .default, handler: { (action) in
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
imagePicker.sourceType = .photoLibrary
self.present(imagePicker, animated: true, completion: nil)
}
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
// Methods for ImagePicker
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
images.append(pickedImage)
DispatchQueue.main.async{
self.libraryCollectionView.reloadData()
}
}
dismiss(animated: true, completion: nil)
}
// Methods for CollectionView
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 0
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cellIdentifier = "cell"
let cell = libraryCollectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! ImageCellView
NSLog(String(images.count))
cell.photoImageView.image = images[indexPath.row]
return cell
}
}
numberOfSections(in collectionView: UICollectionView) should return at least 1.
It's default value is also 1, so you can just delete the whole method from your code.

How do I segue an image to another ViewController and display it within an ImageView?

The following code allows the user to select an image from the gallery or to take a picture and displays it within the ViewController via ImageView. What I want to do here is to pass the image that was taken or selected from the gallery and pass it to another ViewController to which it gets displayed in an ImageView. Ideally once the picture is selected or taken the ViewController changes immediately to the Second ViewController and displays the image in the ImageView.
How can this be achieved? thanks.
import Foundation
import UIKit
import MobileCoreServices
import AssetsLibrary
import AVFoundation
import SystemConfiguration
class ViewController: UIViewController, UITextViewDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextFieldDelegate, UIPopoverControllerDelegate, UIAlertViewDelegate {
var controller = UIImagePickerController()
var assetsLibrary = ALAssetsLibrary()
var selectedImage = UIImageView ()
private var image: UIImage? // THIS ONE
#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
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#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: "Gallery", 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
image = imageView.image!
performSegueWithIdentifier("TEST", sender: self)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController)
{
print("picker cancel.")
}
}
Here is my second ViewController
import UIKit
class ViewController2: UIViewController {
var Image = UIImage ()
#IBOutlet var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = Image
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Edit 2
Given that you have too many mistakes in your code, I'm going to a bit more specific.
First: You need to understand the difference between UIImage and UIImageView
Second: If you want to perform segue after the user selects an image, you should call the method on the didFinishPickingMediaWithInfo delegate, like this:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
{
picker .dismissViewControllerAnimated(true, completion: nil)
imageView.image=info[UIImagePickerControllerOriginalImage] as? UIImage
image = imageView.image!
performSegueWithIdentifier("mySegueToNextViewController", sender: self)
}
Also, I added a new property called "image" (should be called "selectedImage", but you can change it later).
private var image: UIImage? // THIS ONE
#IBOutlet weak var btnClickMe: UIButton!
#IBOutlet weak var imageView: UIImageView!
Third: On the ViewController2 you need to set the image library to the UIImageView.
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = selectedImage
}
Finally: In the Storyboard, select ViewController, go to editor -> Embed In -> Navigation Controller.
Now, should work just fine.
Once you select the image, call the following method:
performSegueWithIdentifier("mySegueToNextViewController", sender: self)
Then you need to implement:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "mySegueToNextViewController" {
if let nextViewController = segue.destinationViewController as? NextViewController {
nextViewController.image = selectedImage
}
}
}
Keep in mind that for this to work, you should have public property on NextViewController (just like Unis Barakat said).
Then on the NextViewController viewDidLoad() you could set the image to the imageView.
Hope this helps!
on top of class define a variable, something like:
var selectedImage: UIImage
then when you are in that view controller set that image and in the other view controller, you simply display the image that you set in the first controller.