iOS push到navigation中已存在的viewController處理

前言

對于IM頁面開發(fā)中,經(jīng)常會碰到跳轉到一個UINavigationController的子控制器棧堆中已經(jīng)存在的ViewController的情況沸移。
出現(xiàn)步驟:

eg1- ab ab 循環(huán)

  1. 進入IM聊天,
  2. 點擊頭像吭露,
  3. 點擊聊天哎甲,

eg2- abc abc循環(huán)

  1. 進入IM聊天博脑,
  2. 點擊右上角進入設置,
  3. 點擊頭像或者搜索聊天記錄屁倔,
  4. 點擊聊天

這種情況其實微信中也處理的不是特別好:群聊中點擊某個人脑又,發(fā)起聊天后,會退回root,然后再push到與這個人的會話中问麸。
一般我們會認為相同的對象才會沒有存在的價值往衷,而和某人的P2P聊天與之前的Team聊天是完全不同的內(nèi)容。假如是我還想與群內(nèi)別人交涉严卖,就要重新找到這個群再進行額外頻繁操作了席舍。
基于這個設想,我認為減少出現(xiàn)相同控制器的過程哮笆,應該對控制器的唯一屬性也進行一個確認相同操作来颤。

實現(xiàn)思路

  1. 跳轉前對需要去冗的ViewController設置待判斷的key-values,
  2. 對UINavigationController的pushViewController:animated:進行方法替換:跳轉前發(fā)現(xiàn)棧堆中有相同Class時疟呐,對兩個ViewController的key-values對應確認脚曾。
  3. 如果key-values相同,則用方法popToViewController:animated:跳轉回到已經(jīng)存在的ViewController启具,否則就進行正常push操作本讥。

實現(xiàn)代碼

1. UIViewController 分類
添加操作方法和對比屬性,不設置的界面則不受影響鲁冯。

@interface UIViewController (SameControllerInStack)

@property (nonatomic, strong) NSDictionary * sameConfirmPropertys;

- (void)gobackIfAlreadyInStackConfirmBy:(NSDictionary *)propertys;

@end

const void *const kSameConfirmPropertys = &kSameConfirmPropertys;

@implementation UIViewController (SameControllerInStack)

- (NSDictionary *)sameConfirmPropertys {
    return objc_getAssociatedObject(self, &kSameConfirmPropertys);
}

- (void)setSameConfirmPropertys:(NSDictionary *)sameConfirmPropertys {
    objc_setAssociatedObject(self, kSameConfirmPropertys, sameConfirmPropertys, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)gobackIfAlreadyInStackConfirmBy:(NSDictionary *)propertys {
    self.sameConfirmPropertys = propertys;
}

@end

2. UINavigationController 分類
push方法替換拷沸,在方法中進行同屬性控制器的判斷

@interface UINavigationController (SameControllerInStack)

@end

@implementation UINavigationController (SameControllerInStack)

+ (void)load {
   static dispatch_once_t onceToken;
   dispatch_once(&onceToken, ^{
       @autoreleasepool {
           [self swizzleMethod:@selector(pushViewController:animated:) swizzledSelector:@selector(swizzle_pushViewController:animated:)];
       }
   });
}

- (void)swizzle_pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
   NSDictionary * confirmPropertys = viewController.sameConfirmPropertys;
   BOOL isSame;
   if (confirmPropertys.count) {
       for (UIViewController * vc in self.viewControllers) {
           if ([vc isKindOfClass:viewController.class]) {
               BOOL isSame = [self samePropertyOfVC1:vc VC2:viewController propertys:confirmPropertys];
               if (isSame) {
                   [self popToViewController:vc animated:animated];
                   return;
               }
           }
       }
   }
   [self swizzle_pushViewController:viewController animated:animated];
}

