iOS didSelectTabBarItem 知道之前选择了啥项目

Posted

技术标签:

【中文标题】iOS didSelectTabBarItem 知道之前选择了啥项目【英文标题】:iOS didSelectTabBarItem knowing what item was selected prioriOS didSelectTabBarItem 知道之前选择了什么项目 【发布时间】:2012-09-16 04:07:01 【问题描述】:

我有一个带有 UITabBarios 应用程序,并将其代表设置为我的班级。didSelectTabBarItem 正确触发,一切正常。然而,我确实有一些条件代码必须在UITabBarItem选择之后发生在一个特定的UITabBarItem IE。一些额外的代码,如果用户选择了标签栏项目 3 并且之前在标签栏项目 1 上,我就不必这样做了。

那么,无论如何,是否以编程方式(除了通过状态变量通过我的程序直接跟踪,以了解在选择新标签栏项目时标签栏上先前选择的项目是什么?

【问题讨论】:

【参考方案1】:

是的,可以通过键值观察 (KVO)。

注意这个答案是关于UITabBar而不是UITabBarController。标签栏控制器委托具有您正在寻找的方法(如 rdelmar 所述)。

首先,像这样观察你的标签栏:

- (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];
        NSLog(@"was tab %i",was);
        NSLog(@"is tab  %i",is);
     
    // handle other observings.

请记住在viewDidUnloaddealloc 中删除自己作为观察者,因为viewDidUnload 可能永远不会被调用。

【讨论】:

谢谢,这就是我要找的!我知道控制器有这方面的选项,但由于许多原因,我不使用控制器只是标签栏!非常感谢。【参考方案2】:

如果您不使用 UITabBarController,我不知道这是否可以通过您建议的方式(状态变量)以外的方式完成。如果您使用的是标签栏控制器,那么您可以在标签栏控制器的委托中执行此操作:

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController 
    if (viewController == [self.tabBarController.viewControllers objectAtIndex:2 && self.tabBarController.selectedIndex == 1]) 
        NSLog(@"Do special programming");
    
    return YES;

此方法在切换之前调用(与 UITabBar 方法 didSelectTabBarItem 不同),因此所选索引将是在您触摸新选项卡之前处于活动状态的选项卡的索引。

【讨论】:

如果 OP 有一个 UITabBarController 这个委托方法是要走的路。但我认为你的意思是if (viewController == [self.tabBarController.viewControllers objectAtIndex:2] && self.tabBarController.selectedIndex == 1) 谢谢,我感谢大家提供的所有控制器选项,但我想我应该更具体一点,我没有使用标签栏控制器,只是一个标签栏。【参考方案3】:

可能有更好的想法,但一种方法是在 AppDelegate 中创建一个 NSString 对象来存储当前视图控制器的类的名称,以便您可以从下一个视图控制器读取字符串并检查之前选择的项目。

在你的 AppDelegate.h 中声明一个字符串并合成它。

@property (strong, nonatomic) NSString * preSelectedViewController;

并且在所有设置为 UITabViewController 项目的 UIViewControllers 中执行此操作

.h 文件中

#import "AppDelegate.h"

.m 文件中将其包含在您的 viewWillAppear: 方法中

AppDelegate * delegate1 =(AppDelegate *) [[UIApplication sharedApplication] delegate];
if (delegate1.preSelectedViewController ==nil) 

    delegate1.preSelectedViewController=NSStringFromClass( [self class]);



NSLog(@"previous %@",delegate1.preSelectedViewController);

//include 2nd_viewcontroller.h file and this if statement in your 3rd_viewcontroller(i.e. where you want to check and do your other programming) 
if ([delegate1.preSelectedViewController isEqualToString:NSStringFromClass([2nd_ViewController class]) ]) 
    //do your little extra code


delegate1.preSelectedViewController=NSStringFromClass( [self class]);
NSLog(@"present %@",delegate1.preSelectedViewController);

猜猜这对你有用

【讨论】:

【参考方案4】:

为什么不将 lastSelectedIndex 存储在 iVar 和 - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController 你手上有这两种价值观。 您甚至可以(从未尝试过)使用 - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController 所以你有当前选择的视图控制器索引视图 selectedIndex ,然后通过其他方法你可以找到视图控制器的要选择索引的索引。

【讨论】:

【参考方案5】:

我发现这适用于ReactiveCocoa:

#import <ReactiveCocoa/ReactiveCocoa.h>
// ...
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
@weakify(self);
[RACObserve(appDelegate, tabBarController.tabBar.selectedItem) subscribeNext:^(UITabBarItem *selectedTab) 
    @strongify(self);
    NSUInteger selectedIndex = [appDelegate.tabBarController.tabBar.items indexOfObject:selectedTab];
    NSLog(@"selected index: %lu", (unsigned long)selectedIndex);
];

【讨论】:

以上是关于iOS didSelectTabBarItem 知道之前选择了啥项目的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发中通知(Notification)快速入门及推送通知实现教程

IO 模型知多少 | 代码篇

IO 模型知多少 | 代码篇

iOS中通知中心NSNotificationCenter应用总结

iOS运营知多少—7月23日

IO 模型知多少