如何在视图控制器中实现两个集合视图?
How to implementing two collection view inside of view controller?
嗨,我是 Swift 编程语言的初学者,我在视图控制器内部实现两个集合视图时遇到问题,这是我想要实现的 link 图片:
可能吗?到目前为止,我的代码似乎不起作用:
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UICollectionViewDataSource, UICollectionViewDelegate{
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var collectionViewTwo: UICollectionView!
var optionOne = ["Gulsah", "Hurrem", "Mihrimah", "Nilufer"]
override func viewDidLoad() {
super.viewDidLoad()
self.resetFilterThumbnails()
self.collectionView.delegate = self
}
//For the collectionView, number of filters in the section
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if (filters == true){
//do all the stuff here for FILTER_CELL
return self.filters.count}
else{
return self.optionOne.count}
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("FILTER_CELL", forIndexPath: indexPath) as FilterThumbnailCell
let cellTwo = collectionView.dequeueReusableCellWithReuseIdentifier("FILTER_CELL_TWO", forIndexPath: indexPath) as FilterThumbnailCell
var filterThumbnail = self.filterThumbnails[indexPath.row]
println("filter cell two")
if (indexPath.item == 0){
//do all the stuff here for FILTER_CELL
if filterThumbnail.filteredThumbnail != nil {
cell.imageView.image = filterThumbnail.filteredThumbnail
} else {
cell.imageView.image = filterThumbnail.originalThumbnail
//filterThumbnail is a class instance
filterThumbnail.generateThumbnail({ (image) -> Void in
if let cell = collectionView.cellForItemAtIndexPath(indexPath) as? FilterThumbnailCell {
cell.imageView.image = image
}
})
}
return cell
}else{
//FILTER_CELL_TWO
var button = cellTwo.viewWithTag(1) as UILabel
button.text = optionOne[indexPath.row]
cellTwo.backgroundColor = UIColor.redColor()
return cellTwo
}
}
}
这是很有可能的。您可以通过多种方式做到这一点。
1:
您可以实现两个包含的视图控制器。这可能是最干净的,因为您可以在单独的控制器中处理交互。在这种情况下,您可能还需要实现一些 delegate/protocols 以将信息传递回 parentViewController。
2:
您可以创建一个单独的 datasource/delegate class 来处理每个视图控制器的关联函数,并在 viewDidLoad 中分配它们。这种情况可能还需要实现 delegates/protocols 以从 collectionView dataSource/Delegate class.
传递信息
这是一个示例,取自主从 class 像这样创建您的 class(如果需要,添加符合 UITableViewDelegate 的内容):
import UIKit
class MyDataSource: NSObject, UITableViewDataSource {
var objects = [AnyObject]()
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return objects.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let object = objects[indexPath.row] as NSDate
cell.textLabel!.text = object.description
return cell
}
}
然后在您的 UIViewController 中创建一个类型为 MyDataSource 的变量:
var dataSource1 = MyDataSource()
var dataSource2 = MyDataSource()
在 viewDidLoad 内部,您可以将其对象分配给数据源并将数据源分配给表视图:
dataSource1.objects = objects1;
dataSource2.objects = objects2;
tableView1.dataSource = dataSource1
tableView2.dataSource = dataSource2
现在每个表视图都将使用此数据源的不同实例,具有自己的一组模型对象。如果您需要进一步自定义您的数据源(就像您所做的那样)只需创建另一个数据源 class 并将其分配给适当的对象。如果你在这些数据源对象中遵循表视图的委托,你应该为数据源实现一个标准协议,并在你的视图控制器中遵循该协议:
数据源对象上方:
protocol DataSourceDelegate{
func didSelectCellAtIndexPath(indexPath:NSIndexPath)
}
数据源对象内部:
var dataSourceDelegate:DataSourceDelegate?
视图控制器内部:
dataSource.dataSourceDelegate = self
确保符合class定义中的委托。然后实例化视图控制器中的方法:
func didSelectCellAtIndexPath(indexPath:NSIndexPath){
// Your code here
}
确保在数据源中调用委托
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
dataSourceDelegate?.didSelectCellAtIndexPath(indexPath)
}
要注册单元格,如果您使用的是故事板,只需确保单元格标识符是正确的即可,您不需要注册任何其他内容。如果没有,您可以在数据源中注册单元格(可能是个好主意,因为它会保留所有信息)
3:
您可以使用一个 viewController 并通过将传递到 dataSource/Delegate 函数的 collectionView 与连接到视图中相应 collectionView 的出口进行比较来区分不同情况。虽然这种情况不需要实现任何委托,但它会用大量 if/else 语句填充 viewController,可能会使代码更难 maintain/read.
嗨,我是 Swift 编程语言的初学者,我在视图控制器内部实现两个集合视图时遇到问题,这是我想要实现的 link 图片:
可能吗?到目前为止,我的代码似乎不起作用:
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UICollectionViewDataSource, UICollectionViewDelegate{
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var collectionViewTwo: UICollectionView!
var optionOne = ["Gulsah", "Hurrem", "Mihrimah", "Nilufer"]
override func viewDidLoad() {
super.viewDidLoad()
self.resetFilterThumbnails()
self.collectionView.delegate = self
}
//For the collectionView, number of filters in the section
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if (filters == true){
//do all the stuff here for FILTER_CELL
return self.filters.count}
else{
return self.optionOne.count}
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("FILTER_CELL", forIndexPath: indexPath) as FilterThumbnailCell
let cellTwo = collectionView.dequeueReusableCellWithReuseIdentifier("FILTER_CELL_TWO", forIndexPath: indexPath) as FilterThumbnailCell
var filterThumbnail = self.filterThumbnails[indexPath.row]
println("filter cell two")
if (indexPath.item == 0){
//do all the stuff here for FILTER_CELL
if filterThumbnail.filteredThumbnail != nil {
cell.imageView.image = filterThumbnail.filteredThumbnail
} else {
cell.imageView.image = filterThumbnail.originalThumbnail
//filterThumbnail is a class instance
filterThumbnail.generateThumbnail({ (image) -> Void in
if let cell = collectionView.cellForItemAtIndexPath(indexPath) as? FilterThumbnailCell {
cell.imageView.image = image
}
})
}
return cell
}else{
//FILTER_CELL_TWO
var button = cellTwo.viewWithTag(1) as UILabel
button.text = optionOne[indexPath.row]
cellTwo.backgroundColor = UIColor.redColor()
return cellTwo
}
}
}
这是很有可能的。您可以通过多种方式做到这一点。
1:
您可以实现两个包含的视图控制器。这可能是最干净的,因为您可以在单独的控制器中处理交互。在这种情况下,您可能还需要实现一些 delegate/protocols 以将信息传递回 parentViewController。
2:
您可以创建一个单独的 datasource/delegate class 来处理每个视图控制器的关联函数,并在 viewDidLoad 中分配它们。这种情况可能还需要实现 delegates/protocols 以从 collectionView dataSource/Delegate class.
传递信息这是一个示例,取自主从 class 像这样创建您的 class(如果需要,添加符合 UITableViewDelegate 的内容):
import UIKit
class MyDataSource: NSObject, UITableViewDataSource {
var objects = [AnyObject]()
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return objects.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let object = objects[indexPath.row] as NSDate
cell.textLabel!.text = object.description
return cell
}
}
然后在您的 UIViewController 中创建一个类型为 MyDataSource 的变量:
var dataSource1 = MyDataSource()
var dataSource2 = MyDataSource()
在 viewDidLoad 内部,您可以将其对象分配给数据源并将数据源分配给表视图:
dataSource1.objects = objects1;
dataSource2.objects = objects2;
tableView1.dataSource = dataSource1
tableView2.dataSource = dataSource2
现在每个表视图都将使用此数据源的不同实例,具有自己的一组模型对象。如果您需要进一步自定义您的数据源(就像您所做的那样)只需创建另一个数据源 class 并将其分配给适当的对象。如果你在这些数据源对象中遵循表视图的委托,你应该为数据源实现一个标准协议,并在你的视图控制器中遵循该协议:
数据源对象上方:
protocol DataSourceDelegate{
func didSelectCellAtIndexPath(indexPath:NSIndexPath)
}
数据源对象内部:
var dataSourceDelegate:DataSourceDelegate?
视图控制器内部:
dataSource.dataSourceDelegate = self
确保符合class定义中的委托。然后实例化视图控制器中的方法:
func didSelectCellAtIndexPath(indexPath:NSIndexPath){
// Your code here
}
确保在数据源中调用委托
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
dataSourceDelegate?.didSelectCellAtIndexPath(indexPath)
}
要注册单元格,如果您使用的是故事板,只需确保单元格标识符是正确的即可,您不需要注册任何其他内容。如果没有,您可以在数据源中注册单元格(可能是个好主意,因为它会保留所有信息)
3:
您可以使用一个 viewController 并通过将传递到 dataSource/Delegate 函数的 collectionView 与连接到视图中相应 collectionView 的出口进行比较来区分不同情况。虽然这种情况不需要实现任何委托,但它会用大量 if/else 语句填充 viewController,可能会使代码更难 maintain/read.