Программно создавая UIButton внутри пользовательского подкласса UIView, как получить доступ к владельцу файла для добавления целевого метода? делегаты?

#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 и, по сути, передавать их кнопке.
  • Вы также могли бы использовать делегат, подобный тому, который вы упомянули.
  • Или вы могли бы реструктурировать его так, чтобы иерархия виджетов была плоской, но их отображение было вложенным.

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

В делегаты и источники данных раздела какао основы руководстве приводится пример того, что код выглядит следующим образом для создания делегатов.