@IBDesignable аварійний агент


74

Коли я пишу свій власний- UIButtonрозширений клас і створюю його @IBDesignable, я отримую дві помилки в Interface Builder, а саме:

  • Main.storyboard: помилка: IB Designables: Не вдалося оновити статус автоматичного макета: Агент зірвався, оскільки fd закрито
  • Main.storyboard: помилка: IB Designables: Не вдалося відобразити екземпляр RandjeUIButton: Агент зірвався

Ось мій код:

import UIKit

@IBDesignable
class RandjeUIButton: UIButton {
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.backgroundColor = UIColor.blackColor()
    }
}

Я працюю в Xcode 7 beta 2 в OS X 10.11 beta 2. (Запуск у VM)


11
Вам потрібно перевизначити , init(frame: CGRect)а також
Ерік Цянь

3
Я зробив це, помилки щодо агента тепер усуваються. Я все ще бачу помилку збірки в Interface Builder зараз, коли вибираю мітку в інспекторі посвідчень?
jbehrens94

1
@EricQian Я також перевизначає перевизначення init (кадр: CGRect) та необхідний метод init? (Кодер aDecoder: NSCoder). Все одно отримана та сама помилка.
Радж Аггравал

Відповіді:


120

Конструктор інтерфейсів Xcode вимагає, щоб ви реалізували обидва або жоден ініціалізатор, щоб @IBDesignableкласи правильно відображалися в IB.

Якщо ви реалізуєте, required init(coder aDecoder: NSCoder)вам доведеться також перевизначити init(frame: CGRect), інакше "агент не спрацює", як видно з помилок, які видає Xcode.

Для цього додайте до свого класу такий код:

override init(frame: CGRect) {
    super.init(frame: frame)
}

12
Я не думаю, що це причина. У мене обидва методи, я на 7.2. Це все ще падає.
Alix

1
Це було причиною для мене, я видалив це, init(frame: CGRect)бо лише ініціалізував його з розкадрування.
Kyle Goslan

2
@mathielo Я також перевизначаю перевизначення init (кадр: CGRect) та необхідний метод init? (кодер aDecoder: NSCoder). Досі
трапилася

1
Для мене це виявилося дуже важким завданням налагодження. Я підкласував клас, який був присутній в іншому фреймворку (Pod). Батьківський клас мав один із методів init без загальнодоступної області (за замовчуванням внутрішній). Отже, метод init не був помітний у моєму джерелі. Нарешті, зрозумів це і зробив копію батьківського класу в джерелі мого проекту. Дуже дякую!
KK

1
Цих двох ініціатив може бути недостатньо. Візьмемо для прикладу UISegmentedControl, вам слід також реалізувати перевизначення init (items: [Any]?) .
Bagusflyer

23

Я зіткнувся з тією ж проблемою і вирішив її таким чином:

  1. Проблема:

помилка: IB Designables: Не вдалося оновити стан автоматичного макетування: Агент зірвався

  1. Знайдіть у файлі перевірки кнопку налагодження та натисніть її.

налагоджувати

  1. Тоді Xcode скаже вам, де проблема. У моєму випадку я кидаю IBDesignableперед класом.

  2. Потім я його очищаю і відновлюю, помилка зникла


Привіт @Azure, я теж стикаюся з проблемою. Xcode (7.3) не рухає мене до рядка коду, що спричиняє проблему, коли я натискаю кнопку Налагодження, як ви добре показали на доданому зображенні. Це помилка Xcode?
Саувік Долуй

Привіт ~ Ви вирішили свою проблему зараз? Я також використовую Xcode (7.3). Будь ласка, переконайтеся, що ви вибрали подання, що призводить до збою, і натисніть кнопку налагодження.
Azure Yu

2
Не забудьте створити точку зупинки "Усі винятки" перед тим, як натиснути кнопку Налагодження, таким чином налагоджувач зупинить або декілька вказівок після аварії, де ви можете просто натиснути свій код у списку трасування стека, або прямо на інструкція, яка викликає збій.
carlos_ms

11

Існує безліч проблем, які можуть спричинити це. Запустіть консоль і знайдіть звіт про аварійне завершення роботиIBDesignablesCocoaTouch...

Я щойно вирішив проблему із стороннім призначуваним, який мав проблеми із valueForKeyсемантикою.


11

У Xcode 7.3 жодне з наведених вище рішень не спрацювало для мене, але прийнята відповідь на це запитання зробила: Не вдалося відобразити екземпляр IB Designables

  1. Очистити похідні дані Xcode для проекту. Вони знаходяться в ~ / Library / Developer / Xcode / DerivedData
  2. Очистіть поточну збірку, натиснувши ⌘⇧K
  3. Створіть свій проект
  4. У розкадровці перейдіть до меню Редактор і виконайте функцію Оновити всі подання; дочекайтеся завершення збірки, і помилки повинні бути знищені

