UIViewAlertForUnsatisfiableConstraints पर कैसे फंसें?


234

मुझे अपने डिबगर लॉग में एक त्रुटि दिखाई दे रही है:

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x191f0920 H:[MPKnockoutButton:0x17a876b0]-(34)-[MPDetailSlider:0x17a8bc50](LTR)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

मैं उस कॉल पर कैसे फंस सकता हूं? यह मेरे कोड में कहीं भी दिखाई नहीं देता है।

Screenshot1


10 में से 9 मामलों में: यह सिर्फ इसके कारण होता है: योरू स्टोरीबोर्ड पर कुछ दृश्य या आइटम के लिए, आप "इंस्टॉल किए गए" को अनचेक करते हैं। (उदाहरण के लिए, सिर्फ एक विकास बटन या ऐसी चीज जिसकी आपको किसी और जरूरत नहीं थी।) सामान्य तौर पर, यह "नॉट-इंस्टाल्ड" को बुरी तरह से संभालता है: यह अक्सर उन बाधाओं को छोड़ देता है जो बिना इंस्टॉल किए गए आइटम के बिना अर्थहीन हो जाते हैं। अक्सर समाधान केवल उन वस्तुओं को हटाने के लिए होता है जिनके बारे में आप भूल गए हैं, जो "नहीं-स्थापित" के आसपास बैठे हैं - बस उन्हें हटाएं।
फटी

जवाबों:


442

इस पोस्ट ने मुझे बहुत बहुत मदद की !

मैंने सुझाए गए कार्य के साथ UIViewAlertForUnsatisfiableConstraints प्रतीकात्मक विराम बिंदु जोड़ा :

ओबज-सी परियोजना

po [[UIWindow keyWindow] _autolayoutTrace]

उद्देश्य-सी परियोजना में कस्टम क्रिया के साथ प्रतीकात्मक विराम

स्विफ्ट परियोजना

expr -l objc++ -O -- [[UIWindow keyWindow] _autolayoutTrace]

कस्टम क्रिया के साथ प्रतीकात्मक विराम

इस संकेत के साथ, लॉग अधिक विस्तृत हो गया, और मेरे लिए यह पहचानना आसान हो गया कि किस दृश्य ने बाधा को तोड़ा था।

