#iphone #cocoa-touch #ios4 #delegates
#iPhone #cocoa-touch #ios4 #делегаты
Вопрос:
У меня есть корневой контроллер представления, который загружает созданный мной пользовательский подкласс UIView и добавляет его в качестве подвида.
Внутри этого пользовательского подкласса UIView я кодирую / генерирую UIButton в методе awakeFromNib.
Есть ли простой способ получить доступ к владельцу файла без создания делегата, если метод действия UIButton находится внутри корневого контроллера представления?
Например
[myButton addTarget:[self.file_owner ?] action:@selector(methodInFileOwner:) ....
С помощью Interface Builder по-прежнему легко назначить UIView моему пользовательскому подклассу UIView и просто перетащить ссылку селектора UIButton на владельца файла. Вуаля!
Но как это делается с помощью кода? Должен ли я создавать делегат и использовать
[myButton addTarget:[self.delegate] ...
?
Комментарии:
1. Я только что заметил ошибку в ответе, который я вам дал. Пожалуйста, взгляните на это еще раз, на случай, если я неправильно вас направил. Извините, если я это сделал.
Ответ №1:
Владелец файла — это концепция конструктора интерфейса. В основном, это не существует на стороне программирования, потому что это не нужно. В Interface Builder владельцем файла является класс, который создает экземпляр файла nib. Часто это просто ссылается на класс файла nib, с которым вы в данный момент работаете. Поскольку вы работаете с контроллером представления, владельцем файла является ваш подкласс view controller, и это позволяет вам устанавливать соединения с переменными экземпляра и методами этого класса.
На стороне программирования, в этом случае эквивалентом владельца файла было бы просто self
. И вы получаете доступ к переменной экземпляра, используя свойства, как self.instanceVariable
.
К вашему вопросу. Если вы хотите, чтобы метод selector находился в контроллере представления, это имеет смысл. Но затем контроллер представления может создать кнопку, установить ее цель / действие и добавить ее в качестве вложенного представления в пользовательское представление. Вы могли бы сделать это в viewDidLoad, который вызывается после загрузки файла nib и является стандартным местом, где вы могли бы вносить любые программные дополнения в контроллер представления. Итак, вы могли бы сделать это следующим образом:
- (void)viewDidLoad {
self.myButton = [[[UIButton alloc] initWithFrame:CGRectMake(x, y, width, height)] autorelease];
self.myButton.buttonType = ...;
[myButton addTarget:self action:@selector(actionMethod)...];
self.myCustomView = [[[MyCustomViewClass alloc] initWithFrame:...] autorelease];
[self.myCustomView addSubview:self.myButton.view];
[super viewDidLoad];
}
Приведенный выше код — это просто пример. Вы можете инициализировать свои объекты различными способами. В этом случае кнопка теперь была бы переменной экземпляра контроллера представления. Но вы могли бы так же легко оставить его в пользовательском представлении и просто ссылаться на него как: self.myCustomView.myButton
Я надеюсь, что это полезно.
Исправление: приведенный выше код должен быть в viewWillAppear
, а не viewDidLoad
. При viewDidLoad
вызове геометрия (то есть границы представления) еще не установлена. Итак, чтобы установить фрейм любого объекта, это должно быть сделано в viewWillAppear
.
Ответ №2:
Целью должен быть объект корневого класса контроллера представления. В вашем подклассе UIView вам понадобится ссылка на ваш класс корневого контроллера представления.
Ответ №3:
Если вложенный виджет скрыт от контроллера, то это, по сути, означает, что пользовательское представление должно управлять всеми аспектами этого вложенного виджета. Вот некоторые параметры (и, вероятно, не полный их список):
- Вы могли бы заставить пользовательский subview обрабатывать события UIControl и распространять их на кнопку. Ваше пользовательское подвидение будет реализовывать методы UIControl и, по сути, передавать их кнопке.
- Вы также могли бы использовать делегат, подобный тому, который вы упомянули.
- Или вы могли бы реструктурировать его так, чтобы иерархия виджетов была плоской, но их отображение было вложенным.
Если вы планируете создавать пользовательский компонент, который вы повторно используете в нескольких местах, то первый и второй варианты, вероятно, лучше, поскольку они более гибкие. Если это не так, третий вариант, вероятно, является лучшим, поскольку существует фактическое взаимодействие между кнопкой и контроллером.
В делегаты и источники данных раздела какао основы руководстве приводится пример того, что код выглядит следующим образом для создания делегатов.