IB_DESIGNABLE, IBInspectable - Конструктор інтерфейсів не оновлюється


91

У мене є такий набір коду:

CustomView.h

#import <UIKit/UIKit.h>

IB_DESIGNABLE
@interface CustomView : UIView

@property (nonatomic) IBInspectable UIColor *borderColor;
@property (nonatomic) IBInspectable CGFloat borderWidth;
@property (nonatomic) IBInspectable CGFloat cornerRadius;

@end

CustomView.m

#import "CustomView.h"

@implementation CustomView

- (void)setBorderColor:(UIColor *)borderColor {
    _borderColor = borderColor;
    self.layer.borderColor = borderColor.CGColor;
}

- (void)setBorderWidth:(CGFloat)borderWidth {
    _borderWidth = borderWidth;
    self.layer.borderWidth = borderWidth;
}

- (void)setCornerRadius:(CGFloat)cornerRadius {
    _cornerRadius = cornerRadius;
    self.layer.cornerRadius = cornerRadius;
}

@end

(Для довідки Swift ця проблема також виникала із кодом Swift)

CustomView.swift

@IBDesignable
class CustomView : UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    @IBInspectable var borderColor : UIColor = UIColor.clearColor() {
        didSet {
            self.layer.borderColor = borderColor.CGColor
        }
    }

    @IBInspectable var borderWidth : CGFloat = 0.0 {
        didSet {
            self.layer.borderWidth = borderWidth
        }
    }

    @IBInspectable var cornerRadius : CGFloat = 0.0 {
        didSet {
            self.layer.cornerRadius = cornerRadius
        }
    }
}

Я додав a UIViewдо контролера перегляду на раскадровці та встановив для його підкласу значення CustomView.

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

Це додає рядок "Дизайнерські". Він застряг на "Оновлення", а підказка говорить "Очікування побудови цілі". Це ніколи не змінюється від цього статусу.

Коли я переходжу до перевірки атрибутів, я можу встановити такі IBInspectableвластивості:

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

І після встановлення вони також відображаються в "Визначених користувачем атрибутах виконання":

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

Однак статус "Designables" ніколи не виходить за межі "Оновлення" за допомогою тієї ж підказки (я кілька разів пробував Cmd + B, нічого не змінюється).

Більше того, коли я встановлюю IBInspectableвластивості, я отримую попередження для кожного з них:

IBDesignables - ігнорування визначеного користувачем атрибута виконання для шляху ключа "borderColor" на екземплярі "UIView" ... цей клас не відповідає кодуванню значення-ключ для ключа borderColor.

Знімок екрана створених попереджень:

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


Я знайомий із проблемами, що відповідають кодуванню значення ключ-значення, і загалом знаю, як їх вирішити ... але я не розумію, як вирішити цю проблему тут. За даними інспектора ідентичності подання, подання є "CustomView" (а не звичайний "UIView", який не має цих властивостей). І якби подання не було "CustomView", то ці призначувані властивості не відображались би в Інспекторі атрибутів, так? Але коли Interface Builder намагається застосувати ці атрибути до подання, він повертається до думки, що клас представлення "UIView" і не може застосувати атрибути.

Будь-яка допомога? Будь ласка, дайте мені знати, якщо я залишив якусь важливу деталь, але для чого це варто, я точно дотримувався цього підручника (крім ObjC проти Swift). Варто також зазначити, що я дотримувався цього підручника точно на іншій машині, і це спрацювало як шарм (я мав намір зробити це повідомлення вчора ввечері, але на комп’ютері, на якому я тоді був, цієї проблеми не було).


На підставі коментарів було висловлено припущення, що, можливо, .mфайл не включений і це може спричинити проблему. Я подумав, що, напевно, не зміг би зробити цей сценарій, але все одно перевірив.

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

Коли я вперше намагався це зробити, я розумів, що IB_DESIGNABLEзаняття повинні бути частиною іншої UIKitсистеми. Так що з першого екрану, ви можете бачити , що я створив основу «CustomViews», який має один клас, CustomView. Ви також побачите тут, що я також створив a OtherView, який є ідентичним CustomView, за винятком того, що він не знаходиться в окремій структурі. Однак однакова проблема зберігається на розкадруванні між обома класами.

