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