why won't my main viewcontroller update when i

2019-09-11 02:51发布

问题:

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?

回答1:

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:

 import UIKit
 import CoreData
 import MobileCoreServices

 class FeedViewController: UIViewController, UICollectionViewDataSource,
 UICollectionViewDelegate, UIImagePickerControllerDelegate,
 UINavigationControllerDelegate {
 @IBOutlet weak var collectionView: UICollectionView!
 var feedArray: [AnyObject] = []

change it so you have:

 import UIKit
 import CoreData
 import MobileCoreServices

  var feedArray: [AnyObject] = []

 class FeedViewController: UIViewController, UICollectionViewDataSource,
 UICollectionViewDelegate, UIImagePickerControllerDelegate,
 UINavigationControllerDelegate {
 @IBOutlet weak var collectionView: UICollectionView!

And instead of using

    FeedViewController().feedArray.append(feedItem)

Now you can use:

    feedArray.append(feedItem)

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.



回答2:

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.