Тут ми маємо скріншот, який вказує, що CustomView.mвключено для побудови разом із CustomViewsфреймворком:

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

Тим часом наступний знімок екрану вказує на кілька речей:

  • CustomViews.framework належним чином включено в основний проект.
  • OtherView.mтакож включено як джерело компіляції, тому навіть якщо щось не так CustomView, OtherViewмає працювати, однак воно генерує однакові помилки.
  • Main.storyboardі LaunchScreen.xibвідображаються червоними. Я поняття не маю, чому, і не маю ні найменшого поняття, чому так LaunchScreen.xib(я не торкався цього файлу), хоча, переглянувши інші проекти, я можу сказати, що Main.storyboardдля цих проектів також відображається червоним, і я нічого не робить з IB_DESIGNABLEабо IBInspectableтам.

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


Я вже кілька разів пробував і повторював це. Це працює щоразу на моєму комп’ютері вдома - я не можу вдома відтворити проблему, описану в цьому питанні. На роботі це ніколи не працює. Проблема, описана в цьому питанні, трапляється щоразу.

Обидва комп'ютери - це Mac Minis, придбані новими цього року (не нові моделі, модель кінця 2012 року). На обох комп’ютерах працює OS X Yosemite 10.10. На обох комп’ютерах працює Xcode версії 6.1. Вдома побудована (6A1052d). Сьогодні вранці я можу підтвердити, що на обох комп’ютерах виконуються однакові збірки Xcode.

Інші припустили мені, що це може бути погана оперативна пам'ять. Мені це здається надуманим. Я перезапускав проект кілька разів, перезавантажував комп’ютер кілька разів. Мені здається, якщо на комп’ютері приблизно 6 місяців була погана оперативна пам’ять, то я бачив би інші проблеми, і ця проблема була б менш послідовною. Але ця точна проблема зберігається, незважаючи на те, що неодноразово перезавантажувався весь проект з нуля та повністю перезавантажувався на комп'ютері.


Слід зазначити, що якщо я насправді скомпілюю та запустим цей проект, власний вигляд із IBInspectableвластивостями фактично відображається, оскільки я очікую, що розкадровка його відобразить. Я гадаю, що це було б навіть у випадку з директивами IB_DESIGNABLEand та IBInspectable, оскільки вони створюються як визначені користувачем атрибути виконання.


Ну, це була просто ідея. Я видалив CustomView.m із цілі, а потім отримав подібні попередження під час запуску програми.
Martin R

Це здається справжнім гремліном, враховуючи ваше порівняння з, здавалося б, однаковою машиною (яка якось відрізняється). Ви пробували розміщувати повідомлення на devforums? Здається, ви летите всліпу без додаткової інформації, а ваш процес здається обґрунтованим та раціональним. Попередження "побудувати" може не означати занадто багато, оскільки Xcode рясніє оманливими повідомленнями про помилки. Однак для випробувань ви спробували редактор -> "налагодити вибраний вигляд", так? (Можливо, це не спрацює, але варто перевірити стан розумності). Крім того, що-небудь відображається в додатку (реєстрація) Console?
Кріс Коновер,

У мене така сама проблема. Шахти з одним файлом xib, що містить IB_DESIGNABLE. Однак, перевіряючи мою настройку, я вже ввімкнув автоматичне оновлення, і я спробував оновити вручну, спочатку очистивши похідні дані тощо. Наразі нічого не працювало. Дивна річ у тому, що у мене цей контроль працював нормально, а потім він зупинився. І я не думаю, що я змінив якийсь код між ними. Божевільний
drekka

Показував попередження, як зазначено вище. Зараз створили другий клас із кодом, скопійованим з оригінального позначення IB. Цей клас чудово працює, і коли я повернувся до початкового неробочого класу, він тепер працює нормально. З цього я дійшов висновку, що десь є якийсь кеш (не у похідних даних), який не очищається, доки оригінальний ib-позначуваний не буде замінений на інший ib-призначуваний. Перехід на UIView, здається, не очищає цей кеш. Тільки інший призначений ib. Перейти до фігури :-)
drekka

Відповіді:


75

