मैंने इस थ्रेड को ओवरराइड करने के लिए पीछा किया -preferredStatusBarStyle
, लेकिन इसे कॉल नहीं किया गया। क्या कोई विकल्प है कि मैं इसे सक्षम करने के लिए बदल सकता हूं? (मैं अपने प्रोजेक्ट में XIB का उपयोग कर रहा हूं।)
मैंने इस थ्रेड को ओवरराइड करने के लिए पीछा किया -preferredStatusBarStyle
, लेकिन इसे कॉल नहीं किया गया। क्या कोई विकल्प है कि मैं इसे सक्षम करने के लिए बदल सकता हूं? (मैं अपने प्रोजेक्ट में XIB का उपयोग कर रहा हूं।)
जवाबों:
मेरे पास एक ही समस्या थी, और मुझे लगा कि यह हो रहा है क्योंकि मैं अपने एप्लिकेशन विंडो में रूट व्यू कंट्रोलर सेट नहीं कर रहा था।
UIViewController
जिसमें मैं लागू किया preferredStatusBarStyle
एक में इस्तेमाल किया गया था UITabBarController
जो स्क्रीन पर देखा गया की उपस्थिति नियंत्रित,।
जब मैंने इसे देखने के लिए रूट व्यू कंट्रोलर सेट किया UITabBarController
, तो स्थिति पट्टी परिवर्तन सही तरीके से काम करना शुरू कर दिया, जैसा कि अपेक्षित था (और preferredStatusBarStyle
विधि कहा जा रहा था)।
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
... // other view controller loading/setup code
self.window.rootViewController = rootTabBarController;
[self.window makeKeyAndVisible];
return YES;
}
वैकल्पिक रूप से, आप निम्न में से किसी एक विधि को, अपने प्रत्येक दृश्य नियंत्रकों में, इसके पृष्ठभूमि रंग के आधार पर, उपयोग करने के बजाय, कह सकते हैं setNeedsStatusBarAppearanceUpdate
:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
या
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
ध्यान दें कि यदि आप इस पद्धति का उपयोग करते हैं, तो आपको प्लास्ट फाइल में भी सेट UIViewControllerBasedStatusBarAppearance
करना होगा NO
।
setNeedsStatusBarAppearanceUpdate
- जब मैंने यह बदलाव किया तो मेरे संदेह की पुष्टि हुई।
UINavigationController का उपयोग करने वाले किसी के लिए:
UINavigationController
पर आगे नहीं है preferredStatusBarStyle
अपने बच्चे को देखने के नियंत्रकों के लिए कॉल। इसके बजाय यह अपनी स्थिति का प्रबंधन करता है - जैसा कि यह होना चाहिए, यह स्क्रीन के शीर्ष पर आ रहा है जहां स्थिति पट्टी रहती है और इसलिए इसके लिए जिम्मेदार होना चाहिए। preferredStatusBarStyle
एक नौसेना नियंत्रक के भीतर अपने कुलपतियों में लागू करने से कुछ नहीं होगा - उन्हें कभी नहीं बुलाया जाएगा।
चाल क्या है UINavigationController
क्या के लिए वापस जाने के लिए तय करने के लिए उपयोग करता है UIStatusBarStyleDefault
या UIStatusBarStyleLightContent
। यह इस पर आधारित है UINavigationBar.barStyle
। डिफ़ॉल्ट ( UIBarStyleDefault
) अंधेरे अग्रभूमि UIStatusBarStyleDefault
स्थिति बार में परिणाम देता है। और UIBarStyleBlack
एक UIStatusBarStyleLightContent
स्टेटस बार देगा।
टी एल; डॉ:
यदि आप चाहते हैं UIStatusBarStyleLightContent
एक पर UINavigationController
उपयोग करें:
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
preferredStatusBarStyle
वास्तव में चाइल्ड व्यू कंट्रोलर पर कॉल किया जाएगा यदि आप नेविगेशन बार (सेट ) navigationBarHidden
को छिपाते हैं YES
, तो बिल्कुल उपयुक्त।
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]
navigationBarHidden
सेट को इंगित करने के लिए YES
वास्तव में preferredStatusBarStyle
बुलाया जाएगा, और उन लोगों के लिए एक चेतावनी जो इस पर ठोकर खा सकते हैं: यह साथ काम करता है navigationBarHidden
, लेकिन साथ नहीं navigationBar.hidden
!
इसलिए मैंने वास्तव में UINavigationController के लिए एक श्रेणी जोड़ी लेकिन विधियों का उपयोग किया:
-(UIViewController *)childViewControllerForStatusBarStyle;
-(UIViewController *)childViewControllerForStatusBarHidden;
और उन लोगों को वर्तमान दृश्यमान UIViewController वापस कर दिया था। यह वर्तमान दृश्य दृश्य नियंत्रक को अपनी पसंदीदा शैली / दृश्यता सेट करता है।
यहां इसके लिए एक पूर्ण कोड स्निपेट दिया गया है:
स्विफ्ट में:
extension UINavigationController {
public override func childViewControllerForStatusBarHidden() -> UIViewController? {
return self.topViewController
}
public override func childViewControllerForStatusBarStyle() -> UIViewController? {
return self.topViewController
}
}
उद्देश्य-सी में:
@interface UINavigationController (StatusBarStyle)
@end
@implementation UINavigationController (StatusBarStyle)
-(UIViewController *)childViewControllerForStatusBarStyle {
return self.topViewController;
}
-(UIViewController *)childViewControllerForStatusBarHidden {
return self.topViewController;
}
@end
और अच्छे उपाय के लिए, यहां एक UIViewController में इसे कैसे लागू किया गया है:
स्विफ्ट में
override public func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
override func prefersStatusBarHidden() -> Bool {
return false
}
ऑब्जेक्टिव-सी में
-(UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent; // your own style
}
- (BOOL)prefersStatusBarHidden {
return NO; // your own visibility code
}
यकीन है कि अंत में, बनाने के अपने अनुप्रयोग plist करता नहीं "नियंत्रक आधारित स्थिति पट्टी उपस्थिति देखें" नहीं करने के लिए सेट है। या तो उस लाइन को हटा दें या इसे YES पर सेट करें (जो मेरा मानना है कि iOS 7 के लिए अब डिफ़ॉल्ट है।)
return self.topViewController;
मेरे लिए काम करता है, लेकिन return self.visibleViewController;
- नहीं
super
इस पद्धति में कॉल करने की आवश्यकता नहीं है और आप वास्तव में इस प्रकार के सभी नियंत्रकों के व्यवहार को बदलना चाहते हैं
अभी भी इससे जूझ रहे किसी व्यक्ति के लिए, स्विफ्ट में यह सरल विस्तार आपके लिए समस्या को ठीक कर सकता है।
extension UINavigationController {
override open var childForStatusBarStyle: UIViewController? {
return self.topViewController
}
}
मेरा ऐप तीनों प्रयोग किया है: UINavigationController
, UISplitViewController
, UITabBarController
, इस प्रकार इन सभी स्थिति पट्टी पर नियंत्रण लेने के लिए लग रहे हैं और कारण होगा preferedStatusBarStyle
अपने बच्चों के लिए नहीं कहा जा करने के लिए। इस व्यवहार को ओवरराइड करने के लिए आप एक एक्सटेंशन बना सकते हैं जैसे कि बाकी के जवाबों का उल्लेख किया गया है। यहाँ स्विफ्ट 4 में तीनों का विस्तार है। काश Apple इस तरह के सामान के बारे में अधिक स्पष्ट होता।
extension UINavigationController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return self.topViewController
}
open override var childViewControllerForStatusBarHidden: UIViewController? {
return self.topViewController
}
}
extension UITabBarController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return self.childViewControllers.first
}
open override var childViewControllerForStatusBarHidden: UIViewController? {
return self.childViewControllers.first
}
}
extension UISplitViewController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return self.childViewControllers.first
}
open override var childViewControllerForStatusBarHidden: UIViewController? {
return self.childViewControllers.first
}
}
संपादित करें: स्विफ्ट 4.2 एपीआई परिवर्तन के लिए अद्यतन
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return self.topViewController
}
open override var childForStatusBarHidden: UIViewController? {
return self.topViewController
}
}
extension UITabBarController {
open override var childForStatusBarStyle: UIViewController? {
return self.children.first
}
open override var childForStatusBarHidden: UIViewController? {
return self.children.first
}
}
extension UISplitViewController {
open override var childForStatusBarStyle: UIViewController? {
return self.children.first
}
open override var childForStatusBarHidden: UIViewController? {
return self.children.first
}
}
टायसन का उत्तर स्थिति बार के रंग को सफेद में बदलने के लिए सही हैUINavigationController
।
अगर किसी को कोड लिखने के बाद उसी परिणाम को पूरा करना है AppDelegate
तो नीचे दिए गए कोड का उपयोग करें और इसे अंदर लिखेंAppDelegate's
didFinishLaunchingWithOptions
विधि के ।
और भूल नहीं है स्थापित करने के लिए UIViewControllerBasedStatusBarAppearance
करने के लिएYES
.plist फ़ाइल में, और परिवर्तन को प्रतिबिंबित नहीं होंगे।
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// status bar appearance code
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
return YES;
}
UINavigationController पर, preferredStatusBarStyle
को नहीं बुलाया जाता है क्योंकि इसके topViewController
लिए प्राथमिकता दी जाती है self
। इसलिए, preferredStatusBarStyle
UINavigationController पर कॉल करने के लिए , आपको इसे बदलने की आवश्यकता हैchildViewControllerForStatusBarStyle
।
अपनी कक्षा में अपने UINavigationController को ओवरराइड करें:
class MyRootNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override var childViewControllerForStatusBarStyle: UIViewController? {
return nil
}
}
सभी UINavigationController के लिए ऐसा करने के लिए, आप एक एक्सटेंशन में ओवरराइड कर सकते हैं (चेतावनी: यह UIDocumentPickerViewController, UIImagePickerController, आदि) को प्रभावित करता है, लेकिन आपको शायद स्विफ्ट प्रलेखन के अनुसार ऐसा नहीं करना चाहिए :
extension UINavigationController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
open override var childViewControllerForStatusBarStyle: UIViewController? {
return nil
}
}
सेरेन के जवाब के अलावा, यदि आप modalPresentationStyle
(उदाहरण के लिए .overCurrentContext
) के साथ एक व्यू कंट्रोलर प्रस्तुत कर रहे हैं, तो आपको इसे नए प्रस्तुत व्यू कंट्रोलर पर भी कॉल करना चाहिए:
presentedViewController.modalPresentationCapturesStatusBarAppearance = true
preferredStatusBarStyle
प्रस्तुत व्यू कंट्रोलर में ओवरराइड करना भी न भूलें ।
हिप्पो के जवाब के अलावा: यदि आप एक UINavigationController का उपयोग कर रहे हैं, तो संभवतः श्रेणी जोड़ना बेहतर होगा:
// UINavigationController+StatusBarStyle.h:
@interface UINavigationController (StatusBarStyle)
@end
// UINavigationController+StatusBarStyle.m:
@implementation UINavigationController (StatusBarStyle)
- (UIStatusBarStyle)preferredStatusBarStyle
{
//also you may add any fancy condition-based code here
return UIStatusBarStyleLightContent;
}
@end
यह समाधान शायद जल्द ही होने वाले व्यवहार पर स्विच करने से बेहतर है।
preferredStatusBarStyle
और UINavigationController विशिष्ट तर्क करता है। अभी यह तर्क पर आधारित है, navigationBar.barStyle
लेकिन मैं अतिरिक्त जाँच को जोड़ा जा सकता है (उदाहरण UISearchDisplayController
के लिए नेवबार मोड को छिपाने के लिए)। डिफ़ॉल्ट तर्क को ओवरराइड करके आप इस सभी कार्यक्षमता को ढीला कर देते हैं और भविष्य में 'wtf' क्षणों के लिए खुद को खुला छोड़ देते हैं। इन-बिल्ट नेवी कंट्रोलर व्यवहार का समर्थन करते हुए ऐसा करने के सही तरीके के लिए ऊपर दिए गए मेरे उत्तर को देखें।
जैसा कि चयनित उत्तर में बताया गया है , मूल कारण आपके विंडो रूट व्यू कंट्रोलर ऑब्जेक्ट की जांच करना है।
childForStatusBarStyle
निम्नलिखित एक्सटेंशन का उपयोग करें, यह उपरोक्त सभी परिदृश्यों को संभालता है -
extension UITabBarController {
open override var childForStatusBarStyle: UIViewController? {
return selectedViewController?.childForStatusBarStyle ?? selectedViewController
}
}
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return topViewController?.childForStatusBarStyle ?? topViewController
}
}
extension AppRootViewController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
return children.first { $0.childForStatusBarStyle != nil }?.childForStatusBarStyle?.preferredStatusBarStyle ?? .default
}
}
UIViewControllerBasedStatusBarAppearance
कुंजी की आवश्यकता नहीं हैinfo.plist
यदि आप नए प्रवाह को सामान्य रूप से प्रस्तुत करते हैं, तो यह मौजूदा स्थिति बार शैली के प्रवाह से अलग हो जाता है। तो, मान लीजिए कि आप एक प्रस्तुत कर रहे हैं NewFlowUIViewController
और फिर नया नेविगेशन या टैबबार नियंत्रक NewFlowUIViewController
जोड़ सकते हैं, फिर NewFlowUIViewController
आगे के नियंत्रक की स्थिति पट्टी शैली को प्रबंधित करने के लिए विस्तार भी जोड़ सकते हैं।
यदि आप modalPresentationStyle सेट fullScreen
करते हैं, तो सामान्य रूप से प्रस्तुत करते समय, आपको modalPresentationCapturesStatusBarAppearance
सही पर सेट करना होगा ताकि प्रस्तुत दृश्य नियंत्रक को स्टेटस बार उपस्थिति नियंत्रण प्राप्त हो।
UINavigationController
का उपवर्ग UIViewController
(जो 🙃 जानता था)!
इसलिए, जब नेविगेशन नियंत्रकों में एम्बेडेड दृश्य नियंत्रक प्रस्तुत करते हैं, तो आप वास्तव में एम्बेडेड दृश्य नियंत्रक प्रस्तुत नहीं कर रहे हैं; आप नेविगेशन नियंत्रकों को प्रस्तुत कर रहे हैं! UINavigationController
, के एक उपवर्ग के रूप में UIViewController
, विरासत preferredStatusBarStyle
औरchildForStatusBarStyle
, जिसे आप इच्छानुसार सेट कर सकते हैं।
निम्न विधियों में से कोई भी कार्य करना चाहिए:
info.plist
, निम्नलिखित संपत्ति जोड़ें:
UIUserInterfaceStyle
(उर्फ। "यूजर इंटरफेस स्टाइल")preferredStatusBarStyle
भीतर ओवरराइड करेंUINavigationController
preferredStatusBarStyle
( doc ) - व्यू कंट्रोलर के लिए पसंदीदा स्टेटस बार स्टाइलउपवर्ग या विस्तार UINavigationController
class MyNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
}
या
extension UINavigationController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
}
childForStatusBarStyle
भीतर ओवरराइड करेंUINavigationController
childForStatusBarStyle
( डॉक्टर ) - स्थिति बार शैली का निर्धारण करने के लिए सिस्टम को देखने के लिए नियंत्रक की आवश्यकता होने पर कॉल किया जाता है"यदि आपका कंटेनर व्यू कंट्रोलर अपने चाइल्ड व्यू कंट्रोलर में से किसी एक से अपनी स्टेटस बार शैली प्राप्त करता है, तो [इस प्रॉपर्टी को ओवरराइड करें] और उस चाइल्ड व्यू कंट्रोलर को लौटा दें। यदि आप शून्य पर लौटते हैं या इस विधि को ओवरराइड नहीं करते हैं, तो सेल्फ के लिए स्टेटस बार स्टाइल का उपयोग किया जाता है। । यदि इस विधि से वापसी मान बदलता है, तो setNeedsStatusBarAppearanceUpdate () विधि को कॉल करें। "
उपवर्ग या विस्तार UINavigationController
class MyNavigationController: UINavigationController {
override var childForStatusBarStyle: UIViewController? {
topViewController
}
}
या
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
topViewController
}
}
आप ऊपर जैसा भी दृश्य नियंत्रक लौटा सकते हैं। मैं निम्नलिखित में से एक की सलाह देता हूं:
topViewController
(of UINavigationController
) ( doc ) - नेविगेशन स्टैक के शीर्ष पर दृश्य नियंत्रकvisibleViewController
(of UINavigationController
) ( doc ) - नेविगेशन इंटरफ़ेस में वर्तमान में दृश्यमान दृश्य से जुड़ा व्यू कंट्रोलर (संकेत: इसमें "एक व्यू कंट्रोलर शामिल किया जा सकता है जिसे नेविगेशन कंट्रोलर के ऊपर मामूली रूप से प्रस्तुत किया गया था")नोट: यदि आप उपवर्ग का निर्णय लेते हैं UINavigationController
, तो उस वर्ग को आईबी में पहचान निरीक्षक के माध्यम से अपने नौसेना नियंत्रकों के लिए लागू करना याद रखें।
PS मेरा कोड स्विफ्ट 5.1 सिंटैक्स ift का उपयोग करता है
@ उपर्युक्त का उत्तर UINavigationControllers के मामले के लिए अभी भी एक महान है। हालाँकि, स्विफ्ट 3 के लिए childViewController कार्यों को बदल दिया गया है vars
। तो UINavigationController
एक्सटेंशन कोड होना चाहिए:
override open var childViewControllerForStatusBarStyle: UIViewController? {
return topViewController
}
override open var childViewControllerForStatusBarHidden: UIViewController? {
return topViewController
}
और फिर व्यू कंट्रोलर में स्टेटस बार स्टाइल को डिक्टेट करना चाहिए:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
यदि आपका व्यूकंट्रोलर UINavigationController के अधीन है।
उपवर्ग UINavigationController और जोड़ें
override var preferredStatusBarStyle: UIStatusBarStyle {
return topViewController?.preferredStatusBarStyle ?? .default
}
ViewController preferredStatusBarStyle
कहा जाएगा।
IOS 7 में UIStatusBarStyle
IOS 7 में स्टेटस बार पारदर्शी है, इसके पीछे का दृश्य दिखाता है।
स्टेटस बार की शैली इसकी सामग्री के दिखावे को संदर्भित करती है। IOS 7 में, स्टेटस बार कंटेंट या तो डार्क ( UIStatusBarStyleDefault
) या लाइट ( UIStatusBarStyleLightContent
) है। दोनों UIStatusBarStyleBlackTranslucent
और UIStatusBarStyleBlackOpaque
आईओएस 7.0 में पदावनत कर रहे हैं। UIStatusBarStyleLightContent
इसके बजाय उपयोग करें ।
कैसे बदलें UIStatusBarStyle
यदि स्थिति पट्टी के नीचे एक नेविगेशन बार है, तो स्थिति बार शैली को नेविगेशन बार शैली ( UINavigationBar.barStyle
) से मिलान करने के लिए समायोजित किया जाएगा :
विशेष रूप से, यदि नेविगेशन बार शैली UIBarStyleDefault है, तो स्टेटस बार शैली होगी UIStatusBarStyleDefault
; यदि नेविगेशन बार शैली है UIBarStyleBlack
, तो स्थिति बार शैली होगीUIStatusBarStyleLightContent
।
यदि स्टेटस बार के नीचे कोई नेविगेशन बार नहीं है, तो स्थिति बार शैली को नियंत्रित किया जा सकता है और एक व्यक्तिगत दृश्य नियंत्रक द्वारा बदला जा सकता है, जबकि ऐप चलता है।
- [UIViewController preferredStatusBarStyle]
iOS 7 में एक नया तरीका जोड़ा गया है। इसे पसंदीदा स्टेटस बार स्टाइल को वापस करने के लिए ओवरराइड किया जा सकता है:
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
यदि स्टेटस बार स्टाइल को स्वयं, ओवरराइड के बजाय चाइल्ड व्यू कंट्रोलर द्वारा नियंत्रित किया जाना चाहिए -[UIViewController childViewControllerForStatusBarStyle]
उस चाइल्ड व्यू कंट्रोलर को वापस करने के लिए करें।
यदि आप इस व्यवहार से बाहर निकलना पसंद करते हैं और -[UIApplication statusBarStyle]
विधि का उपयोग करके स्थिति पट्टी शैली सेट करते हैं , तो UIViewControllerBasedStatusBarAppearance
एक ऐप की Info.plist
फ़ाइल में कुंजी जोड़ें और इसे मान न दें।
अगर कोई किसी नेविगेशन कंट्रोलर का उपयोग कर रहा है और चाहता है कि उसके सभी नेविगेशन कंट्रोलर के पास काली शैली हो, तो आप स्विफ्ट 3 में इस तरह UINavigationController के लिए एक एक्सटेंशन लिख सकते हैं और यह सभी नेविगेशन कंट्रोलर्स (इसे एक कंट्रोलर में असाइन करने के बजाय) पर लागू होगा समय)।
extension UINavigationController {
override open func viewDidLoad() {
super.viewDidLoad()
self.navigationBar.barStyle = UIBarStyle.black
}
}
किसी भी तरह के UIViewController के लिए स्विफ्ट में:
आपके AppDelegate
सेट में:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window!.rootViewController = myRootController
return true
}
myRootController
किसी भी तरह का हो सकता है UIViewController
, जैसे UITabBarController
या UINavigationController
।
फिर, इस रूट नियंत्रक को इस तरह से ओवरराइड करें:
class RootController: UIViewController {
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
}
यह आपके पूरे ऐप में स्टेटस बार की उपस्थिति को बदल देगा, क्योंकि रूट कंट्रोलर बार उपस्थिति के लिए पूरी तरह से जिम्मेदार है।
इस कार्य को करने के लिए View controller-based status bar appearance
अपने Info.plist
(जो कि डिफ़ॉल्ट है) में YES को संपत्ति सेट करने के लिए याद रखें ।
अधिकांश उत्तरों में childViewControllerForStatusBarStyle
विधि का अच्छा कार्यान्वयन शामिल नहीं है UINavigationController
। मेरे अनुभव के अनुसार आपको ऐसे मामलों को संभालना चाहिए, जब नेविगेशन नियंत्रक पर पारदर्शी दृश्य नियंत्रक प्रस्तुत किया जाता है। इन मामलों में आपको अपने मोडल कंट्रोलर ( visibleViewController
) पर नियंत्रण रखना चाहिए , लेकिन गायब होने पर नहीं।
override var childViewControllerForStatusBarStyle: UIViewController? {
var childViewController = visibleViewController
if let controller = childViewController, controller.isBeingDismissed {
childViewController = topViewController
}
return childViewController?.childViewControllerForStatusBarStyle ?? childViewController
}
IOS 13.4 के लिए श्रेणी preferredStatusBarStyle
में विधि UINavigationController
को नहीं कहा जाएगा, उप-वर्ग का उपयोग करने की आवश्यकता के बिना स्विज़लिंग एकमात्र विकल्प लगता है।
उदाहरण:
श्रेणी हेडर:
@interface UINavigationController (StatusBarStyle)
+ (void)setUseLightStatusBarStyle;
@end
कार्यान्वयन:
#import "UINavigationController+StatusBarStyle.h"
#import <objc/runtime.h>
@implementation UINavigationController (StatusBarStyle)
void (^swizzle)(Class, SEL, SEL) = ^(Class c, SEL orig, SEL new){
Method origMethod = class_getInstanceMethod(c, orig);
Method newMethod = class_getInstanceMethod(c, new);
if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
else
method_exchangeImplementations(origMethod, newMethod);
};
+ (void)setUseLightStatusBarStyle {
swizzle(self.class, @selector(preferredStatusBarStyle), @selector(_light_preferredStatusBarStyle));
}
- (UIStatusBarStyle)_light_preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}
@end
AppDelegate.h में उपयोग:
#import "UINavigationController+StatusBarStyle.h"
[UINavigationController setUseLightStatusBarStyle];
इसे हल करने के लिए यहां मेरा तरीका है।
AGViewControllerAppearance नामक एक प्रोटोकॉल को परिभाषित करें ।
AGViewControllerAppearance.h
#import <Foundation/Foundation.h>
@protocol AGViewControllerAppearance <NSObject>
@optional
- (BOOL)showsStatusBar;
- (BOOL)animatesStatusBarVisibility;
- (UIStatusBarStyle)preferredStatusBarStyle;
- (UIStatusBarAnimation)prefferedStatusBarAnimation;
@end
UIViewController पर एक श्रेणी को परिभाषित करें जिसे अपग्रेड कहा जाता है ।
UIViewController + Upgrade.h
#import <UIKit/UIKit.h>
@interface UIViewController (Upgrade)
//
// Replacements
//
- (void)upgradedViewWillAppear:(BOOL)animated;
@end
UIViewController + Upgrade.m
#import "UIViewController+Upgrade.h"
#import <objc/runtime.h>
#import "AGViewControllerAppearance.h" // This is the appearance protocol
@implementation UIViewController (Upgrade)
+ (void)load
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wselector"
Method viewWillAppear = class_getInstanceMethod(self, @selector(viewWillAppear:));
#pragma clang diagnostic pop
Method upgradedViewWillAppear = class_getInstanceMethod(self, @selector(upgradedViewWillAppear:));
method_exchangeImplementations(viewWillAppear, upgradedViewWillAppear);
}
#pragma mark - Implementation
- (void)upgradedViewWillAppear:(BOOL)animated
{
//
// Call the original message (it may be a little confusing that we're
// calling the 'same' method, but we're actually calling the original one :) )
//
[self upgradedViewWillAppear:animated];
//
// Implementation
//
if ([self conformsToProtocol:@protocol(AGViewControllerAppearance)])
{
UIViewController <AGViewControllerAppearance> *viewControllerConformingToAppearance =
(UIViewController <AGViewControllerAppearance> *)self;
//
// Status bar
//
if ([viewControllerConformingToAppearance respondsToSelector:@selector(preferredStatusBarStyle)])
{
BOOL shouldAnimate = YES;
if ([viewControllerConformingToAppearance respondsToSelector:@selector(animatesStatusBarVisibility)])
{
shouldAnimate = [viewControllerConformingToAppearance animatesStatusBarVisibility];
}
[[UIApplication sharedApplication] setStatusBarStyle:[viewControllerConformingToAppearance preferredStatusBarStyle]
animated:shouldAnimate];
}
if ([viewControllerConformingToAppearance respondsToSelector:@selector(showsStatusBar)])
{
UIStatusBarAnimation animation = UIStatusBarAnimationSlide;
if ([viewControllerConformingToAppearance respondsToSelector:@selector(prefferedStatusBarAnimation)])
{
animation = [viewControllerConformingToAppearance prefferedStatusBarAnimation];
}
[[UIApplication sharedApplication] setStatusBarHidden:(! [viewControllerConformingToAppearance showsStatusBar])
withAnimation:animation];
}
}
}
@end
अब, यह कहने का समय है कि आप देख रहे हैं कि नियंत्रक AGViewControllerAppearance प्रोटोकॉल लागू कर रहा है।
उदाहरण:
@interface XYSampleViewController () <AGViewControllerAppearance>
... the rest of the interface
@end
बेशक, आप तरीकों (के बाकी को लागू कर सकते showsStatusBar , animatesStatusBarVisibility , prefferedStatusBarAnimation प्रोटोकॉल और से) UIViewController + अपग्रेड उचित उन्हें द्वारा प्रदान की मूल्यों पर आधारित अनुकूलन कर सकते हैं।
ध्यान दें कि जब का उपयोग कर self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
समाधान
अपनी मुट्ठी में जाना सुनिश्चित करें और हाँ के लिए "नियंत्रक-आधारित स्थिति बार उपस्थिति" सेट करें। अगर इसका NO नहीं है तो यह काम नहीं करेगा।
Xcode 11.4 के बाद से, ओवरराइडिंग preferredStatusBarStyle
UINavigationController एक्सटेंशन में संपत्ति को अब काम नहीं करता है क्योंकि यह नहीं कहा जाएगा।
स्थापना barStyle
के navigationBar
लिए .black
काम करता है वास्तव में, लेकिन यह अवांछित साइड इफेक्ट जोड़ना होगा यदि आप navigationBar जो प्रकाश और अंधेरे मोड के लिए अलग-अलग रूप से सामने आए हो सकता है के लिए subviews जोड़ें। क्योंकि barStyle
काले रंग में सेट करके , userInterfaceStyle
नेविगेशन बार में एम्बेड किए गए एक दृश्य thats की हमेशा एप्लिकेशन की userInterfaceStyle.dark
परवाह किए बिना होगा userInterfaceStyle
।
मैं जिस उचित समाधान के साथ आता हूं, वह वहां का उपवर्ग जोड़कर UINavigationController
ओवरराइड करता preferredStatusBarStyle
है। यदि आप अपने पसंदीदा सभी बचत के लिए इस कस्टम UINavigationController का उपयोग करते हैं।
नेवीगेशनकंट्रोलर या TabBarController वे हैं जिन्हें स्टाइल प्रदान करने की आवश्यकता है। यहां बताया गया है कि मैंने कैसे हल किया: https://stackoverflow.com/a/39072526/242769