IB_DESIGNABLE, IBInspectable - построитель интерфейса не обновляет

У меня есть следующий код:

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.

enter image description here

Это добавляет строку "Designables". Он застрял в "Обновлении", и всплывающая подсказка говорит "Ожидание цели для сборки". Он никогда не изменяется от этого статуса.

Когда я перехожу к проверке атрибутов, я могу установить эти свойства IBInspectable:

enter image description here

И как только они установлены, они также отображаются в "Пользовательских атрибутах времени выполнения":

enter image description here

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

Кроме того, когда я устанавливаю свойства IBInspectable, я получаю предупреждение для каждого из них:

IBDesignables. Игнорирование пользовательского атрибута времени выполнения для ключевого пути "borderColor" в экземпляре "UIView" ... этот класс не подходит для кодирования ключевого значения для ключевого borderColor.

Снимок экрана сгенерированных предупреждений:

enter image description here


Я знаком с проблемами, совместимыми с ключевыми значениями, и вообще знаю, как их решить... но я не понимаю, как решить эту проблему здесь. По мнению инспектора идентификации вида, представление представляет собой "CustomView" (не обычный "UIView" , который не имеет этих свойств). И если представление не было "CustomView", тогда эти назначаемые свойства не отображались бы в Инспекторе атрибутов, правильно? Но когда Interface Builder пытается применить эти атрибуты к представлению, он возвращается к мысли, что класс представления является "UIView" и не может применять атрибуты.

Любая помощь? Пожалуйста, дайте мне знать, если я оставил некоторые важные детали, но для чего это стоит, Я точно следил за этим учебником (кроме ObjC vs Swift). Также стоит отметить, что я следовал этому руководству точно на другой машине, и он работал как шарм (я собирался сделать это сообщение вчера вечером, но компьютер, на котором я был, тогда не имел этой проблемы).


Основываясь на комментариях, было высказано предположение, что, возможно, файл .m не включен и может вызвать проблему. Я, конечно же, думал, что ушел бы из моего пути, чтобы этот сценарий был таким, но я все равно проверил.

enter image description here

Когда я впервые начал делать это, я был в понимании того, что классы IB_DESIGNABLE должны были быть частью другой структуры UIKit. Итак, из этого первого снимка экрана вы можете увидеть, что я создал структуру "CustomViews", которая имеет один класс, CustomView. Вы также увидите здесь, что я также создал OtherView, который идентичен CustomView, за исключением того, что он не находится в отдельной структуре. Однако одинаковая проблема сохраняется на раскадровке между обоими классами.

Здесь у нас есть скриншот, указывающий, что CustomView.m включен в структуру CustomViews:

enter image description here

Между тем, следующий снимок экрана показывает несколько вещей:

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

enter image description here


Я попробовал и повторил это несколько раз. Он работает каждый раз на моем компьютере дома - я не могу воспроизвести проблему, описанную в этом вопросе дома. На работе он никогда не работает. Проблема, описанная в этом вопросе, происходит каждый раз.

Оба компьютера Mac Minis приобрели новый в этом году (а не новые модели, модель конца 2012 года). На обоих компьютерах работает OS X Yosemite 10.10. Оба компьютера работают под управлением Xcode версии 6.1. Дома, сборка (6A1052d). Сегодня утром я могу подтвердить, что оба компьютера работают с идентичными сборками Xcode.

Другие предложили мне, что это может быть плохая оперативная память. Это кажется мне гораздо более привлекательным. Я перезапустил проект несколько раз, перезапустил компьютер несколько раз. Мне кажется, если на компьютере около 6 месяцев было плохое ОЗУ, что я буду видеть другие проблемы, и эта проблема будет менее последовательной. Но эта точная проблема сохраняется, несмотря на многочисленные попытки перезапуска всего проекта с нуля и полной перезагрузки на компьютере.

Следует отметить, что если я действительно компилирую и запускаю этот проект, пользовательский вид с свойствами IBInspectable действительно отображается, поскольку я ожидаю, что раскадровка отобразит его. Я полагаю, что это было бы возможно даже с директивами IB_DESIGNABLE и IBInspectable, поскольку они создаются как атрибуты времени выполнения, определенные пользователем.

Ответ 1

На основе предложения chrisco отладить выбранное представление (которое я уже сделал, но пошел попробовать еще раз для хорошей меры), я заметил пару других параметров в нижней части меню редактора.

  • Автоматическое обновление просмотров
  • Обновить все представления

Я щелкнул "Refresh All Views", и после того, как Xcode немного подумал, вдруг раскадровка отобразила мое представление как ожидалось (правильно применяя мои свойства IBInspectable).

enter image description here

Затем я снова прошел весь процесс, чтобы подтвердить, что это решение.

Я создал новый класс ThirdView. Этот класс идентичен другим. Я изменил свой класс представления на ThirdView и на этот раз немного изменился:

enter image description here

Нажав "Show" для предупреждений:

enter image description here

Новый на этот раз:

Использование класса UIView для объекта с пользовательским классом, потому что класс ThirdView не существует.

Это не более полезно, чем то, что уже существует. Кроме того, теперь три других предупреждения удвоились до 6 странно.

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

