instantiateViewControllerWithIdentifier 之后的 IBOutlet nil
Posted
技术标签:
【中文标题】instantiateViewControllerWithIdentifier 之后的 IBOutlet nil【英文标题】:IBOutlet nil after instantiateViewControllerWithIdentifier 【发布时间】:2015-02-25 23:57:18 【问题描述】:不确定我在这里做错了什么。我已经列出了我的问题和我的代码。很想得到一些帮助。
谢谢!
问题:
VC1 提供 VC2。 来自 VC1 的 IBOutlets 现在为零。 VC2 解散回 VC1。 VC1 中的 IBOutlets 仍然为零。VC1 从 flickR 加载图片网格。 VC2 有一个 searchBar 控制器,当 VC2 被关闭时,它会运行 flickR 查询。在我的 self.collectionView.reload() 失败之前,因为 self.collectionView 是 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)
)
【问题讨论】:
使用 performSegueWithIdentifier() 不会给您带来任何问题。不确定 instantiateViewControllerWithIdentifier 是否会导致错误。 你展示了VC2之后怎么知道VC1的outlets是nil(应该不是这样)?为什么,在 searchBarSearchButtonClicked 方法中,您要创建 MainViewController 的新实例?你不应该那样做。在您要返回的控制器中调用方法的标准方法是使用委托。 感谢您的回复 :) 在 VC2s viewDidLoad() 函数中,我运行这段代码 println(MainViewController().controllerView) 来查看它是否存在,但它总是返回 nil。我将尝试委托方法并更新此帖子。 你得到 nil 是因为 MainViewController() 只是分配了一个新的视图控制器,而不是在故事板中制作的一个连接了它的插座。 能够弄清楚,再次感谢。我在下面发布了一个答案。如果您发现任何错误,请告诉我。干杯 【参考方案1】:感谢 rdelmar,我能够使用协议解决这个问题。
这是我添加的内容:
搜索代理 SearchDelegate 函数 runSearch()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)
【讨论】:
以上是关于instantiateViewControllerWithIdentifier 之后的 IBOutlet nil的主要内容,如果未能解决你的问题,请参考以下文章
Swift:prepareForSegue 和 instantiateViewController 之间的区别