На основі пропозиції Хриско налагодити вибраний вигляд (що я вже зробив, але пішов спробувати ще раз), я помітив ще кілька варіантів внизу меню Редактор.

  • Автоматично оновлювати перегляди
  • Оновити всі перегляди

Я натиснув "Оновити всі перегляди", і після того, як Xcode трохи задумався, раптом раскадровка відображала мій погляд, як очікувалось (правильно застосовуючи мої IBInspectableвластивості).

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

Потім я ще раз пройшов весь процес, щоб підтвердити, що це рішення.

Я створив новий клас ThirdView. Цей клас знову ж таки ідентичний іншим. ThirdViewЦього разу я змінив клас свого подання на і отримав щось дещо інше:

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

Клацнувши "Показати" до попереджень:

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

Цього разу новий:

Використання класу UIView для об'єкта зі спеціальним класом, оскільки клас ThirdView не існує.

Це насправді не є більш корисним, ніж те, що вже існувало. Плюс, тепер три інших попередження дивним чином подвоїлися до 6.

У будь-якому випадку, якщо я знову натисну на "Оновити всі подання" у спадному меню "Редактор", усі помилки зникнуть, і знову, подання відображатиметься належним чином.

Тим не менше, до цього моменту все, що я робив, було тим, з чим я ніколи не возився вдома. Вдома це просто працювало. Тож я увімкнув "Автоматичне оновлення подань" і створив "FourthView" для тестування - ще раз, ідентичний першим трьом.

Після зміни класу подання на "FourthView" ярлик для означень короткий час сказав "Оновлення", а потім нарешті сказав "Актуально":

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

Отже, я перевірив свій комп’ютер вдома. "Автоматично оновлювати подання" ввімкнено на комп’ютері, який завжди працював. Його вимкнули на комп’ютері, який не був. Я ніколи не пам’ятаю, щоб торкнувся цього пункту меню. Я навіть не можу точно сказати, чи існував він до Xcode 6. Але цей параметр міг змінити ситуацію.


TL; DR, якщо у вас виникає та сама проблема, описана у питанні, переконайтеся, що ввімкнено «Автоматичне оновлення подань» (або вручну «Оновити всі подання», коли вам потрібно оновлення в IB):

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


2
Я насправді шукав, як його вимкнути, оскільки він продовжує відображатись у фоновому режимі, що робить старі MacBook справді повільними. Дякую!
Departamento B

Це може вирішити питання тимчасово, але перевірте відповідь від @ Martin-Gilles Lavoie
Ashley Mills

22

У мене є ще кілька деталей, які можуть спричинити не завантаження ваших класів IBDesignable.

Виберіть проблематичну розкадрування / xib, де повинні відображатися ваші власні подання.

У області навігатора перейдіть до Навігатора звітів у робочій області / проекті XCode.

У меню Редактор XCode натисніть (як згадав nhgrif), опцію "Оновити всі перегляди". Це призведе до того, що IB запустить компіляцію для цілої купи речей, яких ви, я впевнений, не очікували.