Тем не менее, до сих пор все, что я делал, было тем, что я никогда не путал дома. Дома это просто сработало. Поэтому я включил "Автоматическое обновление представлений" и создал "FourthView" для тестирования - еще раз, идентичный первым трем.

После изменения класса представления на "FourthView" ярлык designables сказал "Обновление" на короткое мгновение, а затем, наконец, сказал "До настоящего времени":

enter image description here

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


TL; DR, если у вас возникла проблема, описанная в вопросе, убедитесь, что включен режим "Автоматическое обновление просмотров" (или вручную "Обновить все представления", когда вам нужно обновление в IB):

enter image description here

Ответ 2

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

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

В области навигатора перейдите к Навигатору отчетов в рабочей области/проекте XCode.

В меню редактора XCode нажмите (как указано в nhgrif), опцию "Обновить все представления". Это заставит IB запустить компиляцию для целого ряда вещей, которые, я уверен, не ожидали бы.

В Навигаторе отчетов нажмите "По группам", чтобы фильтровать контент и посмотреть раздел "Интерфейс". Вы увидите, что для загрузки пользовательской структуры IBDesignable views она скомпилирует множество вещей. Если какая-либо из этих целей НЕ компилируется, например, (возможно, устаревшие) unit test цели (даже если они полностью не связаны с кодом, который загружает эти представления или раскадровку), тогда IB будет терпеть неудачу при загрузке вашей DLL.

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

Большинство изменений/исправлений кода, которые я сделал для того, чтобы IB правильно загрузил и отобразил мои таможни, где они не связаны или даже не связаны с этими классами, и никогда не загрузите раскадровку во время выполнения этих модульных тестов, Тем не менее, у IB была зависимость от всего компилирования рабочей области для его работы.

Ответ 3

Просто подсказка для всех, у кого есть эта проблема: не забудьте указать тип переменной.

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

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

Ответ 4

Если кто-то еще сталкивается с ошибкой, класс IB Designables не существует по той же причине, что и я. Главный ответ не был моей проблемой... но вот небольшая проблема...

Существует свойство, скрытое в исходном коде storyboard, называемом customModule.

Например, у меня был класс под названием ForwardArrow внутри отдельной структуры, который я случайно добавил к моей основной цели.

Таким образом, XML для некоторых представлений customclass= "ForwardArrow" customModule = "MainTargetNameWasHere"

Когда я удалил их из главной цели в сборке, панель рассказов не обновила MainTargetNameWasHere до CustomViews, которая является основой, в которой она была расположена, и начала выдавать ошибку поиска класса.

Итак, TL;DR; Убедитесь, что если ваш IBDesignable находится в другой структуре, для атрибута customModule xml в вашей доске объявлений установлено правильное значение. И если его вообще нет, добавьте его.

Пример из моего источника:

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

Ответ 5

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

Оказалось, в моем случае это связано с кешем Xcode.

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

Очистить DerivedData, и предупреждение не прошло.

Ответ 6

В качестве примера я использовал CheckboxButton через pod, и графика флажка никогда не появляется в раскадровке, пока я получаю те же проблемы, описанные в этом вопросе:

warning: IB Designables: использование класса UIView для объекта с пользовательским классом, поскольку класс CheckboxButton не существует

и

warning: IB Designables: Игнорирование пользовательского атрибута времени выполнения для ключевого пути "checkColor" на примере "UIView". Удалите исключение при попытке установить его значение: [setValue: forUndefinedKey:]: этот класс не является ключевым значением, совместимым с кодом для ключа checkColor.

Решив проблему, я поставил модуль с именем CheckboxButton, как показано ниже:

Примечание: вы должны заменить CheckboxButton на то, что имя модуля вы используете.

Ответ 7

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

Ответ 8

Я знаю, что это ответ, но вот еще один опыт.

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

После исправления (кода) проблемы с компонентом я обновил все тонну раз, но не добавил атрибутов в инспекторе идентификации.

В конце концов я заметил, что они вернулись, , но только в инспекторе атрибутов (alt-apple-4). Как только я добавил к ним значения, они снова появились в инспекторе идентификации

Ответ 9

Ответ Дэйва Томаса выше дал мне (обратное) решение, если не другие (Derived Data, Editor > Refresh), но для ясности в люди не уверены, где редактировать XML... вам не нужно!

  • В вашем файле раскадровки выберите трудный вид
  • На правой боковой панели выберите вкладку Identity Inspector (третий вариант слева).
  • У вас будет свой собственный класс, который уже должен быть установлен, и Module. Для меня это было пусто, и я получал те же ошибки, что и OP. Я установил Module в мое название проекта и BAM - он начал работать после восстановления!

Ответ 10

Я только что прошел через звонок по этой проблеме. Я пробовал все вещи, перечисленные здесь и в других местах, без везения. Это раскадровка, которая отлично работала навсегда, и она внезапно перестала работать с проблемой "Игнорировать пользовательский атрибут времени выполнения...".

По какой-то причине удаление этого кода из одного из моих IBDesignable исправлено:

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

Удаление этого способа привело к тому, что все предупреждения исчезли, даже в других объектах IBDesignable. Я понятия не имею, почему этот один шаг исправил его, но, возможно, это тоже поможет кому-то другому.

Ответ 11

У меня была такая же проблема, и мне пришлось изменить 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
    }
}