Как получить доступ к IBOutlets, объявленным в суперклассе?

В настоящее время я рефакторинг пары контроллеров представления, которые используют несколько методов IBOutlets и IBAction. Я переместил объявления выходов и метод IBAction в суперкласс, вырезав их из подклассов.

Теперь, когда я открываю Interface Builder, я обнаруживаю, что не вижу выходов или действий, объявленных в суперклассе. Соединения все еще существуют, так как я подключил их до рефакторинга, но они неактивны. (Важно отметить, что соединения также РАБОТАЮТ, так как мое действие срабатывает при нажатии кнопки, а мои выходы модифицируются должным образом.)

Вопрос в том, как я могу заставить конструктор интерфейсов распознавать выходы из суперкласса? Возможно ли это, и если нет, то что вы всем рекомендуете?

(Просто для удовольствия, вот мой заголовочный файл суперкласса:)

@interface TFMainViewController : UIViewController {
    UIImageView *logoImage, *thinkfunImage;
    UIButton *buyFullButton;        
}

@property (nonatomic, retain) IBOutlet UIImageView *logoImage, *thinkfunImage;
@property (nonatomic, retain) IBOutlet UIButton *buyFullButton;

-(IBAction) buyFullVersion;

@end

РЕДАКТИРОВАТЬ: если кому-то интересно, я использую Xcode и IB 3.2.5 с iOS 4.2 SDK.


person Sam Ritchie    schedule 13.12.2010    source источник
comment
вы когда-нибудь выясняли, возможно это или нет? Я надеялся сделать то же самое, но IB, похоже, не распознает свойство, если я не переобъявил его в подклассе?   -  person Rog    schedule 26.07.2011
comment
есть новости по этому пункту? Я столкнулся с той же проблемой здесь - на этот раз с суперклассом Installer Plugin (InstallerPane), который не является моим, поэтому я не могу его изменить --- только в документации говорится, что я должен подключить свой .xib к некоторым свойствам суперкласса!! ! Как?   -  person Motti Shneor    schedule 04.04.2016


Ответы (10)


Я не знал, что можно было подключиться к суперклассам в конструкторе интерфейсов примерно час назад. Поскольку это был единственный вопрос, который я смог найти относительно того, как это сделать, я добавлю свой ответ, хотя этот вопрос старый. Мой ответ касается Xcode 4, а не Xcode 3.

Насколько я могу судить, вы не можете подключиться к розеткам в суперклассе с помощью помощника редактора, но вы можете сделать это, нажав «Владелец файла» в IB. Это должно показать все выходы в Utilities-> Connections Inspector. Затем вы можете нажать Ctrl+щелчок по розетке в инспекторе (щелкнуть знак «+») и перетащить ее на свое представление в IB.

person arsenius    schedule 06.11.2012
comment
Или просто перейдите с Cmd-Click к суперклассу в помощнике редактора, затем вы можете перетащить из класса в IB или наоборот, чтобы подключить розетки или создать новые. - person Kendall Helmstetter Gelner; 13.04.2016

Решение проблемы с IBOutlet.. заключается в изменении типа класса на Базовый класс в инспекторе идентификации

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

подключиться с помощью Control + перетаскивание и

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

изменить его обратно на дочерний класс

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

Это работает для меня

Кстати: я использовал Xcode 6

person Sosily    schedule 13.10.2014
comment
У меня точно такая же проблема. попробовал это с NSCollectionViewItem, поэтому я могу подключить выход textField, но все равно не работает. - person pvinis; 01.06.2015

