3

我有一个带有 a 的 IOS 应用程序,UITabBar并将其代表设置为我的班级..didSelectTabBarItem正确触发,世界一切正常。但是,我确实有一些条件代码,当UITabBarItem所选内容位于一个特定UITabBarItem的 IE 之后。如果用户选择了标签栏项目 3 并且之前在标签栏项目 1 上,我将不必这样做。

所以,无论如何是以编程方式(除了通过状态变量通过我的程序保持直接轨道,要知道选中新的选项卡栏项时,先前所选项目在选项卡栏上是什么?

4

5 回答 5

5

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

注意这个答案是关于 a UITabBarnot a 的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.
}

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

于 2012-09-16T07:16:59.177 回答
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 不同),因此所选索引将是在您触摸新选项卡之前处于活动状态的选项卡的索引。

于 2012-09-16T06:13:37.960 回答
0

可能有更好的想法,但一种方法是在 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);

猜猜这对你有用

于 2012-09-16T05:34:26.377 回答
0

为什么不将 lastSelectedIndex 存储在 iVar 中,并且 - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController 您手头上有两个值。您甚至可能(从未尝试过)使用 - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController ,因此您拥有当前选定的视图控制器索引视图 selectedIndex,然后通过其他方法您可以找到视图控制器的要选择索引的索引。

于 2012-09-16T07:23:47.877 回答
0

我发现这适用于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);
}];
于 2017-09-18T01:26:06.717 回答