在嵌入在 UITableviewCell 中的 UICollectionView 中进行 Segue,Swift
Posted
技术标签:
【中文标题】在嵌入在 UITableviewCell 中的 UICollectionView 中进行 Segue,Swift【英文标题】:Segue in a UICollectionView embedded in a UITableviewCell, Swift 【发布时间】:2017-09-25 08:29:50 【问题描述】:我在UITableViewCell
中创建了一个UICollectionView
,效果很好。我唯一的问题是,我无法在 didSelectItemAt
方法上对另一个 ViewController
执行 Segue。
我知道我必须从 TableViewController 执行它,我在 Storyboard 上做了一个 segue,我尝试了多种可能性,但由于某些原因它不起作用。
这里是我的TableviewController
:
import UIKit
import RealmSwift
import SwiftyJSON
class HomeVTwoTableViewController: UITableViewController
let realm = try! Realm()
let headers = ["1","2","3"]
override func viewDidLoad()
super.viewDidLoad()
override func viewWillAppear(_ animated: Bool)
self.tableView.separatorStyle = .none
//MARK: Custom Tableview Headers
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
return headers[section]
//MARK: DataSource Methods
override func numberOfSections(in tableView: UITableView) -> Int
return headers.count
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 1
//Choosing the responsible PrototypCell for the Sections
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
if indexPath.section == 0
let cell = tableView.dequeueReusableCell(withIdentifier: "cellBig", for: indexPath) as! HomeVTwoTableViewCell
cell.update()
return cell
else
return UITableViewCell()
// This on of my tries to perform a segue
func liveCellSelected()
performSegue(withIdentifier: "showChat", sender: nil)
这里是我的TableViewCell
和嵌入的CollectionView
:
import UIKit
import RealmSwift
class HomeVTwoTableViewCell: UITableViewCell
var liveCommunities: Results<Community>?
@IBOutlet weak var collectionView: UICollectionView!
override func awakeFromNib()
super.awakeFromNib()
collectionView.delegate = self
collectionView.dataSource = self
extension HomeVTwoTableViewCell:
UICollectionViewDataSource,UICollectionViewDelegate
func numberOfSections(in collectionView: UICollectionView) -> Int
return 1
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return(liveCommunities?.count)!
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCellBig", for: indexPath) as? HomeVTwoCollectionViewCell else
fatalError("Cell has wrong type")
//removes the old image
cell.imageView.image = UIImage(named: "No Image")
cell.titleLbl.text = nil
//set url and Picture
url = (liveCommunities?[indexPath.row].pictureId)!
let name : String = (liveCommunities?[indexPath.row].communityName)!
let channelName : String = (liveCommunities?[indexPath.row].channelName)!
cell.titleLbl.text = name
cell.senderLbl.text = channelName
cell.imageView.downloadedFrom(link :"someSecretUrl")
return cell
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
selectedCommunity = (liveCommunities?[indexPath.row].communityId)!
HomeVTwoTableViewController().liveCellSelected()
我发现another question 具有类似的主题,但无法实现委托协议而不会对现有委托产生问题。
也许这是一个明显的错误,但我看不到。 提前致谢。
【问题讨论】:
【参考方案1】:你正在用这个实例化你的家庭控制器的一个新实例:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
selectedCommunity = (liveCommunities?[indexPath.row].communityId)!
HomeVTwoTableViewController().liveCellSelected()
你应该做的是通过委托来实现,或者你将你的collectionview委托移动到主控制器
protocol CellCollectionViewDelegate: class
func didselect()
然后你在单元格和你的家庭控制器中实现委托
【讨论】:
感谢您的回答。在问这个问题之前,我实际上尝试过这个。我这样尝试:protocol CellCollectionViewDelegate: class func didSelect()
并定义了在 didselect 中调用它的变量weak var delegate: CellCollectionViewDelegate?
,并在控制器中进行了这样的扩展:extension HomeVTwoTableViewController: CellCollectionViewDelegate func didSelect() performSegue(withIdentifier: "showChat", sender: nil)
但它不起作用。也许你可以帮助我。
你必须在 cellforrow 函数中设置 delegate = self
感谢您的回答。我有 CollectionView.delegate = self 并且如果不弄乱第一个就无法实现另一个。
我的意思是 cell.delegate 不是 collectionview 委托【参考方案2】:
也许你可以创建一个变量来处理这个问题。你也可以做可选的。
class HomeVTwoTableViewCell: UITableViewCell
var liveCommunities: Results<Community>?
@IBOutlet weak var collectionView: UICollectionView!
var didSelectAction: () -> Void // add your action here
这里可以调用这个函数
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
selectedCommunity = (liveCommunities?[indexPath.row].communityId)!
HomeVTwoTableViewController().liveCellSelected()
didSelectAction() // Invoque your action
//在单元格创建器上,添加要点击单元格时的导航或逻辑
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
if indexPath.section == 0
let cell = tableView.dequeueReusableCell(withIdentifier: "cellBig", for: indexPath) as! HomeVTwoTableViewCell
cell.update()
cell.didSelectAction =
// add here your navigation
return cell
else
return UITableViewCell()
【讨论】:
感谢您的回复。但是,如果我尝试您的方法,我会收到“Class 'HomeVTwoTableViewCell' has no initializers”错误。 解决这个问题...您可以将其设为可选或分配空函数 var didSelectAction: (() -> Void ) ?或 var didSelectAction: () -> Void = 谢谢,现在它可以工作了。但这是最好的解决方案吗?它似乎有点复杂?你怎么看? 委托模式可能更容易【参考方案3】:好吧,这个问题似乎有两个解决方案。 一种是通过变量,一种是通过委托。据我所知,委托更常见。
带变量的解决方案 1:
这里是我的TableviewController
:
import UIKit
class TableViewController: UITableViewController
let headers = ["1","2","3"]
override func viewDidLoad()
super.viewDidLoad()
override func numberOfSections(in tableView: UITableView) -> Int
return headers.count
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 1
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "cellBig", for: indexPath) as! HomeVTwoTableViewCell
//Fill function, insert Navigation
cell.didSelectAction =
self.performSegue(withIdentifier: "testSegue", sender: nil)
return cell
这里是我的TableViewCell
和嵌入的CollectionView
:
import UIKit
class HomeVTwoTableViewCell: UITableViewCell
var liveCommunities: Results<Community>?
//Instantiate function
var didSelectAction: () -> Void =
@IBOutlet weak var collectionView: UICollectionView!
override func awakeFromNib()
super.awakeFromNib()
collectionView.delegate = self
collectionView.dataSource = self
extension HomeVTwoTableViewCell:
UICollectionViewDataSource,UICollectionViewDelegate
func numberOfSections(in collectionView: UICollectionView) -> Int
return 1
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return(liveCommunities?.count)!
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCellBig", for: indexPath) as? HomeVTwoCollectionViewCell else
fatalError("Cell has wrong type")
//removes the old text
cell.titleLbl.text = nil
cell.senderLbl.text = nil
let name : String = (liveCommunities?[indexPath.row].communityName)!
let channelName : String = (liveCommunities?[indexPath.row].channelName)!
cell.titleLbl.text = name
cell.senderLbl.text = channelName
return cell
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
selectedCommunity = (liveCommunities?[indexPath.row].communityId)!
// Invoque your action
didSelectAction()
使用委托和协议的解决方案 2:
这里是我的TableviewController
:
import UIKit
class TableViewController: UITableViewController
let headers = ["1","2","3"]
override func viewDidLoad()
super.viewDidLoad()
override func numberOfSections(in tableView: UITableView) -> Int
return headers.count
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 1
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "cellBig", for: indexPath) as! HomeVTwoTableViewCell
//Add delegate
cell.delegate = self
return cell
//Add Extension with Navigation
extension HomeVTwoTableViewController: CellCollectionViewDelegate
func didSelect()
performSegue(withIdentifier: "showChat", sender: nil)
这里是我的TableViewCell
和嵌入的CollectionView
:
import UIKit
//Create a delegate protocol
protocol CellCollectionViewDelegate: class
func didSelect()
class HomeVTwoTableViewCell: UITableViewCell
var liveCommunities: Results<Community>?
//Add a delegate property
weak var delegate: CellCollectionViewDelegate?
@IBOutlet weak var collectionView: UICollectionView!
override func awakeFromNib()
super.awakeFromNib()
collectionView.delegate = self
collectionView.dataSource = self
//Adopt and implement the Delegate Protocol
extension HomeVTwoTableViewCell:
UICollectionViewDataSource,UICollectionViewDelegate
func numberOfSections(in collectionView: UICollectionView) -> Int
return 1
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return(liveCommunities?.count)!
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCellBig", for: indexPath) as? HomeVTwoCollectionViewCell else
fatalError("Cell has wrong type")
//removes the old text
cell.titleLbl.text = nil
cell.senderLbl.text = nil
let name : String = (liveCommunities?[indexPath.row].communityName)!
let channelName : String = (liveCommunities?[indexPath.row].channelName)!
cell.titleLbl.text = name
cell.senderLbl.text = channelName
return cell
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
selectedCommunity = (liveCommunities?[indexPath.row].communityId)!
//call delegate method
delegate?.didSelect()
我试图总结来自
的解决方案Abdoelrhman Mohamed 和 Alexkater 并详细写出来。
如果有问题或遗漏,请告诉我。
【讨论】:
以上是关于在嵌入在 UITableviewCell 中的 UICollectionView 中进行 Segue,Swift的主要内容,如果未能解决你的问题,请参考以下文章
在嵌入在 UITableviewCell 中的 UICollectionView 中进行 Segue,Swift
嵌入在 UITableViewCell 中的动态、自定义布局 UICollectionView
如何为嵌入在 UITableViewCell 中的 UIView 设置动画
如何从嵌入在 UITableViewCell (Swift) 中的 UICollectionView 的单元格中分离出来?