No problems when there should be on Apple iOS Development Guide - ios

I've started today to start learn development for iOS using Apple's Official Guide for Swift Development.
I've reached to Work with View Controllers. A bit before the end of the page there is a checkpoint, where I should run the app on the simulator and when I click the Image View, I supposed to get SIGABRT error because I don't have permissions to show images.
Not only that I don't get any error messages, nothing happens at all when I click the Image View.
I've checked 3 times all over the files to make sure I didn't missed anything. I even created a new project to make sure everything was fine, but still, it doesn't work.
ViewController.swift:
import UIKit
class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
//MARK: Properties
#IBOutlet weak var nameTextField: UITextField!
#IBOutlet weak var mealNameLabel: UILabel!
#IBOutlet weak var photoImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Handle the text field's user input through delegate callbacks.
nameTextField.delegate = self
}
//MARK: UITextFieldDelegate
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// Hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
mealNameLabel.text = textField.text
}
//MARK: UIImagePickerControllerDelegate
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
// Dismiss the picker if the user canceled.
dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// The info dictionary may contain multiple representations of the image. You want to use the original.
guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
// Set photoImageView to display the selected image.
photoImageView.image = selectedImage
// Dismiss the picker.
dismiss(animated: true, completion: nil)
}
//MARK: Actions
#IBAction func selectImageFromPhotoLibrary(_ sender: UITapGestureRecognizer) {
// Hide the keyboard.
nameTextField.resignFirstResponder()
// UIImagePickerController is a view controller that lets a user pick media from their photo library.
let imagePickerController = UIImagePickerController()
// Only allow photos to be picked, not taken.
imagePickerController.sourceType = .photoLibrary
// Make sure ViewController is notified when the user picks an image.
imagePickerController.delegate = self
present(imagePickerController, animated: true, completion: nil)
}
#IBAction func setDefaultLabelText(_ sender: UIButton) {
mealNameLabel.text = "Default Text"
}
}
Main.storyboard:
Can you please help me solve it?

This error should occur when you are trying to access the camera roll without permission to do so.
iOS 10 requires that you add a description as to why you want access to the camera roll. This needs to be added in the info.plist file with the key Privacy - Photo Library Usage Description
If you are not getting this error, I would guess that you have already entered this information in the plist file our are running on an older version of iOS? or the code to access the camera roll is not actually firing, you may need to tap on screen or press a button to initiate the code.

I was using a Tap Gesture Recognizer that I placed on a UIImage using Storyboard.
To get this to work I also had to place a checkmark in the block labeled: "User Interaction Enabled" in the UIImage's Attributes Inspector in the Storyboard.

Related

Touched not working in Xcode simulator (apple official tutorial 'FoodTracker')

I'm working on an official Apple tutorial to learn iOS.
But I did the same, but the touch does not work in the simulator.
I tried turning Xcode off and on and copying and pasting the example file but it still doesn't touch. Or is there anything else you should try?
I need help.
import UIKit
class ViewController: UIViewController, UITextFieldDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
// MARK: Properties
#IBOutlet weak var nameTextField: UITextField!
#IBOutlet weak var mealNameLabel: UILabel!
#IBOutlet weak var photoimageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Handle the text field’s user input through delegate callbacks.
nameTextField.delegate = self
}
//MARK: UITextFieldDelegate
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// Hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
mealNameLabel.text = textField.text
}
//MARK: UIImagePickerControllerDelegate
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
// Dismiss the picker if the user canceled.
dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// The info dictionary may contain multiple representations of the image. You want to use the original.
guard let selectedImage = info[UIImagePickerController.InfoKey.originalImage] as?
UIImage else {
fatalError("Expected a dictionary containing an image, but was provided folowing: \(info)")
}
// Set photoImageView to display the selected image.
photoimageView.image = selectedImage
// dismiss picker
dismiss(animated: true, completion: nil)
}
// MARK: Actions
#IBAction func selectImageFromPhotoLibrary(_ sender: UITapGestureRecognizer) {
// Hide the keyboard.
nameTextField.resignFirstResponder()
// UIImagePickerController is a view controller that lets a user pick media from their photo library.
let imagePickerController = UIImagePickerController()
// Only allow photos to be picked, not taken.
imagePickerController.sourceType = .photoLibrary
// Make sure ViewController is notified when the user picks an image.
imagePickerController.delegate = self
present(imagePickerController, animated: true, completion: nil)
}
#IBAction func setDefaultLabelText(_ sender: UIButton) {
mealNameLabel.text = "Default Text"
}
}
You should add isUserInteractionEnabled as true with Storyboard and add Tap Gesture Recognizer and link (or update this link) #IBAction func selectImageFromPhotoLibrary with Storyboard

