Как получить доступ к переменным ViewController в подклассе?

#iphone #objective-c #cocoa-touch #subclassing

#iPhone #objective-c #cocoa-touch #создание подклассов

Вопрос:

Я предполагаю, что это базово, но я не могу разобраться в этом.

Раньше у меня был только один ViewController, в котором были определены все мои переменные, например, UITextView с именем myTextView. У меня также были методы в этом ViewController для обработки событий, которые относятся к myTextView, такие как - ()hideKeyboard { // do something with myTextView или - (void)keyboardWillShow:(NSNotification *)notification { // do something with myTextView .

Поскольку моя программа становилась все больше и больше, я подумал об использовании подклассов, особенно для других представлений. Итак, я запустил подкласс, например. MySubClass.h и MySubClass.m, в котором у меня был другой UITextView (для аргументации myOtherTextView). Чтобы включить MySubClass, я #imported внедрил его в свой ViewController и добавил @class mySubClass; , а затем мог создавать экземпляры этого класса, чтобы использовать его в своем приложении.

Пока все хорошо. Как вы можете себе представить, все хорошие методы, которые я определил в своем ViewController для того, что должно произойти при редактировании UITextView (например, скрытие клавиатуры и т.д.), Не Сработали для UITextView в MySubClass.

Затем мне было предложено создать другой класс, в котором у меня были все события клавиатуры, и присвоить ему подкласс моего ViewController и mySubView:

 @interface ViewController : MyKeyboardEventsViewController
  

Теперь проблема, которую я вижу, заключается в том, что я не смогу получить доступ ко всем представлениям, textviews, textfields и т.д., Которые я создал в своем ViewController (например, myTextView, о котором я упоминал ранее).

Как я могу добиться того, чтобы все переменные, которые я определил в моем ViewController, также были доступны для MyKeyboardEventsViewController? Или есть другой способ справиться с этим?

В принципе, я не понимаю, как MyKeyboardEventsViewController сможет получать доступ к переменным в моем ViewController, которые ему понадобятся (например, рассматриваемый UITextView или всплывающий accessoryView и т.д. и т.п.).

Любые предложения будут очень приветствоваться.

Ответ №1:

Пример:

Класс A содержит текстовое поле ivar UITextField

Класс B является подклассом класса A и, следовательно, он уже содержит текстовое поле ivar

Примечание: это не наоборот. Класс A не «видит» то, что когда-либо создавалось в классе B.

Когда бы вы ни создавали подкласс класса, вы предоставляете своему новому классу те же методы ivar end, что и для этого подкласса.

Я надеюсь, это то, о чем вы просили.

Редактировать

Итак, для вашего примера я бы сделал следующее:

  • Создайте класс «MyUIKeybordEventResponder»
  • Реализуйте все методы ответчика, такие как - (BOOL)textFieldShouldReturn:(UITextField *)textField
  • Создайте подкласс вашего ViewController из «MyUIKeybordEventResponder»

Обратитевнимание, что метод TextFields souldreturn имеет параметр UITextField, поэтому он знает, какое текстовое поле было нажато. Таким образом, в некотором смысле он получает ваше текстовое поле из подкласса.

Комментарии:

1. Итак, в моем случае UITextField необходимо было бы определить в MyKeyboardEventsViewController. Затем мой ViewController классифицирует MyKeyboardEventsViewController и, таким образом, имеет доступ к UITextField. В таком случае, не могу ли я просто добавить MySubClass к моему ViewController? Или это плохая практика программирования? Насколько я понимаю сейчас, похоже, что в моем ViewController останется не так много кода… это стандартно? Прямо сейчас у меня есть практически все в моем ViewController… Я думаю, это нехорошо.

2. Что касается вашего редактирования: знает ли hideKeyboard, какое текстовое поле / представление было отправлено? например - (IBAction)hideKeyboard { textView.scrollEnabled = NO; [textView resignFirstResponder];

3. В вашем случае ваше UITextField должно быть реализовано в ViewController, а затем реализовать все методы UITextFieldDelegate в MyKeyboardEventsViewController. Сделайте ваш ViewController подклассом MyKeyboardEventsViewController. B / c MyKeyboardEventsViewController является делегатом UITextFieldDelegate, он получит объект (UITextField), когда ему потребуется ответить на него, поэтому вам не нужно беспокоиться о передаче его вручную самостоятельно.

4. @n.evermind относительно размера класса. Если вы создаете один и тот же код более одного раза в проекте, вам следует поместить его в отдельный класс. Надеюсь, это отвечает на ваш вопрос о размере класса.

5. @Cyprian: но у меня все еще возникает проблема, если мне нужно получить доступ к другим строкам, которые я определил в своем ViewController. Например, к любому массиву, в котором я сохранил дату в ViewController и теперь мне нужно получить доступ в mySubView. Смогу ли я сделать это с помощью simpleton?

Ответ №2:

Если я правильно понимаю, у вас есть UIViewController с MyKeyboardEventsViewController в качестве переменной экземпляра, и вы хотите обмениваться данными между ними? Если это так, одним из вариантов было бы создать протокол.

 @protocol MyKeyboardDelegate 

- (void)closeAccessoryView;

@end
  

(Примечание — используйте любые методы в протоколе, который вам нужен, это просто пример)

Затем в ваш MyKeyboardEventsViewController вы включаете файл протокола и создаете ivar

 id <MyKeyboardDelegate> delegate;
  

Также сделайте это свойством и синтезируйте его.

Любой класс, который собирается создать keyboardviewcontroller, должен следить за тем, чтобы он соответствовал протоколу.

 @interface MyViewController : UIViewController <MyKeyboardDelegate>
  ...
@end
  

При создании MyKeyboardEventsViewController задайте делегат.

 MyKeyboardEventsViewController *eventsVC = [[MyKeyboardEventsViewController alloc] init]; 
  

[eventsVC setDelegate:self];

Теперь просто реализуйте метод делегирования и выполняйте любые необходимые действия.