UIWindow:0x7f88a8e4a4a0
|   UILayoutContainerView:0x7f88a8f23b70
|   |   UINavigationTransitionView:0x7f88a8ca1970
|   |   |   UIViewControllerWrapperView:0x7f88a8f2aab0
|   |   |   |   UIView:0x7f88a8ca2880
|   |   |   |   |   *UIView:0x7f88a8ca2a10
|   |   |   |   |   |   *UIButton:0x7f88a8c98820'Archived'
|   |   |   |   |   |   |   UIButtonLabel:0x7f88a8cb0e30'Archived'
|   |   |   |   |   |   *UIButton:0x7f88a8ca22d0'Download'
|   |   |   |   |   |   |   UIButtonLabel:0x7f88a8cb04e0'Download'
|   |   |   |   |   |   *UIButton:0x7f88a8ca1580'Deleted'
|   |   |   |   |   |   |   UIButtonLabel:0x7f88a8caf100'Deleted'
|   |   |   |   |   *UIView:0x7f88a8ca33e0
|   |   |   |   |   *_UILayoutGuide:0x7f88a8ca35b0
|   |   |   |   |   *_UILayoutGuide:0x7f88a8ca4090
|   |   |   |   |   _UIPageViewControllerContentView:0x7f88a8f1a390
|   |   |   |   |   |   _UIQueuingScrollView:0x7f88aa031c00
|   |   |   |   |   |   |   UIView:0x7f88a8f38070
|   |   |   |   |   |   |   UIView:0x7f88a8f381e0
|   |   |   |   |   |   |   |   UIView:0x7f88a8f39fa0, MISSING HOST CONSTRAINTS
|   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8cb9bf0'Retrieve data'- AMBIGUOUS LAYOUT for UIButton:0x7f88a8cb9bf0'Retrieve data'.minX{id: 170}, UIButton:0x7f88a8cb9bf0'Retrieve data'.minY{id: 171}
|   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8f3ad80- AMBIGUOUS LAYOUT for UIImageView:0x7f88a8f3ad80.minX{id: 172}, UIImageView:0x7f88a8f3ad80.minY{id: 173}
|   |   |   |   |   |   |   |   |   *App.RecordInfoView:0x7f88a8cbe530- AMBIGUOUS LAYOUT for App.RecordInfoView:0x7f88a8cbe530.minX{id: 174}, App.RecordInfoView:0x7f88a8cbe530.minY{id: 175}, App.RecordInfoView:0x7f88a8cbe530.Width{id: 176}, App.RecordInfoView:0x7f88a8cbe530.Height{id: 177}
|   |   |   |   |   |   |   |   |   |   +UIView:0x7f88a8cc1d30- AMBIGUOUS LAYOUT for UIView:0x7f88a8cc1d30.minX{id: 178}, UIView:0x7f88a8cc1d30.minY{id: 179}, UIView:0x7f88a8cc1d30.Width{id: 180}, UIView:0x7f88a8cc1d30.Height{id: 181}
|   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8cc1ec0- AMBIGUOUS LAYOUT for UIView:0x7f88a8cc1ec0.minX{id: 153}, UIView:0x7f88a8cc1ec0.minY{id: 151}, UIView:0x7f88a8cc1ec0.Width{id: 154}, UIView:0x7f88a8cc1ec0.Height{id: 165}
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e68e10- AMBIGUOUS LAYOUT for UIView:0x7f88a8e68e10.minX{id: 155}, UIView:0x7f88a8e68e10.minY{id: 150}, UIView:0x7f88a8e68e10.Width{id: 156}
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e65de0- AMBIGUOUS LAYOUT for UIImageView:0x7f88a8e65de0.minX{id: 159}, UIImageView:0x7f88a8e65de0.minY{id: 182}
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8e69080'8-6-2015'- AMBIGUOUS LAYOUT for UILabel:0x7f88a8e69080'8-6-2015'.minX{id: 183}, UILabel:0x7f88a8e69080'8-6-2015'.minY{id: 184}, UILabel:0x7f88a8e69080'8-6-2015'.Width{id: 185}
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0690'16:34'- AMBIGUOUS LAYOUT for UILabel:0x7f88a8cc0690'16:34'.minX{id: 186}, UILabel:0x7f88a8cc0690'16:34'.minY{id: 187}, UILabel:0x7f88a8cc0690'16:34'.Width{id: 188}, UILabel:0x7f88a8cc0690'16:34'.Height{id: 189}
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8cc2050- AMBIGUOUS LAYOUT for UIView:0x7f88a8cc2050.minX{id: 161}, UIView:0x7f88a8cc2050.minY{id: 166}, UIView:0x7f88a8cc2050.Width{id: 163}
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e69d90- AMBIGUOUS LAYOUT for UIImageView:0x7f88a8e69d90.minX{id: 190}, UIImageView:0x7f88a8e69d90.minY{id: 191}, UIImageView:0x7f88a8e69d90.Width{id: 192}, UIImageView:0x7f88a8e69d90.Height{id: 193}
|   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3cc00
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e618d0
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e5ba10
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3cd70
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e58e10
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e5e7a0
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3cee0
|   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3dc70
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e64dd0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8e65290'Average flow rate'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8e712d0'177.0 ml/s'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8c97150'1299.4'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3dde0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3df50'Maximum flow rate'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cbfdb0'371.6 ml/s'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0230'873.5'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3e2a0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3e410'Total volume'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0f20'371.6 ml'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3e870
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3ea00'Time do max. flow'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0ac0'3.6 s'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3ee10
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3efa0'Flow time'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cbf980'2.1 s'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3f3e0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3f570'Voiding time'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc17e0'3.5 s'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3f9a0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3fb30'Voiding delay'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc1380'1.0 s'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e65000
|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8e52f20'Show'
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e6e1d0
|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8e52c90'Send'
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e61bb0
|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8e528e0'Delete'
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e6b3f0
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3ff60
|   |   |   |   |   |   |   |   |   *UIActivityIndicatorView:0x7f88a8cba080
|   |   |   |   |   |   |   |   |   |   UIImageView:0x7f88a8cba700
|   |   |   |   |   |   |   |   |   *_UILayoutGuide:0x7f88a8cc3150
|   |   |   |   |   |   |   |   |   *_UILayoutGuide:0x7f88a8cc3b10
|   |   |   |   |   |   |   UIView:0x7f88a8f339c0
|   |   UINavigationBar:0x7f88a8c96810
|   |   |   _UINavigationBarBackground:0x7f88a8e45c00
|   |   |   |   UIImageView:0x7f88a8e46410
|   |   |   UINavigationItemView:0x7f88a8c97520'App'
|   |   |   |   UILabel:0x7f88a8c97cc0'App'
|   |   |   UINavigationButton:0x7f88a8e3e850
|   |   |   |   UIImageView:0x7f88a8e445b0
|   |   |   _UINavigationBarBackIndicatorView:0x7f88a8f2b530

