You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过Xib类触发searchSegue时提示无此标识符的问题求助

解决从Xib单元格触发Segue时的"Has no segue with identifier"错误

这个问题我之前也踩过坑,核心原因特别明确——Segue是ViewController之间的跳转连接,你的SearchCategoryRowCell作为一个UIView子类(单元格),本身根本没有绑定任何Segue,所以直接在cell里调用performSegue肯定会找不到对应的标识符。下面给你几个靠谱的解决思路,优先推荐前两种:

方法一:用代理(Delegate)让父ViewController触发Segue

这是最规范的解耦做法,能让cell和ViewController各司其职:

  1. 先在SearchCategoryRowCell里定义代理协议:
protocol SearchCategoryRowCellDelegate: AnyObject {
    func searchCategoryCellDidTap(_ cell: SearchCategoryRowCell)
}

class SearchCategoryRowCell: UICollectionViewCell {
    weak var delegate: SearchCategoryRowCellDelegate?
    
    // 假设你的单元格点击事件绑定到这个方法
    @IBAction func cellTapped(_ sender: UIButton) {
        delegate?.searchCategoryCellDidTap(self)
    }
}
  1. 让SearchViewController遵守代理协议,并在创建cell时设置代理:
class SearchViewController: UICollectionViewController, SearchCategoryRowCellDelegate {
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SearchCategoryRowCell", for: indexPath) as! SearchCategoryRowCell
        cell.delegate = self
        return cell
    }
    
    // 实现代理方法,在这里触发Segue
    func searchCategoryCellDidTap(_ cell: SearchCategoryRowCell) {
        // 先拿到当前cell对应的数据源
        guard let indexPath = collectionView.indexPath(for: cell) else { return }
        let selectedCategory = yourDataArray[indexPath.item] // 替换成你的数据源数组
        
        // 由ViewController触发Segue,并传递数据
        performSegue(withIdentifier: "searchSegue", sender: selectedCategory)
    }
    
    // 重写prepare方法,给目标页面传数据
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "searchSegue" {
            let resultVC = segue.destination as! PhotoStreamViewController
            resultVC.selectedCategory = sender as? YourCategoryType // 替换成你的数据类型
        }
    }
}

方法二:用闭包(Closure)回调触发Segue

如果觉得代理太繁琐,闭包是更轻量的选择:

  1. 在SearchCategoryRowCell里添加闭包属性:
class SearchCategoryRowCell: UICollectionViewCell {
    var onTap: (() -> Void)?
    
    @IBAction func cellTapped(_ sender: UIButton) {
        onTap?()
    }
}
  1. 在SearchViewController的cellForItemAt里设置闭包逻辑:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SearchCategoryRowCell", for: indexPath) as! SearchCategoryRowCell
    
    // 绑定闭包,在cell点击时触发Segue
    cell.onTap = { [weak self] in
        guard let self = self else { return }
        let selectedCategory = self.yourDataArray[indexPath.item]
        self.performSegue(withIdentifier: "searchSegue", sender: selectedCategory)
    }
    
    return cell
}

同样别忘了在prepare(for:sender:)里给PhotoStreamViewController传递数据。

方法三:用通知(Notification)触发(不推荐)

这个方法耦合度很高,不利于后续维护,除非是临时测试场景才建议用:

  1. 在SearchCategoryRowCell的点击事件里发送通知:
@IBAction func cellTapped(_ sender: UIButton) {
    NotificationCenter.default.post(name: NSNotification.Name("SearchCategoryTapped"), object: self)
}
  1. 在SearchViewController里监听通知并触发Segue:
override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(handleCategoryTap), name: NSNotification.Name("SearchCategoryTapped"), object: nil)
}

@objc private func handleCategoryTap(_ notification: Notification) {
    guard let cell = notification.object as? SearchCategoryRowCell, 
          let indexPath = collectionView.indexPath(for: cell) else { return }
    let selectedCategory = yourDataArray[indexPath.item]
    performSegue(withIdentifier: "searchSegue", sender: selectedCategory)
}

// 记得在页面销毁时移除监听
deinit {
    NotificationCenter.default.removeObserver(self)
}

核心总结

不管用哪种方法,核心逻辑都是:让拥有Segue的SearchViewController来负责触发跳转,而不是让cell直接调用performSegue。优先选择代理或闭包,能保持代码的低耦合性,后续维护也更方便。

内容的提问来源于stack exchange,提问作者cyildirim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:42:34