This class is not key value coding-compliant for the key cancel

I keep getting this error: Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<FoodTracker.MealViewController 0x7faa9ed189d0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key cancel.'
I'm trying to complete the Apple developer guide to getting started with iOS apps. My code and storyboard looks exactly like theirs does in the example file. I'm hoping that a fresh eye might be able to see something I am not?
import UIKit
import os.log
class MealViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
//MARK: Properties
#IBOutlet weak var nameTextField: UITextField!
#IBOutlet weak var photoImageView: UIImageView!
#IBOutlet weak var ratingControl: RatingControl!
#IBOutlet weak var saveButton: UIBarButtonItem!
/*
This value is either passed by 'MealTableViewController' in
'prepare(for:sender) or constructed as part of adding a new meal.
*/
var meal: Meal?
override func viewDidLoad() {
super.viewDidLoad()
// Handle the text field's user input through delegate callbacks
nameTextField.delegate = self
// Enable save button only if text field has valid Meal name
updateSaveButtonState()
}
//MARK: UITextFieldDelegate
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// Hide the keyboard
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
updateSaveButtonState()
navigationItem.title = textField.text
}
func textFieldDidBeginEditing(_ textField: UITextField) {
// Disable save button while editing
saveButton.isEnabled = false
}
//MARK: UIImagePickerControllerDelegate
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
// Dismiss the picker if the user canceled
dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// The info dictionary may contain multiple representations of the image. You want to use the original.
guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
// Set photoImageView to display the selected image
photoImageView.image = selectedImage
// Dismiss the picker
dismiss(animated: true, completion: nil)
}
//MARK: Navigation
#IBAction func cancel(_ sender: UIBarButtonItem) {
dismiss(animated: true, completion: nil)
}
// Configure view controller before it's presented
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
// Configure destination view controller only when save button pressed
guard let button = sender as? UIBarButtonItem, button === saveButton else {
os_log("The save button was not pressed, cancelling", log: OSLog.default, type: .debug)
return
}
let name = nameTextField.text ?? ""
let photo = photoImageView.image
let rating = ratingControl.rating
// Set meal to be passed to MealTableViewController after unwind segue
meal = Meal(name: name, photo: photo, rating: rating)
}
//MARK: Actions
#IBAction func selectImageFromPhotoLibrary(_ sender: UITapGestureRecognizer) {
// Hide the keyboard
nameTextField.resignFirstResponder()
// UIImagePickerController is a view controller that lets a user pick media from their photo library
let imagePickerController = UIImagePickerController()
// Only allow photos to be picked, not taken
imagePickerController.sourceType = .photoLibrary
// Make sure ViewController is notified when the user picks an image
imagePickerController.delegate = self
present(imagePickerController, animated: true, completion: nil)
}
//MARK: Private Methods
private func updateSaveButtonState() {
// Disable the save button if the text field is empty
let text = nameTextField.text ?? ""
saveButton.isEnabled = !text.isEmpty
}
}
There are a few other files, but please just let me know what you need because I am very new to Swift/XCode and not sure what to provide/not provide.
This means that you have something on your storyboard connected to the IBOutlet called cancel but you don't have this IBOutlet in your class. So compiler can't find Key cancel(it means property) in your class. You should find that button(i think it's a UIButton because of the name) in storyboard, click right mouse button on it and click "x" to delete that connection. Or you might want to delete this button at all. Or you might want to add this IBOutlet to your class.
I agree with what Alex Shubin mentioned in his answer, an actionable solution like “look for any connections that don’t exist anymore and delete them”. I was having the same issue and his suggestion fixed that bug. For those who are new to programming, and Xcode like me, a little more information on how to locate the x button in storyboard might be helpful.
Click on the yellow circle at the top of the view controller in storyboard.
Then show the connections inspector in the upper right of the utilities bar. The connections inspector is the menu on the far right, a circle with a right pointing arrow. Click that, and you should see all the connections for that view controller.
I'm including a screen shot of what that looks like in my app.
Check for the module name under "Identity Inspector". Either module name has to be selected or "Inherit Module from Target" has to be checked. If there are multiple modules, select the appropriate one.

Following iOS Tutorial - Cannot get image picker to display

So I'm new to iOS Development and I'm finally onto this step: https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/WorkWithViewControllers.html#//apple_ref/doc/uid/TP40015214-CH6-SW1
I've followed the guide step-by-step and for some reason, when I run my app, I click on the Image View and nothing pops up. My code is exactly like Apple's with the exception of nameTextField being businessNameTextField and businessNameLabel. Here's my ViewController.swift file
//
// ViewController.swift
// Example (Sample 1)
//
// Created by lewlsaucengravy on 4/9/17.
// Copyright © 2017 Example. All rights reserved.
//
import UIKit
class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
//MARK: Properties
#IBOutlet weak var businessNameLabel: UILabel!
#IBOutlet weak var businessTextField: UITextField!
#IBOutlet weak var photoImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
businessTextField.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: UITextFieldDelegate
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// Hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
businessNameLabel.text = textField.text
}
//MARK: UIImagePickerControllerDelegate
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
// Dismiss the picker if user cancelled.
dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// The info dictionary may contain multiple representations of the image. You want to use the original.
guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
// Set photoImageView to display the selected image.
photoImageView.image = selectedImage
// Dismiss the picker.
dismiss(animated: true, completion: nil)
}
//MARK: Actions
#IBAction func completeProfile(_ sender: UIButton) {
businessNameLabel.text = "test"
}
#IBAction func selectImageFromPhotoLibrary(_ sender: UITapGestureRecognizer) {
// Hide the keyboard.
businessTextField.resignFirstResponder()
// UIImagePickerController is a view controller that lets a user pick media from their photo library.
let imagePickerController = UIImagePickerController()
// Only allow photos to be picked, not taken.
imagePickerController.sourceType = .photoLibrary
// Make sure ViewController is notified when the user picks an image.
imagePickerController.delegate = self
present(imagePickerController, animated: true, completion: nil)
}
}
My AppDelegate.swift file is is the default when creating the project, so nothing to show there.
Here's the Main.storyboard:
I'm trying to avoid just deleting the app and starting over because I want to get in the habit of troubleshooting and learning what I'm doing wrong.
From what I understand, and feel free to correct me if I'm wrong, when the user clicks on the Image View, it's calling the selectImageFromPhotoLibrary function from which I've defined under Actions, and everything is supposed to go from there.
Edit
It looks like the issue may have been the "User Interaction Enabled" checkbox that I forgot to check. It's the only thing I changed since posting the question and apparently it's working now.
Ensure the User Interaction Enabled checkbox is checked:
From what I am thinking, you did not have set the following parameters in your plist:

