我的设置:
`UITableViewController` (ComboViewController)
-> Several Static Cells
-> One Static Cell contains a dynamic `tableView`
我需要使用自定义Delegate/DataSource,因为动态表视图嵌入在TableViewController
的静态表视图中
此自定义Delegate/DataSource如下所示:
class DataSource: NSObject, UITableViewDataSource, UITableViewDelegate {
// class variables
override init() {
super.init()
// initialize variables
}
//some data source/ delegate methods like number of rows, cellForRowAtIndexPath
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var indexedCombos: NSDictionary?
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let comboVC: ComboInfoViewController = storyboard.instantiateViewControllerWithIdentifier("ComboInfo") as! ComboInfoViewController
comboVC.doSegue()
}
}
在ComboViewController
中,我有以下内容:
class ComboInfoViewController: UITableViewController {
func doSegue() {
self.performSegueWithIdentifier("tosingle", sender: combListTable)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "tosingle" {
//do stuff
}
}
}
如果segue是模态的,我会得到这个错误:
Warning: Attempt to present SingleProductViewController on ComboInfoViewController whose view is not in the window hierarchy!
如果segue是push,那么会调用prepareForSegue
方法,但viewController
不会push!发生了什么?
我找了又找。但我不知道是什么导致了这种行为。
使用此行创建ComboInfoViewController实例时,
let comboVC: ComboInfoViewController = storyboard.instantiateViewControllerWithIdentifier("ComboInfo") as! ComboInfoViewController
您正在创建一个新实例,但它不是屏幕上的实例,而且永远不会是,所以这就是您出现错误的原因。理解这个概念是非常重要的;了解视图控制器是如何创建的,以及如何获得指向现有视图控制器的指针,是iOS编程的基础。
然而,在这种情况下,你甚至不需要获得指向屏幕上的指针,因为你应该直接从单元格(动态原型)连接segue,这意味着你不需要任何代码来执行它。你可以删除didSelectRowAtIndexPath方法和doSegue方法。您只需要执行prepareForSegue。如果你需要将信息传递给下一个基于被触摸行的控制器,你可以像下面这样做。表视图控制器代码现在应该是这样的(这是我对这个问题的回答Swift:TableView in Static UITableViewCell中代码的更新),
class ComboInfoViewController: UITableViewController {
@IBOutlet weak var staticTableView: UITableView!
@IBOutlet weak var dynamicTableView: UITableView!
var dataSource = DataSource()
override func viewDidLoad() {
super.viewDidLoad()
dynamicTableView.dataSource = dataSource
dynamicTableView.delegate = dataSource
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row != 1 {
return 44
}else{
return 250 // the second cell has the dynamic table view in it
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "tosingle" {
var cell = sender as! UITableViewCell
var indexPath = dynamicTableView.indexPathForCell(cell)
var dataPoint = dataSource.theData[indexPath!.row] // theData is the array used to populate the dynamic table view in the DataSource class
// pass dataPoint to the next view controller which you get from segue.destinationviewController
println(dataPoint)
}
}
}