#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];
Теперь просто реализуйте метод делегирования и выполняйте любые необходимые действия.