vendoo_v1.0/Vendoo/ItemImagePickerViewController.swift
Okechi Onyeje eee7986ffb Bug has been resolved
Alerts and validation have been added to posting process to prevent bad input, as well as alerts to network selection, to alert user when no networks have been selected or authorized
2016-11-26 15:16:08 -05:00

582 lines
26 KiB
Swift

//
// ItemImagePickerViewController.swift
// Vendoo
//
// Created by Okechi Onyeje on 5/27/16.
// Copyright © 2016 Okechi Onyeje. All rights reserved.
//
/*
need to make this class display a top navigation bar so user may cancel the new item posting if need be
*/
import UIKit
class ItemImagePickerViewController: UIViewController {
//Outlets
@IBOutlet weak var cancelButton: UIButton!
@IBOutlet weak var descriptionLabel: UILabel!
@IBOutlet weak var quantityLabel: UILabel!
@IBOutlet weak var possibleItemImageMain: UIImageView!
@IBOutlet weak var possibleItemImage2: UIImageView!
@IBOutlet weak var possibleItemImage3: UIImageView!
@IBOutlet weak var possibleItemImage4: UIImageView!
@IBOutlet weak var possibleItemImage5: UIImageView!
@IBOutlet weak var itemQuantity: UITextField!
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var itemName: UITextField!
@IBOutlet weak var itemDescription: UITextView!
@IBOutlet weak var itemPrice: UITextField!
@IBOutlet weak var textEditScrollView: UIScrollView!
//@IBOutlet weak var categoryPicker: UIPickerView!
@IBOutlet weak var priceLabel: UILabel!
@IBOutlet weak var containerScrollView: UIScrollView!
//class variables
var pickerData: [String] = [String]()
var itemImagesSelections = [false,false,false,false,false]
private var picker = UIImagePickerController()
private var currImageSelected: UIImageView!
private var currUILabel: UILabel!
private var imageIndex: Int!
private var isEditing: Bool = false
private var currentInformation: Dictionary<String, AnyObject>!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.tabBarController?.tabBar.hidden = true
// Connect data:
//self.categoryPicker.delegate = self
//self.categoryPicker.dataSource = self
self.itemDescription.delegate = self
self.itemName.delegate = self
self.itemQuantity.delegate = self
self.itemPrice.delegate = self
self.picker.delegate = self
addEditableItemsToScrollView()
// Input data into the Array:
pickerData = ["Category 1", "Category 2", "Category 3", "Category 4", "Category 5", "Category 6"]
let tapGestureMain = UITapGestureRecognizer(target: self, action: #selector(ItemImagePickerViewController.takePicture))
self.view.addGestureRecognizer(tapGestureMain)
//self.possibleItemImageMain.addGestureRecognizer(tapGestureMain)
//self.possibleItemImage2.addGestureRecognizer(tapGesture2)
//self.possibleItemImage3.addGestureRecognizer(tapGesture)
//self.possibleItemImage4.addGestureRecognizer(tapGesture)
//self.possibleItemImage5.addGestureRecognizer(tapGesture)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.tabBar.hidden = true
}
func toggleEditingMode(dictionary: Dictionary<String, AnyObject>?){
if(!self.isEditing) {
self.currentInformation = dictionary!
}
self.isEditing = !self.isEditing
}
/*
This function is called in the viewDidLoad function.
It will load all these editable items into the scroll view
being used to control the text editing views
*/
func addEditableItemsToScrollView(){
self.textEditScrollView.addSubview(self.itemName)
self.textEditScrollView.addSubview(self.itemDescription)
self.textEditScrollView.addSubview(self.itemQuantity)
self.textEditScrollView.addSubview(self.priceLabel)
self.textEditScrollView.addSubview(self.titleLabel)
self.textEditScrollView.addSubview(self.quantityLabel)
self.textEditScrollView.addSubview(self.descriptionLabel)
self.textEditScrollView.addSubview(self.itemPrice)
}
}
//MARK: - Navigation methods
extension ItemImagePickerViewController {
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if(segue.identifier == "CategoriesSegue"){
print(self.itemName.text!)
print(self.itemDescription.text!)
print(self.possibleItemImageMain.image)
print(self.itemPrice.text!)
if (
self.itemName.text! == "" ||
Int(self.itemQuantity.text!) == nil ||
Int(self.itemQuantity.text!) < 1 ||
self.itemPrice.text! == "" ||
Double(self.itemPrice.text!) == nil ||
Double(self.itemPrice.text!) < 0.30 ||
self.itemDescription.text! == "Description"
){
let alert = UIAlertController(title: "Required Information Missing", message: "To proceed with your listing, at least one image must be provided. Along with all provided fields including:\n Title\nDescription\nQuantity (must be greater than 0)\nPrice (must be greater than $0.30).", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:{(action: UIAlertAction!) in alert.dismissViewControllerAnimated(true, completion: nil)}))
self.presentViewController(alert, animated: true, completion: nil)
}else{
var dict: Dictionary<String, AnyObject!> = ["title":self.itemName.text!, "description":self.itemDescription.text!, "price":self.itemPrice.text!, "quantity":self.itemQuantity.text!]
var counter = 0
var images: [UIImageView] = []
for bool in self.itemImagesSelections {
if !bool {
break
}
switch counter {
case 1:
images.append(self.possibleItemImage2)
break
case 2:
images.append(self.possibleItemImage3)
break
case 3:
images.append(self.possibleItemImage4)
break
case 4:
images.append(self.possibleItemImage5)
break
default:
images.append(self.possibleItemImageMain)
}
counter += 1
}
dict["pictures"] = images
(segue.destinationViewController as! CategoriesTableViewController).setListingDictionary(dict)
if(self.isEditing) {
(segue.destinationViewController as! CategoriesTableViewController).setManagers((self.currentInformation["fbManager"] as? FacebookGraphAPIManager)!, fireManager: (self.currentInformation["firebaseManager"] as? FirebaseManager)!, ebayManager: (self.currentInformation["ebayManager"] as? EbayWebServiceManager)!, etsyManager: (self.currentInformation["etsyManager"] as? EtsyRESTAPIManager)!)
}else {
(segue.destinationViewController as! CategoriesTableViewController).setManagers(((self.tabBarController as? HomeViewController)?.fbGraphManager)!,
fireManager: ((self.tabBarController as? HomeViewController)?.firebaseManager)!, ebayManager: ((self.tabBarController as? HomeViewController)?.ebayGraphManager)!,
etsyManager: ((self.tabBarController as? HomeViewController)?.etsyManager)!)
}
}
}
}
}
//MARK: - Camera session methods
extension ItemImagePickerViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
if (self.possibleItemImageMain.image != nil && self.currUILabel != nil ){
self.currUILabel.hidden = true
}
self.currImageSelected.image = image
self.itemImagesSelections[self.imageIndex] = true
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
func takePicture(sender: UITapGestureRecognizer ){
let location: CGPoint = sender.locationInView(self.view)
if(sender.state == UIGestureRecognizerState.Ended) {
var viewsWereSaved = [false, false]
for view in self.view.subviews {
if (view.isKindOfClass(UIImageView) && CGRectContainsPoint(view.frame, location)) {
self.currImageSelected = view as! UIImageView
switch (view.tag) {
case 1:
if(self.itemImagesSelections[0]) {
//self.itemImagesSelections[1] = true
viewsWereSaved[0] = true
self.imageIndex = 1
accessCam()
} else {
let alert = UIAlertController(title: "Main Image Needed", message: "You must have a main image before saving supporting images.", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:{(action: UIAlertAction!) in alert.dismissViewControllerAnimated(true, completion: nil)}))
self.presentViewController(alert, animated: true, completion: nil)
}
break
case 2:
if(self.itemImagesSelections[0] && self.itemImagesSelections[1]) {
viewsWereSaved[0] = true
self.imageIndex = 2
accessCam()
} else {
let alert = UIAlertController(title: "Support Image 1 Missing", message: "You must save your first supporting image before saving more.", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:{(action: UIAlertAction!) in alert.dismissViewControllerAnimated(true, completion: nil)}))
self.presentViewController(alert, animated: true, completion: nil)
}
break
case 3:
if(self.itemImagesSelections[0] && self.itemImagesSelections[1]
&& self.itemImagesSelections[2]) {
viewsWereSaved[0] = true
self.imageIndex = 3
accessCam()
} else {
let alert = UIAlertController(title: "Support Image 2 Missing", message: "You must save your first two supporting images before saving more.", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:{(action: UIAlertAction!) in alert.dismissViewControllerAnimated(true, completion: nil)}))
self.presentViewController(alert, animated: true, completion: nil)
}
break
case 4:
if(self.itemImagesSelections[0] && self.itemImagesSelections[1]
&& self.itemImagesSelections[2] && self.itemImagesSelections[3]) {
viewsWereSaved[0] = true
self.imageIndex = 4
accessCam()
} else {
let alert = UIAlertController(title: "Support Image 3 Missing", message: "You must save your first three supporting images before saving more.", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:{(action: UIAlertAction!) in alert.dismissViewControllerAnimated(true, completion: nil)}))
self.presentViewController(alert, animated: true, completion: nil)
}
break
default:
//self.itemImagesSelections[0] = true
self.imageIndex = 0
accessCam()
break
}
}
if (view.isKindOfClass(UILabel) && CGRectContainsPoint(view.frame, location)) {
self.currUILabel = view as! UILabel
viewsWereSaved[1] = true
}
}
}
}
private func accessCam(){
let captureMenu = UIAlertController(title: nil, message:nil, preferredStyle: .ActionSheet)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: {
(alert: UIAlertAction!) -> Void in
})
let cameraAction = UIAlertAction(title: "Take a New Item Picture", style: .Default, handler: {
(alert: UIAlertAction!) -> Void in
self.picker.allowsEditing = false
self.picker.sourceType = UIImagePickerControllerSourceType.Camera
self.picker.cameraCaptureMode = .Photo
self.presentViewController(self.picker, animated: true, completion: nil)
})
let galleryAction = UIAlertAction(title: "Select a Picture for Your Item", style: .Default, handler: {
(alert: UIAlertAction!) -> Void in
self.picker.allowsEditing = false
self.picker.sourceType = .PhotoLibrary
self.presentViewController(self.picker, animated: true, completion: nil)
})
captureMenu.addAction(galleryAction)
captureMenu.addAction(cameraAction)
captureMenu.addAction(cancelAction)
self.presentViewController(captureMenu, animated: true, completion: nil)
}
}
//MARK: - UIPickerViewDelegate
extension ItemImagePickerViewController: UIPickerViewDelegate {
// Catpure the picker view selection
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// This method is triggered whenever the user makes a change to the picker selection.
// The parameter named row and component represents what was selected.
}
}
//MARK: - UIPickerViewDatasource
extension ItemImagePickerViewController: UIPickerViewDataSource {
// The number of columns of data
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
// The number of rows of data
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count
}
// The data to return for the row and component (column) that's being passed in
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerData[row]
}
}
extension ItemImagePickerViewController: UITextViewDelegate {
func textViewDidBeginEditing(textView: UITextView) {
if (textView.text! == "Description") {
textView.text = ""
textView.textColor = UIColor.blackColor()
//optional
}
textView.becomeFirstResponder()
self.textEditScrollView.setContentOffset(CGPoint( x: 0, y: 100), animated: true)
}
func textViewDidEndEditing(textView: UITextView) {
if (textView.text! == "") {
textView.text = "Description"
textView.textColor = UIColor.lightGrayColor()
//optional
}
self.textEditScrollView.setContentOffset(CGPoint( x: 0, y: 0), animated: true)
}
//Will check for the return key so it can dismiss the text view keyboard
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if text == "\n"{
textView.resignFirstResponder()
return true
}
return true
}
func textViewDidChange(textView: UITextView) {
let fixedWidth = textView.frame.size.width
textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
var newFrame = textView.frame
newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
textView.frame = newFrame;
self.containerScrollView.setContentOffset(CGPointMake(0, 0), animated: true)
}
}
extension ItemImagePickerViewController: UITextFieldDelegate {
func textFieldShouldReturn(textField: UITextField) -> Bool {
self.view.endEditing(true)
return false
}
func hideKeyboard() {
self.view.endEditing(true)
}
}
//Mark: - IBActions
extension ItemImagePickerViewController {
@IBAction func chooseSellerNetworks(sender: AnyObject) {
//segue to networks selection
self.performSegueWithIdentifier("SelectNetworkSegue", sender: self)
}
@IBAction func draftItem(sender: AnyObject) {
if(self.possibleItemImageMain.image == nil){
let alert = UIAlertController(title: "Main Image Needed", message: "To proceed to save your listing as a draft, you must supply at least one picture for your listing.", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:{(action: UIAlertAction!) in alert.dismissViewControllerAnimated(true, completion: nil)}))
self.presentViewController(alert, animated: true, completion: nil)
}else{
//save listing to private user path in firebase
let newListingRef = (self.tabBarController as? HomeViewController)?.firebaseManager.ref.child("Users").child("\(((self.tabBarController as? HomeViewController)?.firebaseManager.user_email)!)").child("user_Listings").childByAutoId()
var counter = -1
for bool in self.itemImagesSelections {
if bool {
counter += 1
}else {
break
}
}
let listing: Dictionary<String, AnyObject?> = ["listingID": newListingRef!.key,
"seller email": (NSUserDefaults.standardUserDefaults().objectForKey("email") as? String)!,
"listingTitle": self.itemName.text,
"listingPrice": self.itemPrice.text,
"listingDescription": self.itemDescription.text,
"listingQuantity": self.itemQuantity.text!,
"numberOfSupportingImages" : counter,
"isListingDraft": true,
"networks": ["areNetworksChosen": false]]
(self.tabBarController as? HomeViewController)?.firebaseManager.ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
let databaseDict = snapshot.value as! [String : AnyObject]
let storageRef = (self.tabBarController as? HomeViewController)?.firebaseManager.storage.referenceForURL((databaseDict["image_storage"] as? String)!)
//check each imageview to see if there is an image to upload
if(self.possibleItemImage2.image != nil){
let listingImageRef = storageRef!.child("images/\(newListingRef!.key)"+"/2.jpg")
listingImageRef.putData(UIImageJPEGRepresentation(self.possibleItemImage2.image!, 0.8)!, metadata: nil,completion:
{(metadata, error) -> Void in
print(metadata)
})
}
if(self.possibleItemImage3.image != nil){
let listingImageRef = storageRef!.child("images/\(newListingRef!.key)"+"/3.jpg")
listingImageRef.putData(UIImageJPEGRepresentation(self.possibleItemImage3.image!, 0.8)!, metadata: nil,completion:
{(metadata, error) -> Void in
print(metadata)
})
}
if(self.possibleItemImage4.image != nil){
let listingImageRef = storageRef!.child("images/\(newListingRef!.key)"+"/4.jpg")
listingImageRef.putData(UIImageJPEGRepresentation(self.possibleItemImage4.image!, 0.8)!, metadata: nil,completion:
{(metadata, error) -> Void in
})
}
if(self.possibleItemImage5.image != nil){
let listingImageRef = storageRef!.child("images/\(newListingRef!.key)"+"/5.jpg")
listingImageRef.putData(UIImageJPEGRepresentation(self.possibleItemImage5.image!, 0.8)!, metadata: nil,completion:
{(metadata, error) -> Void in
})
}
if(self.possibleItemImageMain.image != nil){
let listingImageRef = storageRef!.child("images/\(newListingRef!.key)"+"/main.jpg")
listingImageRef.putData(UIImageJPEGRepresentation(self.possibleItemImageMain.image!, 0.8)!, metadata: nil,completion:
{(metadata, error) -> Void in
newListingRef!.setValue(listing as? Dictionary<String,AnyObject>)
let alert = UIAlertController(title: "Item Saved", message: "Your listing has been saved by a draft", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:{(action: UIAlertAction!) in alert.dismissViewControllerAnimated(true, completion: {
self.dismissViewControllerAnimated(true, completion: nil)
})}))
self.presentViewController(alert, animated: true, completion: nil)
})
}
})
}
}
@IBAction func cancelNewListing(sender: AnyObject) {
//@FIXME: nil out all data user may have entered so that when they reopen new listing page it initialized to a fresh screen.
if(!self.isEditing) {
self.tabBarController?.selectedIndex = 0
}else{
self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
}
}
}
//All these functions will handle the scrolling of the editable elements into view
extension ItemImagePickerViewController{
/*
Each of these functions are event handlers on edit begin/end for
each of the editable elements in the view. This will scroll them into view.
To see which function controls what, check the function name
*/
@IBAction func onTitleEditEnd(sender: AnyObject) {
self.textEditScrollView.setContentOffset(CGPoint( x: 0, y: 0), animated: true)
}
@IBAction func onPriceEditEnd(sender: AnyObject) {
self.textEditScrollView.setContentOffset(CGPoint( x: 0, y: 0), animated: true)
}
@IBAction func onPriceEditBegin(sender: AnyObject) {
self.textEditScrollView.setContentOffset(CGPoint( x: 0, y: 50), animated: true)
}
@IBAction func onQuantityEditBegin(sender: AnyObject) {
self.textEditScrollView.setContentOffset(CGPoint( x: 0, y: 50), animated: true)
}
@IBAction func onQuantityEditEnd(sender: AnyObject) {
self.textEditScrollView.setContentOffset(CGPoint( x: 0, y: 0), animated: true)
}
//This will scroll the title into view when editing it
@IBAction func editingTitleBegan(sender: AnyObject) {
self.textEditScrollView.setContentOffset(CGPoint( x: 0, y: 0), animated: true)
}
}