Ios didSelectViewController在“中”时未被调用;“更多”;部分

Ios didSelectViewController在“中”时未被调用;“更多”;部分,ios,delegates,uitabbarcontroller,Ios,Delegates,Uitabbarcontroller,我有一个UITabBarController,我设置了它的委托方法didSelectViewController,因为我对所选选项卡的索引感兴趣 但是,我注意到当用户在“更多”部分时(当选项卡超过选项卡栏显示的选项卡数时),不会调用didSelectViewController方法: 有没有办法通知我用户从自动创建的表中选择的项目?我在中找到了所需的内容 基本上,您可以为显示在“更多”选项卡内的导航控制器设置一个UIAbbarController远程门和一个UINavigationContro

我有一个UITabBarController,我设置了它的委托方法
didSelectViewController
,因为我对所选选项卡的索引感兴趣

但是,我注意到当用户在“更多”部分时(当选项卡超过选项卡栏显示的选项卡数时),不会调用
didSelectViewController
方法:

有没有办法通知我用户从自动创建的表中选择的项目?

我在中找到了所需的内容

基本上,您可以为显示在“更多”选项卡内的导航控制器设置一个
UIAbbarController远程门
和一个
UINavigationController远程门
。之后,您将检测用户是否触摸了其中一个可见选项卡或“更多”选项卡

编辑

此外,要直接操作“更多”导航控制器中可见的表,可以设置一个“中间人”表视图委托,该委托拦截对原始委托的调用。请参见下面的代码
didSelectViewController

if (viewController == tabBarController.moreNavigationController && tabBarController.moreNavigationController.delegate == nil) {
    // here we replace the "More" tab table delegate with our own implementation
    // this allows us to replace viewControllers seamlessly

    UITableView *view = (UITableView *)self.tabBarController.moreNavigationController.topViewController.view;
    self.originalDelegate = view.delegate;
    view.delegate = self;
}
之后,只要在另一个委托中调用相同的方法,您就可以在委托方法中自由地执行任何您喜欢的操作(我实际上检查了原始委托响应的方法,唯一实现的委托方法是
didSelectRow:forindexath:
)。请参见下面的示例:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // this is the delegate for the "More" tab table
    // it intercepts any touches and replaces the selected view controller if needed
    // then, it calls the original delegate to preserve the behavior of the "More" tab

    // do whatever here 
    // and call the original delegate afterwards
    [self.originalDelegate tableView: tableView didSelectRowAtIndexPath: indexPath];
}

前面的答案几乎是正确的,因为它遗漏了一种正常工作的方法

class MyClass: ... {

    var originalTableDelegate: UITableViewDelegate?
}

extension MyClass: UITabBarControllerDelegate {

    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        if viewController == tabBarController.moreNavigationController && originalTableDelegate == nil {
            if let moreTableView = tabBarController.moreNavigationController.topViewController?.view as? UITableView {
                originalTableDelegate = moreTableView.delegate
                moreTableView.delegate = self
            }
        }
    }
}

extension MyClass: UITableViewDelegate {
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        originalTableDelegate!.tableView!(tableView, willDisplay: cell, forRowAt: indexPath)
    }
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("intercepted")
        originalTableDelegate?.tableView!(tableView, didSelectRowAt: indexPath)
    }
}
更多控制器上的原始表委托实际上是系统隐藏类
UIMoreListController
。如果我们查看一下它,我们会注意到这两个被覆盖的函数:
didSelect
willDisplay

注:


如果苹果决定在未来的iOS版本中在自己的
UIMoreListController
中实现其他委托方法,那么这个委托拦截可能会有潜在的问题。

我也尝试过解决这个问题。我可以知道他们何时点击更多,但要查看他们从更多的tableviewcontroller中选择哪个视图控制器,需要使用非公共api调用。您是否尝试过NSLog这两个委托以查看它是否不同?看起来是一样的。嗯,我已经完全忘记了这是怎么回事,因为那是将近7年前的事了。。。