2010-10-13 3 views
5

मैं अपने खुद के UINavigationBar प्रबंध कर रहा हूँ लगता है। व्यापक स्किनिंग के कारण मुझे ऐसा करने की ज़रूरत है। UINavigationController के लिए प्रलेखन चेतावनी देता है कि UINavigationController के साथ उपयोग किए जाने पर UINavigationBar को स्किन करने की सीमाएं हैं।UINavigationBar topItem/मदों की दोबारा पॉप पर वापस

मैंने व्यापक लॉगिंग की है और जो कुछ भी मैं बता सकता हूं, उससे UINavigationController में "बैक" बटन दबाकर एक के बदले स्टैक के दो आइटम पॉप हो जाते हैं। मुझे एक प्रतिनिधि प्रतिनिधि कॉलबैक मिलता है जो मुझे बता रहा है कि यह तार्किक वस्तु को हटा रहा है, लेकिन यह वास्तव में उस एक और एक को हटा देता है।

जागने में UINavigationController में जोड़ा गया आइटम कभी हटाया जाना चाहिए। इसे किसी कारण से हटाया जा रहा है।

दो समान प्रश्न हैं, लेकिन न ही संतोषजनक उत्तर हैं। दो प्रश्न हैं:

UINavigationBar .items accessor doesn't return the current UINavigationItem

UINavigationBar seems to pop 2 items off stack on "back"

- (void)awakeFromNib { 
    [headerView setDelegate: self]; 
    [headerView pushNavigationItem: tableDisplay animated: NO]; 
} 

- (void) selectedStory: (NSNotification *)not { 
    [headerView pushNavigationItem: base animated: NO]; 
    NSLog(@"Selected story: %@", base); 
} 

- (void) baseNav { 
    NSLog(@"Current items: %@", [headerView items]); 
    BaseInnerItem *current = (BaseInnerItem *)[headerView topItem]; 
    [self addSubview: [current view]]; 
} 

- (BOOL)navigationBar: (UINavigationBar *)navigationBar shouldPushItem: (UINavigationItem *)item { 
    return YES; 
} 

- (BOOL)navigationBar: (UINavigationBar *)navigationBar shouldPopItem: (UINavigationItem *)item { 
    return YES; 
} 

- (void)navigationBar:(UINavigationBar *)navigationBar didPushItem:(UINavigationItem *)item { 
    NSLog(@"didPushItem: %@", item); 
    [self baseNav]; 
} 

- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item { 
    NSLog(@"didPopItem: %@", item); 
    [self baseNav]; 
} 

संपादित एक भी रन से प्रासंगिक डिबगिंग जोड़ने के लिए:

2010-10-13 02:12:45.911 Remix2[17037:207] didPushItem: <TableDisplay: 0x5d41cc0> 
2010-10-13 02:12:45.912 Remix2[17037:207] Current items: (
    "<TableDisplay: 0x5d41cc0>" 
) 
2010-10-13 02:12:49.020 Remix2[17037:207] didPushItem: <WebDisplay: 0x591a590> 
2010-10-13 02:12:49.021 Remix2[17037:207] Current items: (
    "<TableDisplay: 0x5d41cc0>", 
    "<WebDisplay: 0x591a590>" 
) 
2010-10-13 02:12:49.023 Remix2[17037:207] Selected story: <WebDisplay: 0x591a590> 
2010-10-13 02:12:59.498 Remix2[17037:207] didPopItem: <WebDisplay: 0x591a590> 
2010-10-13 02:12:59.499 Remix2[17037:207] Current items: (
) 
+0

मेरे पास एक ही समस्या है लेकिन मैंने नेविगेशन नियंत्रक को अपने कस्टम स्किन किए गए नेविगेशन बार को संभालने दिया है। क्या आपको इसका उत्तर मिला? – mmmattias

उत्तर

0

तुम हमेशा [super awakeFromNib] कॉल करनी होगी जब आपके उपवर्ग को लागू करने वाली विधि, -awakeFromNib के लिए प्रलेखन के अनुसार:

आप माता-पिता कक्षाएं किसी भी अतिरिक्त आरंभीकरण वे

की आवश्यकता होती है महत्वपूर्ण बात है, तथापि, प्रदर्शन करने के लिए अवसर देने के लिए awakeFromNib के सुपर कार्यान्वयन कॉल करना होगा ...

