我试图从viewController中分离dataSource和delegate,以防止viewController变得混乱。我阅读了一些帖子,发现我可以像下面那样分开dataSource,创建一个代表dataSource
的类:
import UIKit
class DataSource: NSObject, UITableViewDataSource, UITableViewDelegate {
var movies = [String]()
//MARK: - UITableViewDataSource
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return movies.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = movies[indexPath.row]
return cell
}
}
我的问题是:如果我想在viewController
课程中使用属性或调用DataSource
类的方法,我该怎么办?例如,我想在用户选择单元格时调用presentViewController
:
func tableView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
//do something here
presentViewController(viewController!, animated: true, completion: nil)
}
答案 0 :(得分:6)
您可以处理选定的回调:
class DataSource: NSObject, UITableViewDataSource, UITableViewDelegate {
var movies = [String]()
private var selectedCallback = ((NSIndexPath)->Void)?
func selectedItemAtIndex(callback:(NSIndexPath) -> Void) {
selectedCallback = callback
}
}
回调:
func tableView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
//do something here
if let callback = selectedCallback {
callback(indexPath)
}
}
使用:
dataSource.selectedItemAtIndex() {
[weak self] indexPath in
// do something ...
// presentViewController(viewController!, animated: true, completion: nil)
}
答案 1 :(得分:1)
您不希望将数据源与presentViewController
等导航逻辑耦合。相反,您的数据源可以有一个委托,数据源将告诉委托用户执行了某个操作。这样,委托不需要知道像indexPaths这样的细节;数据源的委托可以是拥有collectionView的collectionView和dataSource的viewController。
UIViewController:具有属性UICollectionView和属性YourDataSource。 viewController将自己设置为YourDataSource实例的委托。在YourDataSource的collectionViewDidSelectItemAtIndexPath
的实现中,您可以检索位于该indexPath的影片,并使用类似
func dataSource(dataSource: YourDataSource, didSelectMovie movie: YourMovieClass)
这将很好地使viewController不知道如何选择这部电影,并且可以为这部电影创建,设置和呈现一个新的viewController。
答案 2 :(得分:0)
我正在搜索同样的东西并使用了@Unhtu的答案。在实施的过程中,我提出了一些更容易的事情。
阻止作为参数
class DataSource: NSObject, UITableViewDataSource, UITableViewDelegate
{
private var selectedCallback : ((NSIndexPath)->Void)? // declaring a parameter
func tableView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
//Accessing the parameter
if let callback = selectedCallback {
callback(indexPath)
}
}
将参数值分配到ViewController
var dataSource = DataSource()
// Assigning the value to the parameter
dataSource. selectedCallback = {
indexPath in
// do something ...
presentViewController(viewController!, animated: true, completion: nil)
}