Подтвердить что ты не робот

Обнаруживать, когда нажимается элемент панели вкладок

У меня есть контроллер корневого представления, который не установлен как пользовательский класс для любого из моих контроллеров представления на моем раскадровке. Вместо этого все мои контроллеры представлений подклассифицируют этот класс следующим образом.

// RootViewController
class RootViewController: UIViewController, UITabBarDelegate { 

    // This is not getting executed on any of the view controllers
    func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
        print("ddd")
    }
}

// Subclassing it 
class TopStoriesViewController: RootViewController {

}

Но я, похоже, изо всех сил пытаюсь что-то сделать, когда на контроллере представлений накладывается tabbaritem, который подклассифицирует rootviewcontroller, то есть сообщение не печатается.

4b9b3361

Ответ 1

Вы не хотите, чтобы ваш базовый класс контроллера представления был UITabBarDelegate. Если бы вы сделали это, все ваши подклассы контроллера представления были бы делегатами панели вкладок. Я думаю, что вы хотите сделать, это расширить UITabBarController, что-то вроде этого:

class MyTabBarController: UITabBarController, UITabBarControllerDelegate {

затем в этом классе переопределите viewDidLoad и установите для свойства делегата значение self:

self.delegate = self

Примечание: это настройка делегата контроллера панели вкладок. У панели вкладок есть собственный делегат (UITabBarDelegate), которым управляет контроллер панели вкладок, и вам не разрешено изменять.

Итак, теперь этот класс является как UITabBarDelegate (потому что UITabBarController реализует этот протокол), так и UITabBarControllerDelegate, и вы можете переопределять/реализовывать эти методы делегата по желанию, такие как:

// UITabBarDelegate
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
    print("Selected item")
}

// UITabBarControllerDelegate
func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {
    print("Selected view controller")
}

Я предполагаю, что вы, вероятно, больше заинтересованы в последнем. Ознакомьтесь с документацией, чтобы увидеть, что предоставляет каждый из этих делегатов.

И последнее, что в вашей раскадровке (если вы используете раскадровки), установите класс контроллера панели вкладок на MyTabBarController в Identity Inspector, и все готово.

Свифт 3/4

// UITabBarDelegate
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    print("Selected item")
}

// UITabBarControllerDelegate
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
    print("Selected view controller")
}

Ответ 2

Это вызвало у меня ошибку

Изменение делегата панели вкладок, управляемого контроллером панели вкладок, не допускается

Это то, что я сделал, и это сработало

  1. В вашем ViewController вы наследуете UITabBarControllerDelegate
  2. Установить делегата в viewDidLoad
  3. Добавить функцию

Пример:

class MyClass: UIViewController, UITabBarControllerDelegate {

   func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        let tabBarIndex = tabBarController.selectedIndex
        if tabBarIndex == 0 {
            //do your stuff
        }
   }

   override func viewDidLoad() {
        super.viewDidLoad()
        self.tabBarController?.delegate = self
   }

}

Ответ 3

Вот версия ответа @mbeaty с немного большим контекстом. Это адаптировано из моего более полного ответа здесь.

import UIKit

class MyTabBarController: UITabBarController, UITabBarControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        // tell our UITabBarController subclass to handle its own delegate methods
        self.delegate = self
    }

    // called whenever a tab button is tapped
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {

        if let firstVC = viewController as? FirstViewController {
            firstVC.doSomeAction()
        }

        if viewController is FirstViewController {
            print("First tab")
        } else if viewController is SecondViewController {
            print("Second tab")
        }
    }

    // alternate method if you need the tab bar item
    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
        // ...
    }
}

Установите это как пользовательский класс вашего Tab View Controller в IB.

enter image description here

Альтернативное решение

  • Просто сделайте что-нибудь в методе viewDidLoad контроллера представления вкладок. Смотрите этот ответ.

Ответ 4

Я использовал этот код, потому что мне нужно знать, что выбран тот же контроллер представления.

import UIKit

protocol CustomTabBarControllerDelegate {
    func onTabSelected(isTheSame: Bool)
}

class CustomTabBarController: UITabBarController, UITabBarControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
    }

    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        (viewController as? CustomTabBarControllerDelegate)?.onTabSelected(isTheSame: selectedViewController == viewController)
        return true
    }
}


class Tab1ViewController: CustomTabBarControllerDelegate {
    func onTabSelected(isTheSame: Bool) { 
        //do something
    }
}


class Tab2ViewController: CustomTabBarControllerDelegate {
    func onTabSelected(isTheSame: Bool) { 
        //do something
    }
}