Nie można utworzyć wystąpienia klasy o nazwie IBNSLayoutConstraint

81

Używam XCode6 beta i wypróbowuję Swift. Kiedy umieszczam pewne ograniczenia automatycznego układu w kontrolerze widoku, aplikacja ulega awarii z następującym błędem: Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: 'Could not instantiate class named IBNSLayoutConstraint'

zbrox
źródło
Niewiele kodu do umieszczenia w tym miejscu :) Kontroler widoku to zwykły, świeżo utworzony kontroler UIViewController z kilkoma wyjściami i zwykłymi viewDidLoad i didReceiveMemoryWarning. Poza tym istnieją ograniczenia w programie Interface Builder. Myślę, że mogę tutaj dodać kod kontrolera widoku.
zbrox,

Odpowiedzi:

221

Otrzymujesz ten błąd, ponieważ ustawiłeś ograniczenie dla IBOutlet, które jest usuwane w czasie wykonywania. Dzieje się tak, gdy ustawisz ograniczenie jako symbol zastępczy w programie Interface Builder. Ponieważ ograniczenie jest usuwane, gdy przechodzi do jego przywrócenia z archiwum, generuje błąd z informacją, że nie może tego zrobić.

Istnieją dwa sposoby, aby to poprawić.

Metoda 1

  1. Kliknij prawym przyciskiem myszy scenorys> Otwórz jako> Kod źródłowy
  2. W otwartym pliku XML storyboardu wyszukaj placeholder="YES".
  3. Znajdziesz ograniczenia, które mają zostać usunięte w czasie wykonywania. Usuń atrybut zastępczy z ograniczenia, zapisz i zamknij.
  4. Uruchom aplikację, a problem powinien zostać naprawiony.

Metoda 2

  1. Znajdź ograniczenie powodujące problemy w programie Interface Builder. Usuń zaznaczenie opcji Placeholder w GUI. Powinien to być jeden z ograniczeń ustawionych na IBOutlet w ViewController, który powoduje awarię.

Edytor atrybutów programu Interface Builder z zaznaczoną opcją symbolu zastępczego.

Tak to powinno wyglądać:

Edytor atrybutów Interface Builder z niezaznaczoną opcją Placeholder.

Alternatywny

Zakładając, że faktycznie chcesz, aby ograniczenie było symbolem zastępczym, musisz usunąć wszelkie punkty odniesienia. Aby to zrobić, wybierz ograniczenie, które ma być symbolem zastępczym. Następnie otwórz inspektora połączeń (przycisk znajdujący się najdalej po prawej stronie, który wygląda tak: (->)), a następnie usuń wszelkie odnośniki, które mogą istnieć w tym ograniczeniu.

Sandy Chapman
źródło
1
A co jeśli chcesz, aby ograniczenie było symbolem zastępczym? developer.apple.com/library/ios/documentation/UserExperience/…
Daniel Galasko,
2
@DanielGalasko Jeśli chcesz, aby był on symbolem zastępczym, nie przypisuj go do IBOutlet.
Sandy Chapman
@SandyChapman To ma sens! Wielkie dzięki Sandy, czy możesz to uwzględnić w swojej odpowiedzi, abym mógł zagłosować za?
Daniel Galasko,
1
@DanielGalasko, jasne. To dobra uwaga, moja odpowiedź polegała na przyjęciu założenia, że ​​chcesz ograniczyć IBOutlet.
Sandy Chapman,
@SandyChapman: Czy istnieje sposób, aby dowiedzieć się, które ograniczenie to powoduje? Mój projekt jest zbyt duży, aby móc przejść przez każdy z nich, a zrzut stosu nie wskazuje, które z ograniczeń. Próbowałem również wyszukać symbol zastępczy = "TAK", ale nie mogłem znaleźć żadnego w xml.
EmbCoder,
6

Miałem teraz ten sam problem, a poniższe zadziałały.

Udostępniłem działającą wersję mojej aplikacji w App Store, wróciłem do pracy nad nią ponownie kilka dni później, dotykając jednej z moich kart w UITabBarController, awaria uległa awarii:

Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: 'Could not instantiate class named IBNSLayoutConstraint'

Nie miałem żadnych ograniczeń układu zastępczego, o których wiedziałem, ani gniazd, które nie powinny być zdefiniowane.

