2015-12-16 7 views
6
शून्य

मैं एक आवेदन पत्र में कुछ 3 डी स्पर्श को शामिल करने की कोशिश कर रहा हूँ और मैं कहाँ forceTouchCapability जांच viewWillAppear/viewDidAppear में viewDidLoad पर nil लेकिन नहीं लौटा रहा है एक अजीब मुद्दा आई है forceTouchCapability।लौटने

मैं में के रूप में निम्नलिखित ध्यान रखें कि यह केवल उसी दृश्य नियंत्रक पर traitCollection संपत्ति forceTouchCapability का जवाब सत्यापित करने के लिए 9+ iOS पर तो मैं जोड़ दिया है चेक की सुविधा उपलब्ध है कर रहा हूँ:

- (void)loadView { 

    self.view = [[MyView alloc] init]; 
} 

- (void)viewDidLoad { 

    [super viewDidLoad]; 

    // Checking the force touch availability here 
    if ([self.traitCollection respondsToSelector:@selector(forceTouchCapability)] && 
     self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) { 

     // This won't get called because forceTouchCapability is returning nil 
     // which corresponds to UIForceTouchCapabilityUnknown 
     [self registerForPreviewingWithDelegate:self sourceView:self.view]; 
    } 
} 

LLDB में if बयान पर एक ब्रेकपाइंट, po [self.traitCollection forceTouchCapability] रिटर्न में प्रवेश nil जो UIForceTouchCapabilityUnknown से मेल खाती है के साथ। हालांकि, traitCollection ही nil नहीं है।

UIForceTouchCapabilityUnknown के लिए प्रलेखन के अनुसार:

UIForceTouchCapabilityUnknown: The availability of 3D Touch is unknown. For example, if you create a view but have not yet added it to your app’s view hierarchy, the view’s trait collection has this value.

इस बिंदु से पदानुक्रम में जोड़े नहीं गए दृश्य है?

अगर कोई पहले इस समस्या का भी करना पड़ा है मैं उत्सुक हूँ और कैसे इस को हल करने के लिए? मैं इसे viewDidAppear में जोड़ने से बचना चाहता हूं क्योंकि इसे काफी कुछ कहा जा सकता है।

यदि यह मदद करता है, मैं इस पर एक 6S आईओएस 9.1 पर चल रहा हूँ Xcode 7.2

उत्तर

16

दृश्य अभी तक देखें पदानुक्रम को जोड़ा नहीं किया गया है के साथ। इसलिए आप अपने चेक कहीं और डाल करने के लिए है: आप डिबग सांत्वना

(lldb) po self.view.superview 
nil 

में एक superview के लिए जाँच करते हैं कि आप क्या देख रहे हैं, दृश्य एक पदानुक्रम के लिए अभी तक जोड़ा नहीं किया गया है है के द्वारा आसानी से देख सकते हैं।

इसका कारण यह है एप्पल के ViewControllerPreview नमूना अनुप्रयोग में यह viewDidLoad में है एक तरह से भ्रामक है। लेकिन क्या यह वास्तव traitCollectionDidChange में :, क्योंकि तब आप सुनिश्चित हैं कि दृश्य एप्लिकेशन के पदानुक्रम में जोड़ा गया है चाहिए।

यह वह कोड है जिसका मैं उपयोग करता हूं (आईओएस 8 पर काम करता है, अगर आपको बाहरी सशर्त स्थानांतरित करने के लिए स्वतंत्र महसूस करने की आवश्यकता नहीं है)।

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { 
    [super traitCollectionDidChange:previousTraitCollection]; 

    if ([self.traitCollection respondsToSelector:@selector(forceTouchCapability)]) { 
     if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) { 
      // retain the context to avoid registering more than once 
      if (!self.previewingContext) { 
       self.previewingContext = [self registerForPreviewingWithDelegate:self sourceView:self.view]; 
      } 
     } else { 
      [self unregisterForPreviewingWithContext:self.previewingContext]; 
      self.previewingContext = nil; 
     } 
    } 
} 

इस के लिए जोड़ा लाभ यह है कि आपके विचार पंजीकृत किया जाएगा/अपंजीकृत उपयोगकर्ता अपने 3 डी टच सेटिंग्स को परिवर्तित करता है, जबकि एप्लिकेशन चल रहा है है।

+0

आप कमाल के हैं, धन्यवाद! – ajfigueroa

+0

@bpapa अच्छा समाधान। पीओ के बजाय पी के उपयोग की सिफारिश करने पर विचार करें। पी बस के अंदर लग रहा है, पो निष्पादन –

1

मैंने यह समस्या भी देखी है, और पाया कि यह जांचने का सबसे आसान तरीका है कि डिवाइस बल स्पर्श का समर्थन कर सकता है या नहीं, यह स्क्रीन उदाहरण के माध्यम से कर रहा है। इस तरह की समझ में आता है क्योंकि क्षमता स्क्रीन की एक संपत्ति है। ऐसा करने का मतलब है कि आपको व्यू कंट्रोलर या व्यू के जीवन चक्र के बारे में चिंता करने की ज़रूरत नहीं है।

func canForceTouch() -> Bool 
{ 
    if iOS9OrHigher // pseudocode, a function that makes sure u only do this check on ios9 or higher 
    { 
     return UIScreen.mainScreen().traitCollection.forceTouchCapability == .Available 
    } 
    return false 
} 
0

की तरह क्या @bpapa कहा, आपका दृश्य पदानुक्रम देखने पर नहीं जोड़ा गया है अभी तक, लेकिन मेरे समाधान है अलग छोटा सा:

var token:dispatch_once_t = 0 
override func viewDidAppear(animated: Bool) { 
    dispatch_once(&token) { 
     // Force Touch Checking 
     if #available(iOS 9.0, *) { 
      if self.traitCollection.forceTouchCapability == .Available { 
       self.registerForPreviewingWithDelegate(self, sourceView: self.view) 
      } 
     } 
    } 
} 
+0

के लिए प्रयोग किया जाता है क्यों इस में अलग कतारों लाने शुरू?वास्तव में एक वैकल्पिक विधि को लागू करके एसडीके के अनुरूप एक बहुत साफ दृष्टिकोण है। – bpapa

+0

@bpapa हम अभी भी मुख्य कतार का उपयोग कर रहे हैं (यह जवाब देखें http://stackoverflow.com/a/25900466) ... मैं इस कोड को देखने में देख रहा हूं DidAppear यह सुनिश्चित करने के लिए कि सभी विचार पदानुक्रम में हैं .. और प्रेषण एक बार क्योंकि ViewDidAppear को कई बार बुलाया जा सकता है जिसे आप जानते हैं :) – Husam

संबंधित मुद्दे