Я знаю, что этот вопрос задавался раньше, но ответы противоречат друг другу, и я запутался, поэтому, пожалуйста, не раздражайте меня.
Я хочу иметь многократно используемый UIView
подкласс во всем моем приложении. Я хочу описать интерфейс с помощью файла пера.
Теперь предположим, что это представление индикатора загрузки с индикатором активности в нем. Я хотел бы на каком-то событии создать экземпляр этого представления и анимировать его в представлении контроллера представления. Я мог бы без проблем описать интерфейс представления программно, создавая элементы программно и задавая их фрейм внутри метода инициализации и т. Д.
Как я могу сделать это с помощью пера? Сохранение размера, указанного в построителе интерфейса, без необходимости устанавливать фрейм.
Мне удалось это сделать вот так, но я уверен, что это неправильно (это просто представление с пикером в нем):
- (id)initWithDataSource:(NSDictionary *)dataSource {
self = [super init];
if (self){
self = [[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@", [self class]] owner:self options:nil] objectAtIndex:0];
self.pickerViewData = dataSource;
[self configurePickerView];
}
return self;
}
Но я перезаписываю себя, и когда я его создаю:
FSASelectView *selectView = [[FSASelectView alloc] initWithDataSource:selectViewDictionary];
selectView.delegate = self;
selectView.frame = CGRectMake(0, self.view.bottom + 50, [FSASelectView width], [FSASelectView height]);
Мне нужно вручную установить рамку, а не забирать ее из IB.
РЕДАКТИРОВАТЬ: я хочу создать это настраиваемое представление в контроллере представления и иметь доступ для управления элементами представления. Мне не нужен новый контроллер представления.
Спасибо
РЕДАКТИРОВАТЬ: Я не знаю, является ли это лучшей практикой, я уверен, что это не так, но я сделал это так:
FSASelectView *selectView = [[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@",[FSASelectView class]] owner:self options:nil] objectAtIndex:0];
selectView.delegate = self;
[selectView configurePickerViewWithData:ds];
selectView.frame = CGRectMake(0, self.view.bottom + 50, selectView.width, selectView.height);
selectView.alpha = 0.9;
[self.view addSubview:selectView];
[UIView animateWithDuration: 0.25 delay: 0 options:UIViewAnimationOptionAllowUserInteraction |UIViewAnimationOptionCurveEaseInOut animations:^{
selectView.frame = CGRectMake(0, self.view.bottom - selectView.height, selectView.width, selectView.height);
selectView.alpha = 1;
} completion:^(BOOL finished) {
}];
Правильная практика все еще нужна
Должно ли это быть сделано с помощью контроллера представления и инициализации с именем пера? Должен ли я установить перо в каком-либо методе инициализации UIView в коде? Или то, что я сделал, нормально?
initWithDataSource
? В любом случае это будет работать, даже если вы укажете для владельца значение «Nil».Ответы:
Я использую это для инициализации имеющихся у меня многоразовых пользовательских представлений.
Обратите внимание, что вы можете использовать "firstObject" в конце, это немного чище. firstObject - удобный метод для NSArray и NSMutableArray.
Вот типичный пример загрузки xib для использования в качестве заголовка таблицы. В вашем файле YourClass.m
Обычно в
TopArea.xib
файле вы нажимаете File Owner и устанавливаете владельцем файла YourClass . Тогда на самом деле в YourClass.h у вас будут свойства IBOutlet. ВTopArea.xib
, вы можете перетащить элементы управления к этим выходам.Не забывайте, что
TopArea.xib
вам, возможно, придется щелкнуть по самому просмотру и перетащить его в какой-либо выход, чтобы вы могли контролировать его, если это необходимо. (Очень полезный совет: когда вы делаете это для строк ячеек таблицы, вы обязательно должны это сделать - вы должны подключить само представление к соответствующему свойству в вашем коде.)источник
Если вы хотите, чтобы вы
CustomView
и он неxib
зависели от негоFile's Owner
, выполните следующие действия.File's Owner
поле пустым.xib
вашем файлеCustomView
и установите егоCustom Class
какCustomView
(имя вашего пользовательского класса представления)IBOutlet
в.h
файл вашего пользовательского представления..xib
файле вашего пользовательского представления нажмите на просмотр и войдитеConnection Inspector
. Здесь вы найдете все свои IBOutlets, которые вы определяете в.h
файлев
.m
файле вашегоCustomView
класса переопределитеinit
метод следующим образомТеперь, когда вы хотите загрузить свой
CustomView
, используйте следующую строку кода[[CustomView alloc] init];
источник
-init
. Вместо этого он вызоветinitWithFrame:
и-awakeFromNib
. Если вы напишете тот же код для загрузки вашего представления, что и в-init
методе, вы войдете в бесконечный цикл.Выполните следующие шаги
UIView
.MyView.xib
.UIViewController
fromNSObject
в xib. См. Изображение нижеПодключите представление владельца файла к вашему представлению. См. Изображение ниже
Измените класс вашего представления на
MyView
. То же, что и 3.Вот код для загрузки представления:
Надеюсь, поможет.
Уточнение :
UIViewController
используется для загрузки вашего xib и представления, которое наUIViewController
самом деле есть,MyView
которое вы назначили в MyView xib ..Demo Я сделал демо - грейфер здесь
источник
Отвечая на мой собственный вопрос о 2 или около того годах здесь, но ...
Он использует расширение протокола, поэтому вы можете сделать это без дополнительного кода для всех классов.
источник
В Swift:
Например, имя вашего настраиваемого класса
InfoView
Сначала вы создаете файлы
InfoView.xib
иInfoView.swift
вот так:Затем установите
File's Owner
наUIViewController
это нравится:Переименуйте
View
вInfoView
:Щелкните правой кнопкой мыши
File's Owner
и подключите своеview
поле кInfoView
:Убедитесь, что имя класса
InfoView
:И после этого вы можете без проблем добавить действие к кнопке в своем пользовательском классе:
И использование этого настраиваемого класса в вашем
MainViewController
:источник
Ну, вы можете либо инициализировать xib с помощью контроллера представления, либо использовать viewController.view. или сделайте так, как вы это сделали. Создание только
UIView
подкласса в качестве контроллераUIView
- плохая идея.Если у вас нет выходов из вашего пользовательского представления, вы можете напрямую использовать
UIViewController
класс для его инициализации.Обновление: в вашем случае:
В противном случае вам придется сделать заказ
UIViewController
(сделать его владельцем файла, чтобы розетки были правильно подключены).Где бы вы ни хотели добавить представление, которое вы можете использовать.
Однако передача другого контроллера представления (уже используемого для другого представления) в качестве владельца при загрузке xib не является хорошей идеей, поскольку свойство представления контроллера будет изменено, и когда вы захотите получить доступ к исходному представлению, вы не будете иметь ссылку на это.
РЕДАКТИРОВАТЬ: вы столкнетесь с этой проблемой, если вы настроили свой новый xib с владельцем файла в качестве того же основного
UIViewController
класса и связали свойство представления с новым представлением xib.т.е.
Приведенный ниже код вызовет путаницу позже, если вы напишете его внутри view, загрузившего
YourMainViewController
. Это потому, чтоself.view
с этого момента будет ссылаться на ваш customviewисточник