簡単かもしれないと思っていたことが問題になっています。ルートビューコントローラーにテーブルがあり、行が選択されたら、新しいビューをプッシュし、そこから別のタブに移動します。
私の質問は、ユーザーが最初のタブをタップするとすぐにナビゲーションコントローラーがルートにポップすることを確認するにはどうすればよいですか?
タブバーで各タブが選択されているときに、次のデリゲートが呼び出されます。
-(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
このデリゲートメソッド内に次のコードを配置します。
if ([viewController isKindOfClass:[UINavigationController class]])
{
[(UINavigationController *)viewController popToRootViewControllerAnimated:NO];
}
私のアプリでは問題なく動作しています。
Swift愛好家の場合:
import UIKit
class YourTabBarControllerHere: UITabBarController,
UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self;
}
func tabBarController(tabBarController: UITabBarController,
didSelectViewController viewController: UIViewController) {
if let vc = viewController as? UINavigationController {
vc.popViewControllerAnimated(animated: false);
}
}
}
編集: Swift 3更新、それを指摘してくれた@JustinOrozに感謝します。
In Swift 3.1
UITabBarControllerDelegateをTabBarクラスに追加します。
クラスYourClass:UITabBarController、UITabBarControllerDelegate {
後:
func tabBar(tabBar:UITabBar、didSelectItem item:UITabBarItem){をオーバーライドします。
let yourView = self.viewControllers![self.selectedIndex] as! UINavigationController yourView .popToRootViewControllerAnimated(false)
}
あなたがやろうとしていることは少し奇妙に聞こえます。 UINavigationControllersとUITabBarControllersの組み合わせに関するヒューマンインターフェイスガイドラインを読みましたか?
ただし、実行する必要があるのは、UITabBarControllerのデリゲートを設定し、tabBarController:didSelectViewController:デリゲートメソッドを実装することにより、タブの選択を検出することです。このメソッドでは、UINavigationControllerのpopToRootViewControllerAnimated:メソッドを使用してルートビューコントローラーにポップバックする必要があります。
[self.navigationController popToRootViewControllerAnimated:NO];
これを試して。
class TabBarClass: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
let vc = self.viewControllers![selectedIndex] as! UINavigationController
vc.popToRootViewController(animated: false)
}
}
Swift 4.2
私にとって有効な解決策は、UITabBarControllerをサブクラス化し、次のように2つのデリゲート関数を追加することです。
import UIKit
class MyCustomTabBarController: UITabBarController, UITabBarControllerDelegate {
var previousSelectedTabIndex:Int = 0
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
self.previousSelectedTabIndex = tabBarController.selectedIndex
}
override func tabBar(_ tabBar: UITabBar, didSelect item:
UITabBarItem) {
let vc = self.viewControllers![previousSelectedTabIndex] as! UINavigationController
vc.popToRootViewController(animated: false)
}
}
アニメーションをfalseに設定してください。そうしないと、
Unbalanced calls to begin/end appearance transitions for the targeted ViewController
選択したビューコントローラを使用してpopToRootViewControllerを実行します。基本的に、このインスタンスをキャストする必要があります。
スイフト
((selectedViewController) as! UINavigationController).popToRootViewController(animated: false)
//
// I just added extra line so the scroll bar won't annoy you.
UTabControllerは、ユーザーが「ルートにポップ」できるようにするための別のUXを提案します。タブに戻ると、以前のUINavスタック全体が保持されます。バーアイテムをもう一度タップすると(選択したタブをタップすると)、ルートにポップします。それはすべて自動です。 Instagramなどの一部のアプリでは、3回目のタップで上にスクロールできます。
ユーザーが期待しているのはデフォルトのままにすることをお勧めします。
まず、UITabbarControllerのサブクラスを作成し、Observerを追加する必要があります。
- (void)viewDidLoad {
[super viewDidLoad];
[self.tabBar addObserver:self forKeyPath:@"selectedItem" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
}
タブバーを選択すると、次の方法で処理します。
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"selectedItem"] && [object isKindOfClass:[UITabBar class]]){
UITabBar *bar = (UITabBar *)object; // The object will be the bar we're observing.
// The change dictionary will contain the previous tabBarItem for the "old" key.
UITabBarItem *wasItem = [change objectForKey:NSKeyValueChangeOldKey];
NSUInteger was = [bar.items indexOfObject:wasItem];
// The same is true for the new tabBarItem but it will be under the "new" key.
UITabBarItem *isItem = [change objectForKey:NSKeyValueChangeNewKey];
NSUInteger is = [bar.items indexOfObject:isItem];
if (is == was) {
UIViewController *vc = self.viewControllers[is];
if ([vc isKindOfClass:[UINavigationController class]]) {
[(UINavigationController *)vc popToRootViewControllerAnimated:YES];
}
}
}
}
Swift 5.1回答:
class YourTabBarName: UITabBarController, UITabBarControllerDelegate
{
override func viewDidLoad()
{
super.viewDidLoad()
self.delegate = self
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController)
{
if let vc = viewController as? UINavigationController
{ vc.popToRootViewController(animated: false) }
}
}
以下は私のために働いていました。Swift 3:のこのコード
1> UITabbarControllerをサブクラス化し、1つのiVArで以下の2つのメソッドを実装します。class MyTabBarController: UITabBarController ,UITabBarControllerDelegate { var previousSelectedTabIndex : Int = -1 }
2> viewdidLoadでタブバーデリゲートを設定します
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self // you must do it}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
self.previousSelectedTabIndex = tabBarController.selectedIndex
}
func tabBarController(_ tabBarController: UITabBarController,
shouldSelect viewController: UIViewController) -> Bool {
if self.previousSelectedTabIndex == tabBarController.selectedIndex {
let nav = viewController as! UINavigationController // mine in nav_VC
for vc in nav.childViewControllers {
if vc is YUOR_DESIRED_VIEW_CONTROLLER {
nav.popToViewController(vc, animated: true)
return false// IT WONT LET YOU GO TO delegate METHOD
}
}
}
return true
}
tabBarController.selectedIndexは、選択されたタブを提供します
TabBarController_shouldSelect_viewControllerメソッドでは、簡単な計算で目的のViewControllerを設定できます。
上記の両方の方法で上記のコードを実行できず、両方がどのように連携するかを理解した場合