Bronze challenge
Simply modify imagePicker
to allow editing.
imagePicker.allowsEditing = true
. This change is in line 88 inside the function takePicture(_:)
Silver Challenge
I decided to add a button to the bottom of the stack view, under the UIImageView, and only show it if there is an image present. The functions added and modified are removeImage(_:)
, viewWillAppear(_:)
. Also, the UIButton is connected to the code as an action and an outlet.
Here is the full code. Again the only change to the storyboard was the UIButton and its drawing is set to hidden.
DetailVIewController.swift
import UIKit
class DetailViewController: UIViewController, UITextFieldDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
@IBOutlet var nameField: CustomTextField!
@IBOutlet var serialNameField: CustomTextField!
@IBOutlet var valueField: CustomTextField!
@IBOutlet var dateLabel: UILabel!
@IBOutlet var removeImageButton: UIButton!
@IBOutlet var imageView: UIImageView!
var item: Item! {
didSet {
navigationItem.title = item.name
}
}
var imageStore: ImageStore!
let numberFormatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
return formatter
}()
let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none
return formatter
}()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
nameField.text = item.name
serialNameField.text = item.serialNumber
valueField.text = numberFormatter.string(from: NSNumber(value: item.valueInDollars))
dateLabel.text = dateFormatter.string(from: item.dateCreated)
let key = item.itemKey
let imageToDisplay = imageStore.image(forKey: key)
imageView.image = imageToDisplay
if imageToDisplay != nil {
removeImageButton.isHidden = false
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
view.endEditing(true)
item.name = nameField.text ?? ""
item.serialNumber = serialNameField.text
if let valueText = valueField.text, let value = numberFormatter.number(from: valueText) {
item.valueInDollars = value.intValue
} else {
item.valueInDollars = 0
}
}
@IBAction func backgroundTapped(_ sender: UITapGestureRecognizer) {
view.endEditing(true)
}
@IBAction func takePicture(_ sender: UIBarButtonItem) {
let imagePicker = UIImagePickerController()
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.sourceType = .camera
} else {
imagePicker.sourceType = .photoLibrary
}
imagePicker.delegate = self
imagePicker.allowsEditing = true
present(imagePicker, animated: true, completion: nil)
}
@IBAction func removeImage(_ sender: UIButton) {
imageStore.deleteImage(forKey: item.itemKey)
imageView.image = nil
removeImageButton.isHidden = true
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// Get picked image from info dictionary
let image = info[UIImagePickerControllerEditedImage] as! UIImage
imageStore.setImage(image, forKey: item.itemKey)
// Put that image on the screen in the image view
imageView.image = image
// take the image picker off the screen -
// you must call this dismiss method
dismiss(animated: true, completion: nil)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "ChangeDate"?:
let controller = segue.destination as! ItemDateViewController
controller.item = self.item
default:
preconditionFailure("Unexpected segue identifier.")
}
}
}