5

कुछ नेटवर्क ऑपरेशंस करते समय, मैं एक मोडल व्यू कंट्रोलर (एमबी प्रोग्रेसएचयूडी के समान लेकिन दृश्य नियंत्रक के समान) प्रस्तुत करता हूं ताकि उपयोगकर्ता इंटरैक्शन को रोका जा सके और प्रगति का संकेत दिया जा सके।स्टेटस बार रंग बदलने के बिना व्यू कंट्रोलर प्रस्तुत करना, जैसे UIAlertController

व्यू कंट्रोलर में modalPresentationStyle = .Custom है और एक संक्रमण प्रतिनिधि और कस्टम प्रस्तुति नियंत्रक का उपयोग करके एनिमेटेड है। संक्रमण को एनिमेट करने से परे उनके पास प्रस्तुति को चलाने में कोई कस्टम क्रिया नहीं है।

मेरी समस्या यह है कि जब भी दृश्य नियंत्रक प्रस्तुत किया जाता है, तो यह स्टेटस बार रंग काला हो जाता है। मैं preferredStatusBarStyle को हमेशा .LightContent वापस करने के लिए ओवरराइड कर सकता हूं लेकिन कभी-कभी यह दृश्य नियंत्रक .Default के साथ व्यू कंट्रोलर पर प्रस्तुत किया जाता है और मैं इसे वहां भी बदलना नहीं चाहता हूं। असल में, मैं UIAlertController के समान व्यवहार करना चाहता हूं।

Screenshot showing presented view controller causing dark status bar content

मैं स्थिति पट्टी स्थान से बाहर प्रस्तुत दृश्य नियंत्रक स्थानांतरित करने के लिए प्रस्तुति नियंत्रक को विन्यस्त की कोशिश की है:

private class SEUIProgressControllerPresentationController: UIPresentationController { 

    override func shouldPresentInFullscreen() -> Bool { 
     return false 
    } 

    private override func frameOfPresentedViewInContainerView() -> CGRect { 
     return super.frameOfPresentedViewInContainerView().insetBy(dx: 40, dy: 100) 
    } 

    ... 
} 

ये सेटिंग्स प्रस्तुत नियंत्रक के शीर्ष के लिए कदम कर स्टेटस बार से बाहर है लेकिन स्टेटस बार अभी भी प्रभावित है। क्या कोई ऐसी संपत्ति है जो मुझे याद आ रही है जो मेरे व्यू कंट्रोलर को स्टेटस बार शैली को अपडेट करने से रोक देगी?

उत्तर

3

अद्यतन

ऐसा लगता है कि यह आईओएस से 10 में निर्धारित किया गया है की तरह डिफ़ॉल्ट व्यवहार प्रस्तुत दृश्य नियंत्रक जब तक या तो प्रस्तुत दृश्य नियंत्रक modalPresentationCapturesStatusBarAppearance == true या आप से एक का उपयोग किया है से स्थिति पट्टी नियमों की अनदेखी करने के लिए है स्टेटस बार स्पेस में विस्तारित कई अंतर्निहित प्रस्तुति नियंत्रक (.custom नहीं)।

असल में, कस्टम के लिए व्यवहार मजबूर ऑप्ट-इन के बजाय डिफ़ॉल्ट ऑप्ट-आउट में बदल गया है।


आईओएस 9.x के लिए और कम

ज्यादा खुदाई के बाद, आवेदन की स्थिति पट्टी रंग की स्थापना के लिए आंतरिक तर्क इस तरह दिखता है:

var viewController = window.rootViewController! 

while let presentedViewController = viewController.valueForKey("_presentedStatusBarViewController") as? UIViewController { 
    viewController = presentedViewController 
} 

while let childViewController = viewController.childViewControllerForStatusBarStyle() { 
    viewController = childViewController 
} 

let style = viewController.preferredStatusBarStyle() 

दृश्य नियंत्रक की संपत्ति _presentedStatusBarViewController असाइन किया गया है प्रेजेंटेशन के दौरान इसकी प्रेजेंटेशन कंट्रोलर की निजी विधि _shouldChangeStatusBarViewController() के मूल्य के आधार पर। इस विधि का डिफ़ॉल्ट कार्यान्वयन सत्य लौटने के लिए है, _UIAlertControllerPresentationController और कुछ अन्य प्रस्तुति नियंत्रक झूठी लौट रहे हैं।

सबसे सीधा रास्ता है कि स्थिति पट्टी में परिवर्तन नहीं करने के लिए इसका मतलब है कि अपनी प्रस्तुति नियंत्रक के लिए इस विधि को जोड़ने के लिए बस है:

private class SEUIProgressControllerPresentationController: UIPresentationController { 

    @objc func _shouldChangeStatusBarViewController() -> Bool { 
     return false 
    } 

    ... 
} 

दुर्भाग्य से, यह एक App स्टोर समीक्षा पास नहीं होंगे।

इसके बजाय, मैं क्या कर रहा हूँ तर्क यह है कि मेरे विचार नियंत्रक में पेश दृश्य नियंत्रक पर लागू किया जाएगा पुनः है:

public class SEUIProgressController: UIViewController { 

    ... 
    public override func preferredStatusBarStyle() -> UIStatusBarStyle { 

     guard var targetViewController = presentingViewController else { 
      return .LightContent 
     } 

     while let parentViewController = targetViewController.parentViewController { 
      targetViewController = parentViewController 
     } 

     while let childViewController = targetViewController.childViewControllerForStatusBarStyle() { 
      targetViewController = childViewController 
     } 

     return targetViewController.preferredStatusBarStyle() 
    } 

    public override func prefersStatusBarHidden() -> Bool { 

     guard var targetViewController = presentingViewController else { 
      return false 
     } 

     while let parentViewController = targetViewController.parentViewController { 
      targetViewController = parentViewController 
     } 

     while let childViewController = targetViewController.childViewControllerForStatusBarHidden() { 
      targetViewController = childViewController 
     } 

     return targetViewController.prefersStatusBarHidden() 
    } 
} 
संबंधित मुद्दे