Swift tutorial foodtracker: tap gesture method not called

I am playing around with the apple swift tutorial for the Foodtracker and try to open now the Photo library with the tap gesture.
//
// ViewController.swift
// FoodTracker
//
import UIKit
class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
// MARK: Properties
#IBOutlet weak var nameTextField: UITextField!
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var mealPhotoView: UIImageView!
// MARK: UIImagePickerControllerDelegate
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
// Dismiss the picker if the user canceled.
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
// The info dictionary contains multiple representations of the image, and this uses the original.
let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
// Set photoImageView to display the selected image.
mealPhotoView.image = selectedImage
// Dismiss the picker.
dismissViewControllerAnimated(true, completion: nil)
}
// MARK: Actions
#IBAction func selectImageFromPhotoLibrary(sender: UITapGestureRecognizer) {
print("selectImage called!")
// Hide the keyboard.
nameTextField.resignFirstResponder()
// UIImagePickerController is a view controller that lets a user pick media from their photo library.
let imagePickerController = UIImagePickerController()
// Only allow photos to be picked, not taken.
imagePickerController.sourceType = .PhotoLibrary
// Make sure ViewController is notified when the user picks an image.
imagePickerController.delegate = self
presentViewController(imagePickerController, animated: true, completion: nil)
}
#IBAction func setDefaultLabelText(sender: AnyObject) {
nameLabel.text = "Default Meal name"
}
override func viewDidLoad() {
super.viewDidLoad()
// Handle the user input on textfield through delegate callback (self == this)
nameTextField.delegate = self
}
// MARK: UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
// Hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(textField: UITextField) {
nameLabel.text = textField.text
}
}
anyhow when the simulator starts up and I tap on the photo the library view is not shown. I even cannot see me debugging message.
I already did remove the outlets and actions and did the whole process again by adding the UIImageView Outlet, add the gesture recognizer, add the action of the gesturerecognizer but still not happening what it should.
I have found the problem - I did not enable the User Interaction which is set to false by default.

