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

iOS继承场景下父控制器配置及Filter代理订阅问题求助

iOS控制器继承链中父控制器配置方案

针对你的控制器继承链MenuViewController → FilterCollectionViewController → CollectionViewController → MapsViewController,要在MapsViewController中配置FilterCollectionViewController的代理,需要解决三个核心问题:代理属性的访问权限、父类方法的逻辑错误、代理赋值时机。

1. 暴露Filter层的代理属性

CollectionViewController作为FilterCollectionViewController的直接子类,默认无法直接访问父类的代理属性,需要在CollectionViewController中添加对父类代理的访问入口:

class CollectionViewController: FilterCollectionViewController {
    // 新增:暴露Filter层的代理属性,让子类可访问
    override var handlerFilterCellDelegate: IHandlerFilterCollectionDelegate! {
        get { super.handlerFilterCellDelegate }
        set { super.handlerFilterCellDelegate = newValue }
    }
    
    override var delegateSettingFilterCell: ISettingFilterCollectionDelegate! {
        get { super.delegateSettingFilterCell }
        set { super.delegateSettingFilterCell = newValue }
    }

    // 原有的其他代码保持不变...
}

2. 修正FilterCollectionViewController的代理调用错误

在FilterCollectionViewController的collectionView(_:didSelectItemAt:)方法中,错误调用了registerCell,应该触发代理的itemSelect方法:

extension FilterCollectionViewController: UICollectionViewDataSource, UICollectionViewDelegate  {
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        // 替换原错误代码,调用代理的点击方法
        handlerFilterCellDelegate.itemSelect(index: indexPath.row)
    }

    // 原有的其他代码保持不变...
}

3. 调整MapsViewController的代理赋值时机

父类的viewDidLoad会在子类初始化后优先执行,需要确保代理在父类配置UI前完成赋值,可调整初始化逻辑:

final class MapsViewController: CollectionViewController {
    init(menuDelegate: IMenuDelegate, itemMenu: MenuItem) {
        super.init()
        // 先设置Filter层的代理,再配置其他内容
        handlerFilterCellDelegate = self
        delegateSettingFilterCell = self
        
        headerMenu = HeaderMenuViewController(menuItem: itemMenu, delegate: menuDelegate)
        handlerCellDelegate = self
        delegateSettingCell = self
        
        print("Maps view controller \(itemMenu)")
    }

    // 实现Filter代理方法
    extension MapsViewController: IHandlerFilterCollectionDelegate {
        func itemSelect(index: Int) {
            // 处理筛选器单元格点击逻辑,比如更新筛选条件
            print("Filter cell selected at index: \(index)")
        }
    }

    extension MapsViewController: ISettingFilterCollectionDelegate {
        func createCell(collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            // 自定义筛选器单元格创建逻辑
            let filterModel = modelFilterForDisplay[indexPath.row]
            if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FilterCell.reuseIdentifier, for: indexPath) as? FilterCell {
                cell.titleLabel.text = filterModel.title
                return cell
            }
            return UICollectionViewCell()
        }

        func registerCell(collectionView: UICollectionView) {
            collectionView.register(FilterCell.self, forCellWithReuseIdentifier: FilterCell.reuseIdentifier)
        }

        func calculateCellSize(screenWidth: CGFloat) -> CGSize {
            // 自定义筛选器单元格尺寸
            return CGSize(width: 100, height: 40)
        }
    }

    // 原有的其他代码保持不变...
}

额外注意事项

  • 访问权限:确保所有代理属性、父类需要被子类访问的属性都设置为open或public,避免访问限制
  • 初始化顺序:父类的viewDidLoad会在子类初始化后立即执行,所以代理赋值要优先于父类的UI配置逻辑
  • 数据传递:如果需要在MapsViewController中更新筛选器数据,可以给FilterCollectionViewController添加公开的更新方法,比如:
    class FilterCollectionViewController: MenuViewController {
        // 新增:公开更新筛选数据的方法
        func updateFilterData(_ data: [IFilterCollectionModel]) {
            modelFilterForDisplay = data
            collectionFilterView.reloadData()
        }
    }
    
    然后在MapsViewController中直接调用updateFilterData即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 09:53:10