Legend:
    * - is laid out with auto layout
    + - is laid out manually, but is represented in the layout engine because translatesAutoresizingMaskIntoConstraints = YES
     - layout engine host

तब मैंने निष्पादन को रोक दिया ठहराव और मैंने समस्याग्रस्त दृश्य की पृष्ठभूमि का रंग कमांड के साथ बदल दिया ( आपके ऑब्जेक्ट की 0x7f88a8cc2050मेमोरी एड्रेस के साथ बदल रहा है ...)

Obj सी

expr ((UIView *)0x7f88a8cc2050).backgroundColor = [UIColor redColor]

स्विफ्ट 3.0

expr -l Swift -- import UIKit
expr -l Swift -- unsafeBitCast(0x7f88a8cc2050, to: UIView.self).backgroundColor = UIColor.red

... और परिणाम यह बहुत बढ़िया था!

संकेत किया गया दृश्य

एकदम कमाल का! आशा करता हूँ की ये काम करेगा।


3
@iAnurag आप कंसोल क्षेत्र में कमांड चला सकते हैं, जब निष्पादन रोक दिया जाता है।
थोमास कैलम

2
@TomCalmon मैंने ऐसा ही किया ... लेकिन यह निम्न त्रुटि दिखाता है rror: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x7f88a8cc2050). The process has been returned to the state before expression evaluation.
iAnurag

2
expr -l objc++ -O -- [[UIWindow keyWindow] _autolayoutTrace]nilमेरे लिए रिटर्न
इगोर एंड्रीव

2
सुनिश्चित करें कि आप अपनी वस्तु के मेमोरी पते के साथ 0x7f88a8cc2050 को प्रतिस्थापित करते हैं और निष्पादन के कारण कमांड को कंसोल में चलाते हैं।
टॉम हावर्ड

3
Unfreakingbelievable। यहाँ महान टिप, पूरी तरह से मुझे सीधे मुद्दे पर जाने में मदद की। एक बार जब आइटम को लाल रंग में बदल दिया जाता है, तो यदि संभव हो तो निष्पादन जारी रखें और आप हाइलाइट देखेंगे।
आरोन

255

तुम एक जोड़ना चाहें, Symbolic Breakpoint। ऐसा करने के लिए Apple एक उत्कृष्ट मार्गदर्शिका प्रदान करता है ।

  1. ब्रेकपॉइंट नेविगेटर खोलें cmd+7( cmd+8Xcode 9 में)
  2. Addनिचले बाएँ में बटन पर क्लिक करें
  3. चुनते हैं Add Symbolic Breakpoint...
  4. जहां यह कहता है कि Symbolबस टाइप करेंUIViewAlertForUnsatisfiableConstraints

आप इसे किसी भी अन्य ब्रेकपॉइंट की तरह भी मान सकते हैं, इसे चालू और बंद कर सकते हैं, कार्रवाई जोड़ सकते हैं या संदेश भेज सकते हैं।


55
मुझे अभी समझ नहीं आया कि मैं इस संकेत के साथ समस्या को बेहतर तरीके से कैसे मिटा सकता हूं। मैंने एक प्रतीकात्मक विराम बिंदु जोड़ा लेकिन यह अभी भी मुझे पर्याप्त जानकारी नहीं देता है कि समस्या क्या है। एकमात्र तरीका लाइन को लाइन से पढ़ने और समझने का प्रयास करता है कि समस्या का कारण क्या है .... अन्यथा बाधाओं को साफ़ करना और फिर से असिस्टेंट व्यू में पूर्वावलोकन के साथ उन्हें जोड़ना सबसे अधिक मदद करनी चाहिए!
एलेक्स Cio