UIImageVIew.image isn't be changed

I'm newbie to iOS programming, and trying to developer "FoodTracker" in Swift tutorial. Below is all my code.
import UIKit
class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
//MARK: Properties
#IBOutlet weak var nameTextField: UITextField!
#IBOutlet weak var mealNameLabel: UILabel!
#IBOutlet weak var photoImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
nameTextField.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: Actions
#IBAction func selectImageFromPhotoLibrary(sender: UITapGestureRecognizer) {
// Hide the keyboard.
nameTextField.resignFirstResponder()
//UIImagePickerController is a view controller that lets a user pick media from their photo library.
let imagePickerController = UIImagePickerController()
//Only allow photos to be picked, not taken.
imagePickerController.sourceType = .PhotoLibrary
//Make sure ViewController is notified when the user picks an image.
imagePickerController.delegate = self
presentViewController(imagePickerController, animated: true, completion: nil)
}
#IBAction func setDefaultLabelText(sender: UIButton) {
mealNameLabel.text = "Default Text"
}
//MARK: UIImagePickerControllerDelegate
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
//Dismiss the picker if the user canceled.
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithinfo info: [String : AnyObject]) {
//The info dictionary contains multiple representations of the image, and this uses the original.
let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage
photoImageView.image = selectedImage
// Dismiss the picker.
dismissViewControllerAnimated(true, completion: nil)
}
//MARK: UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
//hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(textField: UITextField) {
mealNameLabel.text = textField.text
}
}
The app is executed normally but the image can't be changed.
The normal process is click the image > select any image from Camera roll > change the image of idle screen. The problem is last step, "change the image of idle screen."
Which point is my mistake? I have compared my code with example code in tutorial again and again, but I couldn't find something helpful. Please help me.
2 things:
First declare the
let imagePicker = UIImagePickerController();
as an instance variable and then set it's delegate to self in viewdidload
override func viewDidLoad() {
super.viewDidLoad();
imagePicker.delegate=self;
}
This way it's set only once (rather reseting for each func call)
Second I suggest to use :
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
photoImageView.image=image;
}
instead of (didFinishPickingMediaWithinfo ...), which made exactly for picking image, just as you need and you don't need casting.
Here is a simplified example:
image picker example
Hope it helped
Finnaly, I figure out the solution. But it's little trivial.
The problem is Language version. I used XCode 6.4 and Swift 1.2.
But the homepage used XCode 7.0 beta and Swift 2.0.
This is the reason of my problem. And now, all works fine.
Thank you for all my responders.
Did you look at selectedImage variable? Does it nil? Try to setup breakpoint to line after setting selectedImage.

Resources