जहाँ तक मैं बता सकता हूँ, कभी-कभी UINavigationBar को subclass करना ज़रूरी होता है, कुछ अमानक रेस्टलिंग करने के लिए। कभी-कभी श्रेणियों का उपयोग करके ऐसा करने से बचना संभव है , लेकिन हमेशा नहीं।
वर्तमान में, जहां तक मुझे पता है, एक UIViewController के भीतर एक कस्टम UINavigationBar सेट करने का एकमात्र तरीका IB (अर्थात, एक संग्रह के माध्यम से) है - यह शायद उस तरह से नहीं होना चाहिए, लेकिन अभी के लिए, हम इसके साथ रहते हैं।
यह अक्सर ठीक होता है, लेकिन कभी-कभी आईबी का उपयोग करना वास्तव में संभव नहीं होता है।
तो, मैंने तीन विकल्प देखे:
- उपवर्ग UINavigationBar और इसे IB में सभी को हुक करें, फिर प्रत्येक बार जब मैं एक UINavigationController चाहता था, तो निब को लोड करने के बारे में बताएं;
- उपवर्ग के बजाय, UINavigationBar के व्यवहार को बदलने के लिए एक श्रेणी के भीतर विधि प्रतिस्थापन का उपयोग करें , या
- उपवर्ग UINavigationBar और UINavigationController को संग्रहीत / अनारक्षित करने के बारे में थोड़ा विचार करना।
विकल्प 1 इस मामले में मेरे लिए अक्षम्य (या कम से कम बहुत कष्टप्रद) था, जैसा कि मुझे UINavigationController प्रोग्रामेटिक रूप से बनाने की आवश्यकता थी, 2 मेरी राय में थोड़ा खतरनाक और अंतिम उपाय का अधिक विकल्प है, इसलिए मैंने विकल्प 3 चुना।
मेरा दृष्टिकोण एक UINavigationController के 'टेम्पलेट' संग्रह बनाने के लिए था, और अराजक, जो इसे वापस कर रहा था initWithRootViewController
।
ऐसे:
IB में, मैंने UINavigationBont के लिए उपयुक्त वर्ग सेट के साथ एक UINavigationController बनाया।
फिर, मैंने मौजूदा नियंत्रक को लिया, और इसका उपयोग करके एक संग्रहीत प्रति सहेज ली +[NSKeyedArchiver archiveRootObject:toFile:]
। मैंने सिर्फ ऐप प्रतिनिधि के भीतर, सिम्युलेटर में ऐसा किया है।
मैंने तब -i ध्वज के साथ 'xxd' उपयोगिता का उपयोग किया, सहेजी गई फ़ाइल से c कोड उत्पन्न करने के लिए, मेरे उपवर्ग ( xxd -i path/to/file
) में संग्रहीत संस्करण को एम्बेड करने के लिए ।
भीतर initWithRootViewController
मैं संग्रह से निकालने कि टेम्पलेट, और असंग्रहित के परिणाम के सेट स्व:
// This is the data from [NSKeyedArchiver archivedDataWithRootObject:controller], where
// controller is a CTNavigationController with navigation bar class set to CTNavigationBar,
// from IB. This c code was created using 'xxd -i'
static unsigned char archived_controller[] = {
0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd4, 0x01, 0x02, 0x03,
...
};
static unsigned int archived_controller_len = 682;
...
- (id)initWithRootViewController:(UIViewController *)rootViewController {
// Replace with unarchived view controller, necessary for the custom navigation bar
[self release];
self = (CTNavigationController*)[NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithBytes:archived_controller length:archived_controller_len]];
[self setViewControllers:[NSArray arrayWithObject:rootViewController]];
return [self retain];
}
फिर, मैं सिर्फ अपने UIViewController उपवर्ग का एक नया उदाहरण ले सकता हूं जिसमें कस्टम नेविगेशन बार सेट है:
UIViewController *modalViewController = [[[CTNavigationController alloc] initWithRootViewController:myTableViewController] autorelease];
[self.navigationController presentModalViewController:modalViewController animated:YES];
यह मुझे एक नेविगेशन बार और टूलबार के साथ सभी सेट अप और जगह में कस्टम नेविगेशन बार क्लास के साथ एक मोडल UITableViewController देता है। मैं किसी भी थोड़ा बुरा विधि प्रतिस्थापन करने की जरूरत नहीं थी, और मैं nibs के साथ के बारे में जब मैं वास्तव में सिर्फ प्रोग्रामिक रूप से काम करना चाहते हैं के साथ मिलाना नहीं है।
मैं +layerClass
UINavigationController के भीतर देखना चाहता हूं - +navigationBarClass
- लेकिन अभी के लिए, यह काम करता है।