Мені не потрібно було робити 4-й крок для вирішення проблеми (і отримати свій PaintCode-drawRect'd UIView для малювання в розкадруванні), включений сюди про всяк випадок.

Кредит @Mojtaba та @WeZZard


11

Для мене це скористалося не використанням #if !TARGET_INTERFACE_BUILDER. В основному я мав якийсь код, який призведе до доступу до шляху в моєму Bundle ...

Bundle.main.path(forResource: "Foo", ofType: "plist")

Проблема полягає в тому, що при запуску в IB (а не у вашому додатку), Bundle.mainваш додаток ...

(lldb) po Bundle.main
NSBundle </Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Overlays> (loaded)

Отже, відповідь на це - просто @IBDesignable UIViewуважно переглянути свій код і використовувати #if !TARGET_INTERFACE_BUILDERдля чого-небудь (у моєму випадку це, наприклад, звернення CoreLocation), що не має сенсу під час роботи під час проектування.

Як я це налагодив і знайшов

Це те, що ви бачите, використовуючи під Editor -> Debug Selected Viewчас вибору вашого @IBDesignable UIViewв розкадруванні:

Це те, що ви бачите під час використання <code> Editor -> Debug Selected View </code> під час вибору <code> @IBDesignable UIView </code> на вашій розкадровці

Потім ви потрапите в потрібне місце

Навігатор налагодження

У моєму випадку, як ви можете бачити, initXXXXробив програму assert, яка аварійно завершувала роботу під час проектування, оскільки вона шукала значення у файлі в моєму Bundle - Xcode, під час проектування.


Який сенс використовувати @IBDesignable, якщо ми маємо використовувати> #if !TARGET_INTERFACE_BUILDER
Яш Беді

9

Я знайшов щось дійсно важливе при використанні UIImage у будь-якому класі з позначкою @IBDesignable. Класичний init UIImage призведе до збою агента:

let myImage = UIImage(named: String) // crash the agent

Рішення полягає у використанні цього методу ініціювання UIImage:

let myImage = UIImage(named: String, in: Bundle, compatibleWith: UITraitCollection)

Приклад робочого коду:

let appBundle = Bundle(for: type(of: self))
let myImage = UIImage(named: "myImage", in: bundle, compatibleWith: self.traitCollection))

Де self - це ваш клас із ключовим словом @IBDesignable. Xcode 9.4, Swift 4.1


8

XCode 10, Swift 4.2

Я знайшов тут відповідь

Рішення було простим - зміна способу вирішення набору в required init?(coder aDecoder: NSCoder)методі мого власного класу подання.

    Bundle.main.loadNibNamed(String(describing: TestView.self), owner: self, options: nil)

потрібно було змінити на

let bundle = Bundle(for: TestView.self)
bundle.loadNibNamed(String(describing: TestView.self), owner: self, options: nil)

2

Ось як я вирішую цю проблему:

  • Переконайтесь, що розетки правильно ініціалізовані
  • Властивості @IBInspectable були б належним чином ініціалізовані
  • у файлі xib натисніть на заповнювач власника файлу, перейдіть до інспектора посвідчень, переконайтеся, що він не має будь-яких значень за замовчуванням

import UIKit

@IBDesignable class TestView: UIView {
    
    @IBOutlet weak var label: UILabel!
    
    
    @IBInspectable var textLabel1: String? {
        get {
            return label.text
        }
        set {
            label.text = newValue
        }
    }

    
    // MARK: Setup
    
    var view1: UIView!
    var nibName: String = "TestView"
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        xibSetup()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        xibSetup()
    }
    
    private func xibSetup() {
        view1 = loadViewFromNib()
        
        view1?.frame = self.bounds
        view1?.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
        
        if view1 != nil {
            addSubview(view1!)
            //textLabel1 = "ok"
        }
    }
    
    private func loadViewFromNib() -> UIView? {
        let bundle = NSBundle(forClass: self.dynamicType)
        let nib = UINib(nibName: nibName, bundle: bundle)
        for object in nib.instantiateWithOwner(self, options: nil) {
            if let view: UIView = object as? UIView {
                return view
            }
        }
        return nil
    }
    
    
}

Використання:

введіть тут опис зображення


2

Просто повторно відкрийте код в іншій системі налаштування Xcode. У моєму випадку це спрацювало.


Здається, це працює у деяких випадках. у мене була та сама проблема, я пробував усі можливі речі, які не змогли виправити проблему, і, нарешті, я повністю закрив xcode і відкрив інший проект, який не реалізовував жодного @IBDesignable, і відкрив проект, в якому агент аварійно завершував роботу, і повідомлення про помилки зникли. у мене немає жодної вагомої логіки за цим, але, схоже, xcode має якесь болото :(
занурення

1

Я витратив на це цілий день і нарешті вирішив свою проблему введіть тут опис зображення

Я вибрав Build для цілі як 8.0, і це все для мене виправляє.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.