30199

IBOutlet nil after instantiateViewControllerWithIdentifier

Question:

Not sure exactly what I'm doing wrong here. I've listed out what my problem is and my code. Would love to get some help.

Thanks!

Problem:

<ul><li>VC1 presents VC2. </li> <li>IBOutlets from VC1 are now nil.</li> <li>VC2 dismisses back into VC1. </li> <li>IBOutlets in VC1 are still nil. </li> </ul>

VC1 loads a grid of pictures from flickR. VC2 has a searchBar controller, when VC2 is dismissed it does runs flickR query. Right before my self.collectionView.reload() fails because self.collectionView is nil :(

VC1

import UIKit class MainViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource { @IBOutlet var collectionView: UICollectionView! @IBOutlet var searchMask: UIView! let api_key = "f87357398a52b80e0c9f76bf94c8ee94" var flickResults:NSMutableArray! = NSMutableArray() var titleResults:NSMutableArray! = NSMutableArray() override func viewDidLoad() { super.viewDidLoad() loadPhotos("Brasil") // Do any additional setup after loading the view. } override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) } func loadPhotos(searchString: String) { let flickr:FlickrHelper = FlickrHelper() println("Collection: \(self.collectionView)") flickr.request(searchString, per_page: 50, completion: { (searchStr, flickrPhotos, photoTitle) -> () in dispatch_async(dispatch_get_main_queue(), { self.flickResults = flickrPhotos self.titleResults = photoTitle self.collectionView.reloadData() }) }) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } override func preferredStatusBarStyle() -> UIStatusBarStyle { return UIStatusBarStyle.LightContent } func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell: PhotoCell = self.collectionView.dequeueReusableCellWithReuseIdentifier("photoCell", forIndexPath: indexPath) as PhotoCell cell.photoImageView.alpha = 0 let queue:dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) dispatch_async(queue, { let searchURL: String = self.flickResults.objectAtIndex(indexPath.item) as String let title: String = self.titleResults.objectAtIndex(indexPath.item) as String let image: UIImage = self.loadImage(searchURL) dispatch_async(dispatch_get_main_queue(), { UIView.animateWithDuration(0.5, animations: { cell.photoImageView.image = image cell.photoTitle.text = title.capitalizedString cell.photoImageView.alpha = 1 }) }) }) insertBlurView(cell.titleMask, UIBlurEffectStyle.Dark) return cell } func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return self.flickResults.count } func loadImage(imageUrl: String) -> UIImage{ let url = NSURL(string: imageUrl) let data = NSData(contentsOfURL: url!) let image = UIImage(data: data!) return image! } @IBAction func searchButtonPressed(sender: UIButton) { let storyboard = UIStoryboard(name: "Main", bundle: nil); let vc: SearchViewController = storyboard.instantiateViewControllerWithIdentifier("Search") as SearchViewController providesPresentationContextTransitionStyle = true definesPresentationContext = true vc.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext self.presentViewController(vc, animated: false, completion: nil) } }

VC2

import UIKit class SearchViewController: UIViewController, UITextFieldDelegate, UISearchBarDelegate, UICollectionViewDelegate { @IBOutlet var searchMask: UIView! @IBOutlet var searchField: UITextField! @IBOutlet var searchBar: UISearchBar! override func viewDidLoad() { super.viewDidLoad() insertBlurView(self.searchMask, UIBlurEffectStyle.Dark) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func exitTap(sender: UIButton) { self.dismissViewControllerAnimated(true, completion: nil) } func searchBarSearchButtonClicked(searchBar: UISearchBar) { self.dismissViewControllerAnimated(true, completion: { let mainvc = self.storyboard?.instantiateViewControllerWithIdentifier("Main") as MainViewController mainvc.loadPhotos(searchBar.text) }) } }

Answer1:

Thanks to rdelmar, I was able to figure this out using protocols.

Here's what I added:

<ul><li>SearchDelegate </li> <li>SearchDelegate function runSearch()</li> </ul>

VC1

class MainViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, SearchDelegate { func runSearch(searchString: String) { loadPhotos(searchString) } }

VC2

protocol SearchDelegate { func runSearch(searchString: String) } class SearchViewController: UIViewController, UITextFieldDelegate, UISearchBarDelegate, UICollectionViewDelegate { @IBOutlet var searchMask: UIView! @IBOutlet var searchField: UITextField! @IBOutlet var searchBar: UISearchBar! var delegate: SearchDelegate? func searchBarSearchButtonClicked(searchBar: UISearchBar) { delegate?.runSearch(searchBar.text) self.dismissViewControllerAnimated(true, completion:nil) }

Recommend

  • Selecting rows maintaining distribution percentage?
  • Searchbox in Listview: always the same result
  • How to detect a flick gesture using UISwipeGestureRecognizer?
  • Create a div like element that has overflow set to auto using HTML Canvas
  • mysql query with WHERE IF and FIND_IN_SET() function
  • Get the parent controller name from partialview action
  • How do I nest a call to a method within a call to a method using Expression.Call
  • Autolayout is not updating frames instantly in iOS8-Xcode6
  • Change height constraint of table view outside of viewDidAppear in iOS 7
  • alert with UIAlertController can't dissmiss it
  • VBA Evaluate function with string arguments
  • MonoTouch SIGABRT “Ran out of trampolines of type 2” error
  • Custom UITabBarController Problems with View Controllers and Views
  • Could not match polymorphic type in haskell
  • dismissModalViewControllerAnimated nonatomic?
  • Auto Height of UICollectionView inside UITableViewCell
  • “[CALayer release]: message sent to deallocated instance” when dismissing modal view controller
  • Generate a unique string based on a pair of strings
  • “A GKScore must specify a leaderboard.”
  • Deleting a widget from QTableView
  • Jquery UI Sortable, move item automatically
  • multidatatrigger with multibinding in ControlTemplate.Triggers
  • Accessing Rows In A LINQ Result Without A Foreach Loop?
  • Is there a parser equivalent of 'fragment' marking in ANTLR4?
  • Where these are stored?
  • If statement skipping right to else after being called once?
  • abstracting over a collection
  • How can I tell a form not to dispose a particular control when it closes?
  • Build Successful but not running on simulator
  • Reading a file into a multidimensional array
  • App restarts from wrong activity
  • custom UITableViewCell with image for highlighting
  • Jetty Server not starting: Unable to establish loopback connection
  • How would I use PHP exceptions to define a redirect?
  • How to redirect a user to a different server and include HTTP basic authentication credentials?
  • sending/ receiving email in Java
  • How to set my toolbar fixed while scrolling android
  • Symfony2: How to get request parameter
  • AT Commands to Send SMS not working in Windows 8.1
  • retrieve vertices with no linked edge in arangodb
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • log4net write single file for each call to log.info
  • Getting error when using KSoap library to consume .NET web services
  • apache spark aggregate function using min value
  • Sorting a 2D array using the second column C++