didSelectViewController не вызывается, когда в разделе «Больше» - PullRequest
9 голосов
/ 27 апреля 2011

У меня есть UITabBarController, и я настроил его метод делегата didSelectViewController, так как меня интересует индекс выбранной вкладки.

Однако я заметил, что метод didSelectViewController не вызывается, когда пользователь находится в разделе «Еще» (когда вкладок больше, чем можно отобразить на панели вкладок):

The problematic section

Могу ли я получить уведомление об элементах, которые пользователь выбирает из автоматически создаваемой таблицы?

Ответы [ 2 ]

8 голосов
/ 27 апреля 2011

Я нашел то, что мне было нужно в этом вопросе .

В основном вы настроили UITabBarControllerDelegate и a UINavigationControllerDelegate для отображаемого контроллера навигации.внутри вкладки Больше.После этого вы обнаруживаете, нажал ли пользователь одну из видимых вкладок или вкладку «Еще».

РЕДАКТИРОВАТЬ

Кроме того, чтобы напрямую манипулировать таблицей, которая отображается в навигации «Больше»В контроллере вы можете настроить делегата табличного представления «человек посередине», который перехватывает вызовы исходного делегата.См. Код изнутри 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:forIndexPath:).Смотрите пример ниже:

- (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];
}
0 голосов
/ 05 сентября 2018

Предыдущий ответ почти правильный, потому что в нем отсутствует один метод для правильной работы.

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.

Примечание:

Возможна проблема с перехватом делегата, если Apple решит внедрить какой-либо другой метод делегата в свой собственный UIMoreListController в будущих версиях iOS.

...