【问题标题】:Segue in a UICollectionView embedded in a UITableviewCell, Swift在嵌入在 UITableviewCell 中的 UICollectionView 中进行 Segue,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 具有类似的主题,但无法实现委托协议而不会对现有委托产生问题。

也许这是一个明显的错误,但我看不到。 提前致谢。

【问题讨论】:

    标签: ios swift uitableview swift3 uicollectionview


    【解决方案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 并详细写出来。

    如果有问题或遗漏,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-13
      • 1970-01-01
      • 2021-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-30
      相关资源
      最近更新 更多