У Навігаторі звітів натисніть "За групою", щоб відфільтрувати вміст, і перегляньте розділ "Конструктор інтерфейсів". Ви побачите, що для завантаження користувальницького фреймворка IBDesignable views він буде компілювати БАГАТО речей. Якщо будь-яка з цих цілей НЕ компілюється, наприклад (можливо, застаріла) цільових одиниць тесту (навіть якщо вони абсолютно не пов'язані з кодом, який завантажує ці подання або розкадрування), IB не зможе завантажити вашу dll.

У моєму випадку IB намагався скомпілювати 8 цілей, у тому числі 4, де були проведені модульні тести, які не були оновлені після нещодавніх змін рефакторингу, над якими ми працювали.

Більшість змін та виправлень коду, які я зробив для того, щоб IB правильно завантажував та відображав мої митні уявлення там, де вони не пов'язані або навіть не пов'язані з цими класами, і ніколи не завантажував розкадрування в процесі запуску цих модульних тестів. Тим не менше, IB мав залежність від усього робочого простору, який складав його для роботи.


Гей, так як я можу зупинити IB від спроб завантажувати та відображати подання, не пов’язані чи пов’язані з цими класами?
HannahCarney

Я припускаю, що це пов’язано із залежностями заголовка. Чи стосуються призначувані класи інших класів, як тільки заголовок з’явиться, він створить відповідні реалізації. Apple грається з вихідним кодом графіка залежності в XC7GM, що абсолютно не вдається в нашому проекті, оскільки XCode виходить з ладу під час побудови графіка. Наступні 7.1бети не відображають проблему. Наразі наша автоматизована система побудови все ще залежить від версії 6.4, тому ми не досліджували, як її вирішити далі згідно з XC6.4. Ми будемо стрибати прямо до 7.1GM.
Martin-Gilles Lavoie

Якщо у вас декілька цілей / проектів, то це абсолютно правильна відповідь і дійсно вирішує проблему - ВСІ цілі повинні будуватися чисто, я навіть не знав, що в навігаторі звітів є розділ "Конструктор інтерфейсів"! Всі інші відповіді, які я бачив, - це, в основному, багато махів руками, які можуть тимчасово виправити ситуацію, але це остаточне рішення. Молодці.
Ashley Mills

3
Отже, згідно з цим, ми можемо зробити висновок, що атрибут IB_DESIGNABLE - це загальне лайно та марнотратство часу. Тільки уникайте його використання.
m8labs

IB_DESIGNABLE не має нічого спільного з проблемою та рішенням, переліченими вище. Це просто прапор NO-OP для IB, щоб розпізнавати корисні речі. Потрібно просто підтримувати чистоту в будинку.
Martin-Gilles Lavoie

22

Просто підказка для всіх, хто має цю проблему: не забудьте вказати тип змінної.

// Doesn't show up in IB
@IBInspectable var includeLeftSection = true

// Shows now that it knows the type
@IBInspectable var includeLeftSection : Bool = true

6

У мене було таке саме попередження, Ignoring user defined runtime attribute for key path ..хоча я абсолютно впевнений, що не зробив нічого поганого зі своїм користувацьким класом перегляду IBDesignable.

Виявилося, у моєму випадку це пов'язано з кешем Xcode.

rm -rf ~/Library/Developer/Xcode/DerivedData/*

Очищення DerivedDataі попередження пропало.


1
Ярлик у XCode для досягнення того самого результату: ⌘⇧K
Mojo66

@ Mojo66 Я вважаю, що Clean Build відрізняється від очищення папки DerivedData. Звичайно, коли-небудь чиста збірка досить гарна, щоб вирішити певні проблеми кешування Xcode.
samwize

@ Mojo66 ти мабуть мав на увазі ⌘⌥⇧K (cmd + alt + shift + K)
tzaloga

5

Якщо хтось ще стикається з помилкою, клас IB Designables не існує, з тієї ж причини, що і я. Найкраща відповідь була не моєю проблемою ... але тут є трохи пов'язана проблема ...

У вихідному коді таблиці сюжетів є властивість, яка називається customModule.

Наприклад, у мене був клас ForwardArrow в окремому фреймворку, який я випадково додав до своєї головної цілі.

Тож XML для деяких подань закінчився як customClass = "ForwardArrow" customModule = "MainTargetNameWasHere"

Коли я вилучив їх з основної цілі у збірці, дошка розповідей не оновила MainTargetNameWasHere до CustomViews, що є структурою, де він знаходився, і почав видавати, що жоден клас не знайшов помилки.

Отже, TLDR; Переконайтеся, що якщо ваш IBDesignable знаходиться в іншому фреймворку, атрибут customModule xml у вашій дошці історії має правильне значення. А якщо його взагалі немає, додайте його.

Приклад з мого джерела:

<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="MUG-jc-2Ml" customClass="ForwardArrow" customModule="CustomViews">

1
Святе дерьмо, це мене зводить з розуму вже цілий день. Яка неприємна помилка.
GoldenJoe

5

Як мій приклад, я використовував CheckboxButton через pod, і графіка прапорця ніколи не відображається в раскадровці, тоді як у мене виникають ті самі проблеми, описані в запитанні тут:

попередження: IB Designables: Використання класу UIView для об'єкта зі спеціальним класом, оскільки клас CheckboxButton не існує

і

попередження: IB Designables: ігнорування визначеного користувачем атрибута виконання для шляху ключа "checkColor" у екземплярі "UIView". Здійснити виняток при спробі встановити його значення: [setValue: forUndefinedKey:]: цей клас не відповідає коду значення ключа для ключа checkColor.

Шлях вирішення моєї проблеми полягав у тому, щоб надати модулю ім’я CheckboxButton, як показано нижче:

Примітка: вам слід замінити CheckboxButton на будь-яку назву модуля, який ви використовуєте.


4

Я особисто вирішив цю проблему, скориставшись кнопкою "-", щоб видалити вміст зі свого інспектора посвідчення особи. Коли ви видаляєте власні класи, змінюєте вміст у IB, а потім додаєте новий власний клас, призначувані елементи в інспекторі ідентифікаторів не видаляються, і це спричинило у мене цю помилку. Просто видаліть все і відновіть.введіть тут опис зображення


Я зробив саме те, що ти сказав, і це вирішило мою проблему. Всі попередні рішення, викладені тут, не встигли. Дуже дякую. ; o)
XLE_22

@ XLE_22 інколи це вирішує ніхто, хто не дивиться на це, так? :)
HannahCarney

У мене виникла проблема, коли я перейменував властивість IBInspectable на декілька моїх xib. Після цього у мене з’явилося безліч попереджень, які повідомляли мені, що XCode не може знайти перейменовану власність. Видалення майна у інспектора посвідчення особи вирішило мою проблему.
WBuck

1

Я знаю, що на це відповідають, але ось ще один досвід.

У мене були деякі проблеми, не пов'язані з цією проблемою, але в процесі я видалив @IBInspectable з vars у своєму класі та видалив атрибути з інспектора ідентифікації (alt-apple-3).

Після виправлення (кодової) проблеми з компонентом, я багато разів оновлював все, але досі не мав атрибутів в інспекторі посвідчень.

Зрештою, я помітив, що вони повернулися, але лише в інспекторі атрибутів (alt-apple-4) . Як тільки я додав там цінності, вони знову з’явилися в інспекторі особи


1

Відповідь Дейва Томаса вище дав мені (зворотне) рішення, коли не з інших (Виведені дані, Редактор> Оновити), але для ясності на випадок, якщо люди не впевнені, де редагувати XML ... ви не розумієте т потрібно!

  1. У файлі розкадровки виберіть складний вигляд
  2. На правій бічній панелі виберіть вкладку Identity Inspector (3-й варіант зліва).
  3. У вас буде свій власний клас, який вже повинен бути встановлений, і Module. Для мене це було порожнім, і я отримував ті самі помилки, що і OP. Я встановив назву Moduleсвого проекту та BAM - він почав працювати після відновлення!

0

Я щойно розглянув цю проблему. Я спробував усі речі, перераховані тут і деінде, без удачі. Це раскадровка, яка спрацювала назавжди, і вона раптом перестала працювати з проблемою "Ігнорування визначеного користувачем атрибута виконання ...".

З якоїсь причини, вилучивши цей код з одного з моїх IBDesignable, це виправлено:

-(void)viewDidLoad {
    self.clipsToBounds = YES;
}

Видалення цього призвело до того, що всі попередження зникли, навіть в інших об’єктах, які можна призначити IBD. Я не уявляю, чому цей один крок це виправив, але, можливо, це також допоможе комусь іншому.


3
ви пропустили тут заклик до вечері
RolandasR

0

У мене була та сама проблема, і мені довелося змінити cornerRadius і BorderWidth на String, а потім передати їх на CGFloat, це було єдиним рішенням для мене, щоб я міг змінити значення і побачити зміни в конструкторі інтерфейсів.

@IBInspectable var borderColor: UIColor? {
    didSet {
        layer.borderColor = borderColor!.CGColor
    }
}

@IBInspectable var borderWidth: String? {
    didSet {
        layer.borderWidth = CGFloat(Int(borderWidth!) ?? 0)
    }
}

@IBInspectable var cornerRadius: String? {
    didSet {
        layer.cornerRadius = CGFloat(Int(cornerRadius!) ?? 0)
        layer.masksToBounds = layer.cornerRadius > 0
    }
}

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