11
यह ब्रेकपॉइंट पर रुकने के बाद अधिक जानकारी प्राप्त करने में मदद कर सकता है: staxmanade.com/2015/06/debugging-ios-autolayout-issues
fabb

1
बस यह जोड़ते हुए कि अब आप आईबी में बाधाओं को सीधे पहचानकर्ता दे सकते हैं ताकि जब आप उन्हें डिबग कर रहे हों, तो वह नाम जो आप देखेंगे।
मार्क ए। डोनोहे

2
(@MarqueIV पर अनुवर्ती) के NSLayoutConstraintपास identifieriOS 7 - Xcode 7 और उसके बाद की एक संपत्ति है , जिसे IB स्टोरीबोर्ड से और साथ ही कोड से भी सेट किया जा सकता है। पहचानकर्ता की स्थापना करके आप आसान डीबग लॉग में सिस्टम-जनित और उपयोगकर्ता-सृजित की कमी के बीच भेद कर सकते हैं, उदाहरण के लिए myConstraint.identifier = "centered image"(स्रोत और उदाहरण: useyourloaf.com/blog/using-identifiers-to-debug-autolayout )
PDK

@AlexCio यह कैसे मदद करता है? कम से कम यह है कि यह इस समय होता है कि यह होता है। यह एक स्टैक ट्रेस देता है जहां आप पीछे हट सकते हैं और मूल पा सकते हैं ...
Honey

10

स्टीफन की सलाह का पालन किया और कोड और वाह डिबग करने की कोशिश की! इसने काम कर दिया। उत्तर डीबग संदेश में ही निहित है।

Will attempt to recover by breaking constraint NSLayoutConstraint:0x191f0920 H:[MPKnockoutButton:0x17a876b0]-(34)-[MPDetailSlider:0x17a8bc50](LTR)>

ऊपर की रेखा आपको बताती है कि रनटाइम ने इस बाधा को दूर करके काम किया। हो सकता है कि आपको अपने बटन (MPKnockoutButton) पर क्षैतिज रिक्ति की आवश्यकता न हो। एक बार जब आप इस बाधा को साफ करते हैं, तो यह रनटाइम पर शिकायत नहीं करेगा और आपको वांछित व्यवहार मिलेगा।


3
संकलक? आप रनटाइम मतलब है? संकलक ने बाधा को नहीं हटाया। संकलक ने रनटाइम से निपटने के लिए इसे वहां छोड़ दिया, इसलिए रनटाइम के दौरान "ब्रेकिंग अड़चन द्वारा पुनर्प्राप्त करें" ।
जहर

हाँ, मेरा मतलब था रनटाइम
सिटग्रुप

2

जब भी मैं उन बाधाओं को दूर करने का प्रयास करता हूं जो सिस्टम को तोड़ना था, तो आईबी में संतुष्ट करने के लिए मेरी बाधाएं अब पर्याप्त नहीं हैं (यानी आईबी में "लापता बाधाओं" से पता चलता है, जिसका अर्थ है कि वे अपूर्ण हैं और उनका उपयोग नहीं किया जाएगा)। मैं वास्तव में यह कम प्राथमिकता को तोड़ना चाहता हूं, जो (और यह एक धारणा है) प्रणाली को इनायत से तोड़ने की अनुमति देता है। यह शायद सबसे अच्छा समाधान नहीं है, लेकिन इसने मेरी समस्या को हल कर दिया और परिणामस्वरूप बाधाओं ने पूरी तरह से काम किया।


2
आमतौर पर यह एक ऐसी स्थिति है जहां आप एक प्लेसहोल्डर बाधा का उपयोग करना चाहते हैं जिसे रनटाइम पर हटा दिया जाता है। बाधा को एक प्लेसहोल्डर बाधा बनाने के लिए, बाधा निरीक्षक पर जाएं और "निर्माण समय पर निकालें" पर क्लिक करें। ध्यान दें कि आईबी ड्राइंग क्षेत्र में बाधा आई-बीम प्रतीक यह इंगित करने के लिए नीले से भूरे रंग में कैसे बदल जाता है।
spencery2

1
मेरी भी यही समस्या थी। जब मैं टूटी हुई बाधा को हटाता हूं तो मेरा डिजाइन टूट जाता है। इसलिए मैंने प्राथमिकता को माध्यम बनाया।
जेरेमी पीडीनल 14
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.