IB должен иметь возможность видеть выходы из суперклассов, я делал это несколько раз без проблем. Вы уверены, что правильно импортируете суперкласс (используя #import вместо @class)? IB нужен какой-то способ вернуться к суперклассу.

person Kendall Helmstetter Gelner    schedule 13.12.2010
comment
Кендалл, взглянув на другой ответ, вы что-то дублируете или все объявление находится в суперклассе? Я использую #import и имею доступ к свойствам внутри подклассов, поэтому я знаю, что импорт заголовков работает. - person Sam Ritchie; 13.12.2010
comment
Я только что создал тестовый проект для этого - и он не работает. Начиная с Xcode 7.x - IB показывает только IBOutlets фактического класса, объявленного для объекта, а не его суперклассов. - person Motti Shneor; 05.04.2016
comment
Я просто играл с этим в Xcode 7.3 в Swift, и он все еще работает нормально. Я смог объявить IBOutlet в суперклассе и либо перетащить его в IB, либо перетащить из IB в розетку, чтобы подключить его. Редактор помощника не показывает суперкласс в разделе «Автоматически», но вы можете перемещаться по нему, а IB показывает выход как исходящий из подкласса (что технически точно). @SamRitchie - ничего не дублируйте, просто сделайте выход в суперклассе, а не в подклассе. - person Kendall Helmstetter Gelner; 13.04.2016

Переключение между суперклассом и подклассом в инспекторе удостоверений позволяет вам подключать свои розетки к классам. Единственная проблема, которую я обнаружил, - это когда вы пытаетесь сделать это с помощью UITableViewCell и его подкласса. Я хотел переназначить экземпляры textLabel и detailTextLabel по умолчанию для меток, которые я создаю в Interface Builder. Обходной путь состоит в том, чтобы создать замещающие метки, а затем переопределить геттеры, чтобы вместо этого они указывали на них.

person Lee Probert    schedule 28.02.2013

Я почти уверен, что IB смотрит только на фактический класс, который вы используете для поиска выходов, а не на суперклассы. Я думаю, что самым простым решением было бы оставить объявления переменных экземпляра в суперклассе, но продублировать строки @property в каждом подклассе.

person Denis Hennessy    schedule 13.12.2010
comment
Фактически, Interface Builder отображает список свойств суперклассов, но они должны быть объявлены в заголовочном файле (только суперкласса), и этот заголовок должен быть импортирован подклассом (как сказал Кендалл). - person Brian; 13.12.2010

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

person Michael57    schedule 01.02.2013

Самый простой способ: создать интерфейс и файлы реализации для вашего подкласса(ов)!
Прекрасный пример: Juggleware потрясающий Подкласс ShadowButton UIButton.

Убедитесь, что в вашем проекте созданы файлы .h и .m. ПРИМЕЧАНИЕ. Нет необходимости #import заголовочных файлов, так как это просто экземпляр класса UIButton.

В Конструкторе интерфейсов:

  1. Выберите элемент, который вы хотите соединить.
  2. Перейдите в раздел Утилиты -> Инспектор идентификационных данных.
  3. Измените класс на свой подкласс (или суперкласс). ПРИМЕЧАНИЕ. Возможно, вам придется ввести имя вашего подкласса и нажать ENTER.

Готово!

Даже если вы объявили базовый класс (UIButton) как IBOutlet в своем заголовочном файле, например...

// YourViewController.h

@interface YourViewController : UIViewController {

IBOutlet UIButton *mybutton;
}

... класс, который вы установили в Interface Builder (ShadowButton), перезапишет его, поскольку он находится на уровне представления.

Самое приятное в этом подходе то, что в вашем коде нет проблем с зависимостями.

person Mike Rapadas    schedule 25.02.2013

В проекте, над которым я сейчас работаю, у нас есть BaseViewController с UIScrollView как IBOutlet, и мы обрабатываем события появления/исчезновения клавиатуры и соответствующим образом перемещаем содержимое. Сначала я не мог подключиться к этому IBOutlet, чем решил проблему так, что похоже на ответ Sosily:

  • У BaseViewController есть IBOutlet по имени contentScrollView. Вижу 5 подключенных ранее розеток, которые UIScrollViews на других UIViewControllers, созданных людьми, ранее работавшими над проектом

  • Я попытался подключить свой UIScrollView как contentScrollView. Хотя мой UIViewController является подклассом BaseViewController, я не могу его подключить.

  • Пробовал подключить уже подключенный UIScrollViews как contentScrollView. Хотя все UIViewControllers являются подклассами BaseViewController, я также не могу связать их снова. Итак, я начал искать подвох.

  • Я создал такой же contentScrollView IBOutlet на своем UIViewController, подключил scrollView к своей розетке contentScrollView и удалил только что созданный.

  • Теперь scrollView подключен как contentScrollView к владельцу файла, но единственный contentScrollView принадлежит BaseViewController. Протестировано и подтверждено, что события клавиатуры обрабатываются правильно.

person Yunus Nedim Mehel    schedule 18.09.2015

Я столкнулся с аналогичной проблемой с суперклассом, но это было связано с ошибкой в ​​Xcode (8.2), когда Interface Builder не показывает выходы в инспекторе соединений, если эти выходы были объявлены с аннотацией типа _Nullable для совместимости со Swift.

Использование nullable внутри скобок @property помогает обойти проблему.

Эта ошибка Xcode, по-видимому, влияет на выходы в любом классе (т.е. не только в суперклассах).

person user2067021    schedule 12.01.2017

У меня была та же проблема, и оказалось, что это было из-за того, что в суперклассе у меня были IBOutlets, объявленные как «_Nullable». Пример:

@property (nonatomic, strong)   IBOutlet UITableView *_Nullable mySuperTableView;

Когда я удалил _Nullable, внезапно в IB снова появились IBOutlets, и все снова стало хорошо. (Я установил для них значение _Nullable только потому, что Xcode жаловался, что «в указателе отсутствует спецификатор типа nullability»... (не знаю почему).)

person BobCowe    schedule 14.01.2017