我有一个带UITabBar
的IOS应用程序,并将其委托设置为我的班级。didSelectTabBarItem
正确触发,所有这些都适合全世界。但是我确实有一些条件代码必须在选择的UITabBarItem
在一个特定的UITabBarItem
IE之后发生..如果用户点击标签栏项目3,它们当前在标签栏项目2上我必须做一些额外的代码,如果用户选择了标签栏项目3并且之前在标签栏项目1上,我就不必这样做。
那么,无论如何都是以编程方式(除了通过状态变量通过我的程序直接跟踪,以便在选择新的标签栏项目时知道标签栏上的所选项目是什么?
答案 0 :(得分:5)
是的,可以通过键值观察(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.
}
请记住在viewDidUnload
和dealloc
中将自己视为观察者,因为viewDidUnload
可能永远不会被调用。
答案 1 :(得分: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不同),因此所选索引将是触摸新选项卡之前处于活动状态的选项卡的索引。
答案 2 :(得分:0)
可能有更好的想法,但一种方法是在AppDelegate中创建一个NSString对象来存储当前视图控制器的类的名称,以便您可以从下一个视图控制器读取字符串并检查以前选择的项目。
在你的AppDelegate.h中声明一个字符串并合成它。
@property (strong, nonatomic) NSString * preSelectedViewController;
并且所有UIViewControllers 中的都被设置为UITabViewController的项目
.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);
猜猜这对你有用
答案 3 :(得分:0)
为什么不将lastSelectedIndex存储在iVar中
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
你手上有两个价值观。
你甚至可能(从未尝试过)使用它
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
所以你有当前选择的视图控制器索引视图selectedIndex,然后通过一个额外的方法,你可以找到viewController的选择索引的索引。
答案 4 :(得分: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);
}];