- (BOOL)samePropertyOfVC1:(id)vc1 VC2:(id)vc2 propertys:(NSDictionary *)propertys {
   for (NSString * property in propertys) {
       id object1 = [vc1 valueForKey:property];
       id object2 = [vc2 valueForKey:property];
       if (![object1 isEqual:object2]) {
           return NO;
       }
   }
   return YES;
}

3. NSObject 分類
進行方法替換需要的簡化方法


@interface NSObject (SwizzleMethod)

- (void)swizzleMethod:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector;

@end

@implementation NSObject (SwizzleMethod)

- (void)swizzleMethod:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector {
    Class class = [self class];
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    
    BOOL didAddMethod = class_addMethod(class,
                                        originalSelector,
                                        method_getImplementation(swizzledMethod),
                                        method_getTypeEncoding(swizzledMethod));
    if (didAddMethod) {
        class_replaceMethod(class,
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

@end

實例參考

添加后在個人名片頁面(個人信息),搜索聊天記錄等可能出現(xiàn)重復界面的操作時薯演,

點擊聊天.png

根據(jù)業(yè)務需要撞芍,加上一句gobackIfAlreadyInStackConfirmBy:就可以了。

    IM_Session_MessageVC *vc = [[IM_Session_MessageVC alloc] initWithSessionId:self.userId sessionType:0];
    [vc gobackIfAlreadyInStackConfirmBy:@{@"sessionId" : self.userId,
                                          @"sessionType" : @(0), // P2P
                                          }];
    [self.navigationController pushViewController:vc animated:YES];

PS

本文只是個人見解跨扮,如果發(fā)現(xiàn)有問題或者有更好方案的話序无,請不吝賜教,共同學習進步衡创。
qq:12087014
email: xingjl@outlook.com

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末帝嗡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子璃氢,更是在濱河造成了極大的恐慌哟玷,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件一也,死亡現(xiàn)場離奇詭異巢寡,居然都是意外死亡,警方通過查閱死者的電腦和手機椰苟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門抑月,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人舆蝴,你說我怎么就攤上這事谦絮×饨裕” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵挨稿,是天一觀的道長仇轻。 經(jīng)常有香客問我,道長奶甘,這世上最難降的妖魔是什么篷店? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮臭家,結果婚禮上疲陕,老公的妹妹穿的比我還像新娘。我一直安慰自己钉赁,他們只是感情好蹄殃,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著你踩,像睡著了一般诅岩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上带膜,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天吩谦,我揣著相機與錄音,去河邊找鬼膝藕。 笑死式廷,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的芭挽。 我是一名探鬼主播滑废,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼袜爪!你這毒婦竟也來了蠕趁?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤饿敲,失蹤者是張志新(化名)和其女友劉穎妻导,沒想到半個月后逛绵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怀各,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年术浪,在試婚紗的時候發(fā)現(xiàn)自己被綠了瓢对。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡胰苏,死狀恐怖硕蛹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤法焰,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布秧荆,位于F島的核電站,受9級特大地震影響埃仪,放射性物質(zhì)發(fā)生泄漏乙濒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一卵蛉、第九天 我趴在偏房一處隱蔽的房頂上張望颁股。 院中可真熱鬧,春花似錦傻丝、人聲如沸甘有。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽亏掀。三九已至,卻和暖如春泛释,著一層夾襖步出監(jiān)牢的瞬間幌氮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工胁澳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留该互,地道東北人。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓韭畸,卻偏偏與公主長得像宇智,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子胰丁,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,111評論 1 32
  • 自練習寫作以來随橘,我共參加4個寫作班。這次迎合魚哥的四個寫作法則锦庸,也發(fā)現(xiàn)寫作班里都有類似的提及机蔗,可見其重要性。 1....
    有香氣的一生閱讀 179評論 1 4
  • /7/吃飯 黎明之前最黑暗甘萧。黎明作為劃分黑夜與白晝的界線萝嘁,黑夜做著最后一刻的掙扎,黎明過后萬物都緩緩醒來扬卷。 清晨的...
    行路南閱讀 249評論 0 1