Im trying to create a very simple app. you are in feedViewController, click on bar button icon (a camera). It takes you to AddEditViewController.
in AddEditView controller, you want to add a picture in an array that will be displayed in feedViewController once you click "save" but my picture is not shown until i stop the app in the simulator and run it again.
import UIKit
import CoreData
import MobileCoreServices
class FeedViewController: UIViewController, UICollectionViewDataSource,
UICollectionViewDelegate, UIImagePickerControllerDelegate,
UINavigationControllerDelegate {
@IBOutlet weak var collectionView: UICollectionView!
var feedArray: [AnyObject] = []
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
makeItLoad()
}
override func viewDidAppear(animated: Bool) {
self.collectionView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func makeItLoad(){
let request = NSFetchRequest(entityName: "FeedItem")
let appDelegate:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
let context:NSManagedObjectContext = appDelegate.managedObjectContext
feedArray = try! context.executeFetchRequest(request)
self.collectionView?.reloadData()
}
@IBAction func addPhotoButtonTapped(sender: AnyObject) {
}
//UICollectionViewDataSource
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int
{
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return feedArray.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell:FeedCell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! FeedCell
let thisItem = feedArray[indexPath.row] as! FeedItem
cell.imageView.image = UIImage(data: thisItem.image!)
cell.captionLabel.text = thisItem.caption
return cell
}
}
and my addEditview is:
import UIKit
import CoreData
import MobileCoreServices
class AddEditViewController:
UIViewController,NSFetchedResultsControllerDelegate,
UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var item : FeedItem? = nil
@IBOutlet weak var addEditNameField: UITextField!
@IBOutlet weak var addEditTypeField: UITextField!
@IBOutlet weak var addEditHashtagField: UITextField!
@IBOutlet weak var addEditImageViewHolder: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func addImageFromDevice(sender: AnyObject) {
let pickerController = UIImagePickerController()
pickerController.delegate = self
pickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
pickerController.allowsEditing = true
self.presentViewController(pickerController, animated: true, completion: nil)
}
@IBAction func addImageFromCamera(sender: AnyObject) {
let pickerController = UIImagePickerController()
pickerController.delegate = self
pickerController.sourceType = UIImagePickerControllerSourceType.Camera
pickerController.allowsEditing = true
self.presentViewController(pickerController, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController,
didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
self.dismissViewControllerAnimated(true, completion: nil)
self.addEditImageViewHolder.image = image
}
@IBAction func saveButtonTapped(sender: AnyObject) {
createNewItem()
dismissVC()
}
@IBAction func cancelButtonTapped(sender: AnyObject) {
dismissVC()
}
func dismissVC() {
navigationController?.popViewControllerAnimated(true)
FeedViewController().collectionView?.reloadData()
FeedViewController().viewDidLoad()
}
func createNewItem() {
let entityDescription = NSEntityDescription.entityForName("FeedItem",
inManagedObjectContext: FeedViewController().managedObjectContext)
let feedItem = FeedItem(entity: entityDescription!,
insertIntoManagedObjectContext:
FeedViewController().managedObjectContext)
feedItem.caption = addEditNameField.text
feedItem.type = addEditTypeField.text
feedItem.hashtags = addEditHashtagField.text
feedItem.image = UIImagePNGRepresentation(addEditImageViewHolder.image!)
FeedViewController().feedArray.append(feedItem)
do {
try FeedViewController().managedObjectContext.save()
} catch {
return
}
}
func editItem() {
item!.caption = addEditNameField.text
item!.type = addEditTypeField.text
item!.hashtags = addEditHashtagField.text
item!.image = UIImagePNGRepresentation(addEditImageViewHolder.image!)
do {
try FeedViewController().managedObjectContext.save()
} catch {
return
}
}
}
So my question is: once i press the camera, which is connected to "AddEditViewController" through a segue, and i pick a picture and press "Save". Why won't my FeedViewController be updated? Why do I have to stop the simulator and relaunch it for it to show up?
So, After playing around a little bit and trying to learn, I found the solution
First of all, add the array outside of the class so it is global, so instead of:
change it so you have:
And instead of using
Now you can use:
What the problem was, is that every time i used : "FeedViewController().fee..." I created a new instance, so i actually didn't append the array properly.
I hope it helped.
It seems to me that while you do save the new picture to the database service, and you do add it to the array being used to populate the collection view, you never reload the collection view. For some reason you reload it if the user cancels taking a new picture, which would seem to be redundant, but don't reload after a new picture is taken, which would seem to be important.
Note: There are more efficient ways to add new data to a collectionView than
.reloadData()
..reloadData()
will reload all the cells, while the method.insertItemsAtIndexPaths()
will just add the 1 new cell.