Rozwiązaniem dla mnie było po prostu wyłączenie klas rozmiarów i zachowanie danych klas rozmiaru dla iPhone'a (aplikacja jest tylko dla iPhone'a). To musiało usunąć wszystko, co przegapiłem w klasach wielkości. Chcę klas wielkości, więc włączyłem je ponownie i aplikacja znów działała.

Philip Moore
źródło
Dziękuję za Twój post! Właśnie doświadczyłem tego samego, niczego nie zmieniłem w mojej aplikacji. W moim przypadku zawiesił się podczas ładowania „UIPageViewController”. Wyłączenie klas wielkości i ponowne ich oznaczenie rozwiązało błąd.
nor0x
Dziękuję Ci!! To samo doświadczenie co nor0x. Bardzo dziwne, ale cudownie jest znaleźć tutaj rozwiązanie.
Andy Weinstein
4

Niekoniecznie musi to być problem z ograniczeniami. U mnie było to spowodowane tym, że nie zaznaczyłem „Zainstalowano” dla klasy rozmiaru, która dotyczy mojego układu, patrz tutajinstalacja musi być sprawdzona

abinop
źródło
1

Wystąpił problem z użyciem klas wielkości. Wyłączyłem tę opcję we właściwościach scenorysu i używam tylko układu automatycznego. Nie był to taki duży problem, ponieważ aplikacja jest przeznaczona tylko na iPhone'a.

zbrox
źródło
Wyłączenie „Klasy rozmiaru” i uruchomienie również rozwiązało problem. Następnie ponownie włączam klasy wielkości i wszystko działało.
John Fowler,
1

W końcu przydarzyło mi się to, że wyciąłem podwidok wewnątrz Interface Builder, aby skopiować go do innego xib. To pozostawiło widok podrzędny w oryginalnym konstruktorze interfejsu XIB z wyszarzeniem. Po usunięciu widoku podrzędnego z jego pierwotnego miejsca (poprzez zaznaczenie i usunięcie). Udało mi się pozbyć błędu.

wilforeal
źródło
0

W oknie inspektora, gdy zaznaczysz plik xib, dostępna jest opcja, która nie będzie używać ograniczeń pod „Pokaż plik inspektora” w inspektorze o nazwie „Użyj autoukładu”.

iPatel
źródło
Wiem o tym, ale chcę użyć autoukładu dla tego storyboardu.
zbrox,
Dzięki. Próbowałem się nimi bawić, ale to nie pomogło, ponieważ używałem również klas wielkości. Ale przeczytam to i zobaczę, czy coś przeoczyłem. Dzięki jeszcze raz.
zbrox,
0

Dokonałem zmiany w widoku przewijania, aby umożliwić poprawne działanie kontrolek selektora osadzonych w nim przy użyciu rozwiązania, które znalazłem w innym miejscu w Stackoverflow. Mój nowy storyboard po prostu dodał te atrybuty do widoku przewijania, co wydawało mi się w porządku.

     delaysContentTouches="NO" canCancelContentTouches="NO"

Ale dodatkowo zobaczyłem w moim storyboardzie w innej scenie następujący nowy fragment:

                    <variation key="default">
                        <mask key="subviews">
                            <exclude reference="86H-aM-wei"/>
                        </mask>
                    </variation>

Nie mam pojęcia, skąd się wzięło. Na początku zignorowałem to, ponieważ wszystko wydawało się działać na mojej maszynie deweloperskiej. Ale kiedy kompilacja została zbudowana jako wersja Release i przetestowana, nastąpiła awaria. Usunięcie tego fałszywego (?) Fragmentu naprawiło awarię i nie miało wpływu na nic innego.

Andy Weinstein
źródło
0

Miałem ten problem, gdy miałem przycisk w niestandardowym UICollectionViewCell i miałem niektóre z jego ograniczeń jako IBOutlets w tej klasie. Przeniosłem przycisk z komórki do nadrzędnego kontrolera widoku, a IBOutlets nadal były przywoływane w komórce, ale tak naprawdę nie istniały w komórce, więc wszystko wysadziłem. Wystarczyło usunąć te IBOutlety i wszystko znów działało dobrze!

CMash
źródło