iOS направи SelectTabBarItem, знаейки какъв елемент е бил избран преди това

Имам приложение за IOS с UITabBar и неговият делегат е зададен на моя клас.. didSelectTabBarItem се задейства правилно и всичко е наред със света. Въпреки това имам някакъв условен код, който трябва да се появи, когато избраният UITabBarItem е след един конкретен UITabBarItem IE.. ако потребителят кликне върху елемент 3 от лентата с раздели и в момента е бил върху елемент 2 от лентата с раздели, трябва да направя малко допълнителен код , което не би трябвало да правя, ако потребителят е избрал елемент 3 от лентата с раздели и преди е бил на елемент 1 от лентата с раздели.

И така, има ли все пак програмно (освен поддържане на директно проследяване чрез моята програма чрез променлива на състоянието, за да знам какъв е избраният преди това елемент в лента с раздели, когато е избран нов елемент от лентата с раздели?


person Speckpgh    schedule 16.09.2012    source източник


Отговори (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 може никога да не бъде извикан.

person NJones    schedule 16.09.2012
comment
Благодаря, това е, което търся! Знам, че контролерът имаше опции за това, но по много причини не използвам контролер само лентата с раздели! Много благодаря. - person Speckpgh; 17.09.2012

Не знам дали това може да се направи по начин, различен от това, което предложихте (променлива на състоянието), ако не използвате 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), така че избраният индекс ще бъде индексът на раздела, който е бил активен, преди да докоснете новия раздел.

person rdelmar    schedule 16.09.2012
comment
Ако OP има UITabBarController, този метод на делегиране е правилният начин. Но мисля, че имахте предвид if (viewController == [self.tabBarController.viewControllers objectAtIndex:2] && self.tabBarController.selectedIndex == 1). - person NJones; 16.09.2012
comment
Благодаря, оценявам всички опции за контролер, които хората дават, но предполагам, че трябваше да бъда по-конкретен, че не използвам таббарконтролер, а само таббар. - person Speckpgh; 17.09.2012

Може да има по-добри идеи, но един от начините да направите това е като създадете NSString обект във вашия AppDelegate, за да съхраните името на класа на текущия изглед контролер, така че да можете да прочетете низа от следващия си изглед контролер и да проверите избрания по-рано елемент .

Във вашия 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);

Предполагам, че това ще ви свърши работа

person Neo    schedule 16.09.2012

Защо не съхраните lastSelectedIndex в iVar и в - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController имате и двете стойности на ръце. Може дори (никога не сте го опитвали) да използвате - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController, така че да имате текущо избрания индекс на контролера за изглед view selectedIndex и след това чрез допълнителен метод можете да намерите индекса на избрания индекс на viewController.

person Bernd Rabe    schedule 16.09.2012

Открих, че това работи с 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);
}];
person Stunner    schedule 18.09.2017