Я пытаюсь сделать что-то немного сложнее, но то, что должно быть возможно. Так что это вызов для всех вас, экспертов (на этом форуме много ребят :)).
Я создаю «компонент» Анкеты, который я хочу загрузить в NavigationContoller
(мой QuestionManagerViewController
). «Компонент» является «пустым» UIViewController
, который может загружать различные представления в зависимости от вопроса, на который необходимо ответить.
Я делаю это так:
- Создайте объект Question1View как
UIView
подкласс, определяя некоторыеIBOutlets
. - Создайте (используя Интерфейсный Разработчик)
Question1View.xib
(ЗДЕСЬ, ГДЕ МОЯ ПРОБЛЕМА, ВОЗМОЖНО ). Я установил какUIViewController
и,UIView
чтобы быть класса Question1View. - Я связываю торговые точки с компонентом представления (используя IB).
Я переопределить
initWithNib
мой,QuestionManagerViewController
чтобы выглядеть так:- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if (self = [super initWithNibName:@"Question1View" bundle:nibBundleOrNil]) { // Custom initialization } return self; }
Когда я запускаю код, я получаю эту ошибку:
2009-05-14 15: 05: 37.152 iMobiDines [17148: 20b] *** Завершение работы приложения из-за необработанного исключения '
NSInternalInconsistencyException
', причина: '-[UIViewController _loadViewFromNibNamed:bundle:]
загрузил перо "Question1View", но выход представления не был установлен ".
Я уверен, что есть способ загрузить представление, используя nib-файл, без необходимости создавать класс viewController.
источник
Спасибо вам всем. Я нашел способ сделать то, что хотел.
UIView
сIBOutlet
S вам нужно.UIViewController
(нет пользовательского подкласса, кроме «реального»). Представление «Владелец файла» подключено к основному представлению, а его класс объявлен как класс из шага 1).IBOutlet
s.DynamicViewController
Может запустить свою логику , чтобы решить , что смотреть / XIB к нагрузке. Как только он принял решение, вloadView
методе поместите что-то вроде этого:Это оно!
Основной комплект
loadNibNamed
позаботится об инициализации представления и создании соединений.Теперь ViewController может отображать то или иное представление в зависимости от данных в памяти, и «родительскому» экрану не нужно беспокоиться об этой логике.
источник
Я не уверен, о чем идет речь в некоторых ответах, но мне нужно разместить этот ответ здесь, когда я буду искать в Google в следующий раз. Ключевые слова: «Как загрузить UIView из пера» или «Как загрузить UIView из NSBundle».
Вот код почти на 100% прямо из книги Apress Beginning для iPhone 3 (стр. 247, «Использование новой ячейки табличного представления»):
Это предполагает, что у вас есть
UIView
подкласс с именемBlah
nib,Blah
который содержитUIView
класс, для которого установлен классBlah
.Категория: NSObject + LoadFromNib
Быстрое расширение
И пример в использовании:
источник
isKindOf
вы защищены от изменений структуры Bundle.assert
, будет лучшим решением. Таким образом, вы будете только скрывать проблему.for
цикле. Это дополняет это.Для всех тех , которые нужно управлять более чем один экземпляр пользовательского вида, то есть на выходе коллекции , я слился и индивидуальные ответы @Gonso, @AVeryDev и @Olie следующим образом:
Создайте кастом
MyView : UIView
и установите его в качестве « Custom Class » корняUIView
в желаемой XIB ;Создайте все розетки, в которых вы нуждаетесь
MyView
(сделайте это сейчас, потому что после пункта 3 IB предложит вам соединять розетки с,UIViewController
а не с пользовательским представлением, как мы хотим);Установите
UIViewController
как « Владелец файла » пользовательского представления XIB ;В
UIViewController
добавлении новогоUIViews
для каждого экземпляраMyView
вы хотите, и подключить их кUIViewController
созданию Outlet Коллекции : эти взгляды будут выступать в качестве мнения «обертки» для экземпляров пользовательского вида;Наконец, в
viewDidLoad
вашемUIViewController
добавить следующие строки:источник
Я бы использовал UINib для создания экземпляра пользовательского UIView для повторного использования
В этом случае необходимы файлы MyCustomView.xib , MyCustomViewClass.h и MyCustomViewClass.m Note, которые
[UINib instantiateWithOwner]
возвращают массив, поэтому вам следует использовать элемент, отражающий UIView, который вы хотите использовать повторно. В данном случае это первый элемент.источник
Вы не должны устанавливать класс вашего контроллера представления как подкласс
UIView
в Интерфейсном Разработчике. Это определенно, по крайней мере, часть вашей проблемы. Оставьте это какUIViewController
некоторый подкласс этого класса или какой-либо другой пользовательский класс, который у вас есть.Что касается загрузки только представления из xib, я исходил из того, что вам нужно было установить какой-либо контроллер представления (даже если он не расширяется
UIViewController
, что может быть слишком тяжело для ваших нужд), установленный в качестве владельца файла в интерфейсе Builder, если вы хотите использовать его для определения вашего интерфейса. Я провёл небольшое исследование, чтобы подтвердить это. Это потому, что в противном случае не было бы никакого доступа к любому из элементов интерфейса вUIView
, и не было бы способа, чтобы ваши собственные методы в коде запускались событиями.Если вы используете в
UIViewController
качестве вашего файла владельца для вашего мнения, вы можете просто использовать ,initWithNibName:bundle:
чтобы загрузить его и получить вид контроллера объекта обратно. В IB убедитесь, что вы установилиview
выход в вид с помощью интерфейса в XIB. Если вы используете какой - либо другой тип объекта в вашем файле владельца, вы должны будете использоватьNSBundle
«sloadNibNamed:owner:options:
метод , чтобы загрузить перо, передавая экземпляр файла владельца к методу. Все его свойства будут установлены в соответствии с точками, которые вы определили в IB.источник
Вы также можете использовать initWithNibName UIViewController вместо loadNibNamed. Это проще, я нахожу.
Теперь вам просто нужно создать MySubView.xib и MySubView.h / m. В MySubView.xib установите для класса «Владелец файла» значение UIViewController, а для класса представления - «MySubView».
Вы можете разместить и размер
subview
использования родительского файла XIB.источник
Это отличный вопрос (+1) и ответы были почти полезны;) Извините, ребята, но у меня было огромное количество времени, пробирающегося через это, хотя и Gonso, и AVeryDev дали хорошие подсказки. Надеюсь, этот ответ поможет другим.
MyVC
это контроллер вида, содержащий все эти вещи.MySubview
это вид, который мы хотим загрузить из XIBMySubView
который имеет правильный размер и форму и расположен там, где вы хотите.В MyVC.h есть
В MyVC.m,
@synthesize mySubView;
и не забудьте выпустить его вdealloc
.UIView *view
(может быть излишним, но сработало для меня.) Синтезировать и выпустить его в .mMySubview
и свяжите свойство представления с вашим представлением.IBOutlet
желаниюВернуться в MyVC.m, есть
Немного сложным для меня было то, что подсказки в других ответах загружали мое представление из xib, но НЕ заменяли представление в MyVC (да!) - мне пришлось поменять его самостоятельно.
Кроме того, чтобы получить доступ к
mySubview
методам,view
свойство в файле .xib должно быть установлено вMySubview
. В противном случае он возвращается как старыйUIView
.Если есть способ загрузить
mySubview
напрямую из его собственной xib, то это круто, но это привело меня туда, где я должен был быть.источник
Это то, что должно быть проще. В итоге я расширил
UIViewController
и добавилloadNib:inPlaceholder:
селектор. Теперь я могу сказатьВот код для этой категории (она выполняет ту же процедуру, что и Гонсо):
источник
В быстром
На самом деле я решил эту проблему, загрузив представление в viewDidLoad в моем CustonViewController, где я хотел использовать это представление так:
Не загружайте представление в
loadView()
методе! Метод loadView служит для загрузки представления для вашего пользовательского ViewController.источник
Я тоже хотел сделать что-то подобное, вот что я нашел: (SDK 3.1.3)
У меня есть контроллер представления A (принадлежащий контроллеру Nav), который загружает VC B нажатием кнопки:
В AViewController.m
Теперь у VC B есть интерфейс от Bnib, но когда нажата кнопка, я хочу перейти в «режим редактирования», в котором отдельный интерфейс от другого пера, но я не хочу новый VC для режима редактирования, Я хочу, чтобы новый кончик был связан с моим существующим B VC.
Итак, в BViewController.m (в методе нажатия кнопки)
Затем нажмите другую кнопку (чтобы выйти из режима редактирования):
и я вернулся к своему первоначальному Бнибу.
Это прекрасно работает, но учтите, что мой EditMode.nib содержит только 1 объект верхнего уровня, объект UIView. Неважно, установлен ли Владелец файла в этом кончике как BViewController или NSObject по умолчанию, НО убедитесь, что для параметра Просмотр выхода в Владельце файла НЕ установлено ничего. Если это так, то я получаю аварийное завершение exc_bad_access, и xcode переходит к загрузке 6677 кадров стека, показывая неоднократно вызываемый внутренний метод UIView ... так что это выглядит как бесконечный цикл. (Однако в моем оригинальном Bnib установлен Out Outlet)
Надеюсь это поможет.
источник
Я сделал категорию, которая мне нравится:
UIView+NibInitializer.h
UIView+NibInitializer.m
Затем позвоните так:
Используйте имя пера, если ваше перо названо не так, как имя вашего класса.
Чтобы переопределить его в ваших подклассах для дополнительного поведения, это может выглядеть так:
источник
Для пользователя Swift с настраиваемой опцией:
UIView
подкласс и файлы xib , которые мы назовем по имени нашего собственного класса: в нашем случае MemeView. Внутри класса Meme View не забудьте определить его как дизайн с помощью@IBDesignable
атрибутом до объявления классаПомните, чтобы установить владельца файла в xib с помощью нашего пользовательского
UIView
подкласса на панели Indetity Inspector.Теперь в xib-файле мы можем построить наш интерфейс, создать ограничения, создать торговые точки, действия и т. Д.
Нам нужно реализовать несколько методов для нашего пользовательского класса, чтобы открыть XIB после инициализации
class XibbedView: UIView {
}
В нашем пользовательском классе мы также можем определить некоторые безупречные свойства, чтобы иметь полный контроль над ними из конструктора интерфейса
@IBDesignable class MemeView: XibbedView {
}
Несколько примеров:
Если нам нужно добавить больше информации, когда представление отображается внутри раскадровки или другой xib, для этого мы можем реализовать
prepareForInterfaceBuilder()
этот метод, который будет выполняться только при открытии файла в конструкторе интерфейса. Если вы выполнили все, что я написал, но ничего не работает, это способ отладки представления sigle путем добавления точек останова в его реализации. Вот иерархия просмотров.Надеюсь, что это помогает полный образец можно скачать здесь
источник
let nib = loadNib(nibName)
это экземпляр XibbedView, если вы вызываете `` `addSubview (nib)` ``, то вы добавляете один экземпляр XibbedView в другой экземпляр XibbedView?Я нашел эту запись в блоге Аарона Хиллегаса (автор, инструктор, ниндзя Какао) очень поучительной. Даже если вы не примете его модифицированный подход к загрузке файлов NIB через назначенный инициализатор, вы, вероятно, по крайней мере получите лучшее понимание происходящего процесса. Я использую этот метод в последнее время с большим успехом!
источник
Предыдущий ответ не учитывает изменения в структуре NIB (XIB), которые произошли между 2.0 и 2.1 из iPhone SDK. Пользовательское содержимое теперь начинается с индекса 0 вместо 1.
Вы можете использовать макрос 2.1, который действителен для всех версий 2.1 и выше (это два подчеркивания перед IPHONE:
Мы используем технику, аналогичную этой, для большинства наших приложений.
гулянка
источник
У меня была причина сделать то же самое (программная загрузка представления из файла XIB), но мне нужно было сделать это полностью из контекста подкласса подкласса
UIView
(то есть без какого-либо участия контроллера представления). Для этого я создал этот служебный метод:Затем я вызываю его из
initWithFrame
метода моего подкласса так:Опубликовано для общего интереса; если кто-то видит какие-либо проблемы без этого, пожалуйста, дайте мне знать.
источник
Вот способ сделать это в Swift (в настоящее время пишу Swift 2.0 в XCode 7 beta 5).
Из вашего
UIView
подкласса, который вы задали как «Пользовательский класс» в Интерфейсном Разработчике, создайте метод, подобный этому (мой подкласс называется RecordingFooterView):Тогда вы можете просто назвать это так:
let recordingFooterView = RecordingFooterView.loadFromNib()
источник
Ни один из ответов не объясняет, как создать автономный XIB, который является корнем этого вопроса. Нет
Xcode 4
опции «Создать новый файл XIB».Сделать это
Это может показаться простым, но это может сэкономить вам несколько минут, ища это, так как слово «XIB» нигде не появляется.
источник
@AVeryDev
6) Чтобы прикрепить загруженный вид к виду вашего контроллера:
Предположительно, необходимо убрать его из поля зрения, чтобы избежать утечек памяти.
Для пояснения: контроллер представления имеет несколько IBOutlets, некоторые из которых связаны с элементами в исходном файле пера (как обычно), а некоторые связаны с элементами в загруженном пиру. Оба пера имеют один и тот же класс владельца. Загруженный вид накладывается на исходный.
Подсказка: установите непрозрачность основного вида в загруженном наконечнике на ноль, тогда он не будет скрывать элементы от исходного наконечника.
источник
Потратив много часов, я придумал следующее решение. Выполните следующие шаги для создания пользовательских
UIView
.1) Создать класс myCustomView, унаследованный от UIView .
2) Создайте .xib с именем myCustomView .
3) Измените класс UIView внутри вашего .xib файла, назначьте там класс myCustomView .
4) Создание IBOutlets
5) Загрузите .xib в myCustomView * customView . Используйте следующий пример кода.
источник
Кратчайшая версия:
источник
У меня есть соглашение о присвоении имен Xibs с представлениями в них так же, как представление. То же самое, что можно было бы сделать для контроллера представления. Тогда мне не нужно записывать имена классов в коде. Я загружаю UIView из файла пера с тем же именем.
Пример для класса под названием MyView.
В своем коде создайте новый MyView следующим образом:
MyView * myView = [MyView nib_viewFromNibWithOwner: owner];
Вот категория для этого:
Затем я бы связывал кнопки с действиями используемого мной контроллера и устанавливал метки на ярлыках, используя выходы в моем подклассе пользовательского представления.
источник
Чтобы программно загрузить представление из nib / xib в Swift 4:
источник
В итоге я добавил категорию в UIView для этого:
объяснение здесь: viewcontroller меньше загружает представление в ios & mac
источник