我有一个带有 a 的 IOS 应用程序,UITabBar
并将其代表设置为我的班级..didSelectTabBarItem
正确触发,世界一切正常。但是,我确实有一些条件代码,当UITabBarItem
所选内容位于一个特定UITabBarItem
的 IE 之后。如果用户选择了标签栏项目 3 并且之前在标签栏项目 1 上,我将不必这样做。
所以,无论如何是以编程方式(除了通过状态变量通过我的程序保持直接轨道,要知道选中新的选项卡栏项时,先前所选项目在选项卡栏上是什么?
我有一个带有 a 的 IOS 应用程序,UITabBar
并将其代表设置为我的班级..didSelectTabBarItem
正确触发,世界一切正常。但是,我确实有一些条件代码,当UITabBarItem
所选内容位于一个特定UITabBarItem
的 IE 之后。如果用户选择了标签栏项目 3 并且之前在标签栏项目 1 上,我将不必这样做。
所以,无论如何是以编程方式(除了通过状态变量通过我的程序保持直接轨道,要知道选中新的选项卡栏项时,先前所选项目在选项卡栏上是什么?
是的,通过键值观察 ( KVO
) 是可能的。
注意这个答案是关于 a UITabBar
not 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
可能永远不会被调用。
如果您不使用 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 不同),因此所选索引将是在您触摸新选项卡之前处于活动状态的选项卡的索引。
可能有更好的想法,但一种方法是在 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);
猜猜这对你有用
为什么不将 lastSelectedIndex 存储在 iVar 中,并且
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
您手头上有两个值。您甚至可能(从未尝试过)使用
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
,因此您拥有当前选定的视图控制器索引视图 selectedIndex,然后通过其他方法您可以找到视图控制器的要选择索引的索引。
我发现这适用于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);
}];