переключение на вкладку tabbar программно?

<p>допустим, в моем приложении для iphone есть <code>uibutton</code> в виде одной вкладки, и я хочу, чтобы он открывал другую вкладку в панели вкладок <code>tabbarcontroller</code>. как бы я написал код для этого? </p><p>я предполагаю, что я выгружаю существующее представление и загружаю определенное представление вкладки, но я не уверен, как написать код точно.</p>

<p>попробуйте этот код в swift или objective-c<br></p><p><strong> свифт </strong></p><pre><code>self.tabbarcontroller.selectedindex = 1 </code></pre><p><strong> objective-c </strong> </p><pre><code>[self.tabbarcontroller setselectedindex:1]; </code></pre>

<p>обратите внимание, что вкладки индексируются, начиная с 0. таким образом, работает следующий фрагмент кода</p><pre><code>tabbarcontroller = [[uitabbarcontroller alloc] init]; . . . tabbarcontroller.selectedviewcontroller = [tabbarcontroller.viewcontrollers objectatindex:4]; </code></pre><p>идет к пятой вкладке в панели.</p>

<p>мое мнение таково, что <code>selectedindex</code> или использование <code>objectatindex</code> не обязательно лучший способ переключения вкладки. если вы переупорядочиваете свои вкладки, выбор жестко закодированного индекса может испортить ваше прежнее поведение приложения.</p><p>если у вас есть ссылка на объект контроллера представления, на который вы хотите переключиться, вы можете сделать:</p><pre><code>tabbarcontroller.selectedviewcontroller = myviewcontroller </code></pre><p>конечно, вы должны убедиться, что <code>myviewcontroller</code> действительно находится в списке <code>tabbarcontroller.viewcontrollers</code>.</p>

<p>вы можете просто установить свойство <code>selectedindex</code> в uitabbarcontroller на соответствующий индекс, и представление будет изменено так же, как пользователь нажал кнопку табуляции.</p>

<p>я попробовал то, что предложил disco s2, это было близко, но это то, что в итоге сработало для меня. это было вызвано после выполнения действия внутри другой вкладки.</p><pre><code>for (uinavigationcontroller *controller in self.tabbarcontroller.viewcontrollers) { if ([controller iskindofclass:[myviewcontroller class]]) { [self.tabbarcontroller setselectedviewcontroller:controller]; break; } } </code></pre>

<p>для случаев, когда вы можете перемещать вкладки, вот некоторый код.</p><pre><code>for ( uinavigationcontroller *controller in self.tabbarcontroller.viewcontrollers ) { if ( [[controller.childviewcontrollers objectatindex:0] iskindofclass:[myviewcontroller class]]) { [self.tabbarcontroller setselectedviewcontroller:controller]; break; } } </code></pre>

<p>я хотел иметь возможность указать, какая вкладка должна отображаться по классу, а не по индексу, так как я думал, что это сделано для надежного решения, которое в меньшей степени зависит от того, как вы подключите ib. я не нашел ни решений disco, ни joped для работы, поэтому я создал этот метод:</p><pre><code>-(void)settab:(class)class{ int i = 0; for (uinavigationcontroller *controller in self.tabbarcontontroller.viewcontrollers){ if ([controller iskindofclass:class]){ break; } i++; } self.tabbarcontontroller.selectedindex = i; } </code></pre><p>вы называете это так:</p><pre><code>[self settab:[yourclass class]]; </code></pre><p>надеюсь, это кому-нибудь пригодится</p>

<pre><code>import uikit class tabbarviewcontroller: uitabbarcontroller,uitabbarcontrollerdelegate { //mark:- view life cycle override func viewdidload() { super.viewdidload() } override func didreceivememorywarning() { super.didreceivememorywarning() } //tabbar delegate method override func tabbar(\_ tabbar: uitabbar, didselect item: uitabbaritem) { let yourview = self.viewcontrollers![self.selectedindex] as! uinavigationcontroller yourview.poptorootviewcontroller(animated:false) } } </code></pre>

<p>используйте в файле <code>appdelegate.m</code>:</p><pre><code>(void)tabbarcontroller:(uitabbarcontroller *)tabbarcontroller didselectviewcontroller:(uiviewcontroller *)viewcontroller { nslog(@"selected index: %d", tabbarcontroller.selectedindex); if (viewcontroller == tabbarcontroller.morenavigationcontroller) { tabbarcontroller.morenavigationcontroller.delegate = self; } nsuinteger selectedindex = tabbarcontroller.selectedindex; switch (selectedindex) { case 0: nslog(@"click me %u",self.tabbarcontroller.selectedindex); break; case 1: nslog(@"click me again!! %u",self.tabbarcontroller.selectedindex); break; default: break; } } </code></pre>

<p>как и решение стюарта кларка, но для swift 3:</p><pre><code>func settab<t>(\_ myclass: t.type) { var i: int = 0 if let controllers = self.tabbarcontroller?.viewcontrollers { for controller in controllers { if let nav = controller as? uinavigationcontroller, nav.topviewcontroller is t { break } i = i+1 } } self.tabbarcontroller?.selectedindex = i } </code></pre><p>используйте это так:</p><pre><code>settab(myviewcontroller.self) </code></pre><p>обратите внимание, что моя tabcontroller ссылается на viewcontrollers за навигационными контроллерами. без navigationcontrollers это выглядело бы так:</p><pre><code>if let controller is t { </code></pre>

<p>как и решение стюарта кларка, но для swift 3 и использования идентификатора восстановления, чтобы найти правильную вкладку:</p><pre><code>private func settabbyid(id: string) { var i: int = 0 if let controllers = self.tabbarcontroller?.viewcontrollers { for controller in controllers { if let nav = controller as? uinavigationcontroller, nav.topviewcontroller?.restorationidentifier == id { break } i = i+1 } } self.tabbarcontroller?.selectedindex = i } </code></pre><p>используйте его следующим образом («люди» и «роботы» также должны быть установлены в раскадровке для определенного viewcontroller и его идентификатора восстановления, или используйте идентификатор раскадровки и отметьте «использовать идентификатор раскадровки» в качестве идентификатора восстановления):</p><pre><code>struct tabs { static let humans = "humans" static let robots = "robots" } settabbyid(id: tabs.robots) </code></pre><p>обратите внимание, что моя tabcontroller ссылается на viewcontrollers за навигационными контроллерами. без navigationcontrollers это выглядело бы так:</p><pre><code>if controller.restorationidentifier == id { </code></pre>

<p>моя проблема немного отличается, мне нужно переключиться с одного childviewcontroller в 1-й tabbar на домашний viewcontroller 2-й tabbar. я просто использую решение, предоставленное наверху:</p><pre><code>tabbarcontroller.selectedindex = 2 </code></pre><p>однако, когда он переключился на домашнюю страницу 2-й вкладки, контент становится невидимым. и когда я отлаживаю viewdidappear, viewwillappear, viewdidload, ни один из них не вызывается . мои решения - добавить следующий код в uitabbarcontroller:</p><pre><code>override var shouldautomaticallyforwardappearancemethods: bool { return true } </code></pre>