मैं क्यों समझ में नहीं आता आप वास्तव में अपने स्वयं के नेविगेशन बार का प्रबंधन करना है। आप UINavigationBar उपवर्ग और केवल इस तरह के -drawRect:, -layoutSubviews, आदि, तो एक नेविगेशन नियंत्रक में नेविगेशन पट्टी के प्रबंधन के पीछे तर्क के सभी के रूप में कुछ ड्राइंग या लेआउट तरीकों को ओवरराइड सिर्फ मूल UINaviationBar वर्ग पर वापस गिर जाएगा।

मुझे लगभग हर प्रमुख UIKit कक्षा के लिए व्यापक दृश्य अनुकूलन करना पड़ा, लेकिन मैंने हमेशा मूल कक्षाओं में जटिल तर्क छोड़ दिया, देखो और महसूस को अनुकूलित करने के लिए केवल ड्राइंग विधियों को ओवरराइड किया।

संयोग से, यह वास्तव में अगर सभी आप कर रहे हैं कस्टम छवि संपत्ति का उपयोग है बिल्कुल उपवर्गीकरण बिना एक पूरे एप्लिकेशन त्वचा के लिए बहुत आसान है। एक परत के contents संपत्ति सेट करके, आप देखो और एक UIView आधारित वर्ग के स्वरूप को कस्टमाइज़ कर सकते हैं या तो एक के रूप में की जरूरत के आधार पर या अपने पूरे पूरे एप्लिकेशन:

#import <QuartzCore/QuartzCore.h> 
... 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    UIImage * navigationBarContents = [UIImage imageNamed:@"navigation-bar"]; 
    self.navigationController.navigationBar.layer.contents =  
     (id)navigationBarContents.CGImage; 
} 

आप किसी भी वर्ग है कि विरासत में के लिए सामग्री सेट कर सकते हैं UIView से: नेविगेशन बार, टूलबार, बटन इत्यादि। उप-वर्ग के बिना इस तरह से प्रबंधित करना बहुत आसान है।

+0

UINavigationBar प्रलेखन से: जब नेविगेशन नियंत्रक के संयोजन के साथ प्रयोग किया जाता है, तो नेविगेशन बार में केवल कुछ मुट्ठी भर प्रत्यक्ष अनुकूलन कर सकते हैं। विशेष रूप से, यह इस वर्ग के बार स्टाइल, टिंटकॉलर और पारदर्शी गुणों को संशोधित करने के लिए ठीक है, लेकिन आपको सीधे फ्रेम, सीमाएं, अल्फा, या छिपी हुई संपत्तियों जैसे यूआईवीयू-लेवल गुणों को सीधे परिवर्तित नहीं करना चाहिए। इसके अतिरिक्त, आपको नेविगेशन नियंत्रक को नेविगेशन आइटम्स के ढेर को प्रबंधित करना चाहिए और इन वस्तुओं को स्वयं संशोधित करने का प्रयास नहीं करना चाहिए। –

+0

दृश्य की परत की 'सामग्री' संपत्ति को संशोधित करना इस संबंध में पूरी तरह से ठीक है। मेरा विश्वास करो, मैंने कई प्रणालियों में उपरोक्त पोस्ट की गई तकनीक का उपयोग केवल मेरे नेविगेशन बार के रूप में संशोधित करने के लिए किया है, केवल बाकी सभी विशेषताओं को छोड़कर: बटन, पुशिंग/पॉपिंग, टाइटल इत्यादि। दरअसल, यह सही उद्देश्य है सभी 'UIView' ऑब्जेक्ट्स के लिए बैकिंग 'कैलियर' प्रदान करने का। – LucasTizma

0

यह -[UINavigationBar items]

के कार्यान्वयन में एक बग जब -navigationBar:didPopItem: प्रतिनिधि विधि के अंदर से कहा जाता प्रतीत होता है, यह पिछले वस्तु को छोड़ देगा।अंतर्निहित सरणी को पुनर्प्राप्त करने के लिए आप [navigationBar valueForKey:@"_itemStack"] पर कॉल करके इसे देख सकते हैं और देख सकते हैं कि अपेक्षित आइटम अभी भी वहां हैं।

dispatch_async-navigationBar:didPopItem: विधि के अंदर जोड़ने से मेरे ऐप में समस्या के आसपास सफलतापूर्वक काम करता है।