Как отправить суперпредставление в Objective C - PullRequest
9 голосов
/ 11 февраля 2009

Я новичок в Objective C и какао. Я просто не понимаю, как отправить супервизию UIView. Я не могу заставить это работать. Вот что я попробовал до сих пор:

В моем MainView у меня есть метод с именем resetDrawType:

- (void) resetDrawType {
   self.drawType = foo;
}

Также в MainView я создаю подпредставление и добавляю его в MainView:

mySubView *mySubView = [[mySubView alloc] initWithFrame:CGRectMake(foo, foo, foo, foo)];
[self addSubview:mySubView];
[mySubView release];

Затем, когда подпредставление завершило рисование, я хочу отправить сообщение resetDrawType своему суперпредставлению, которое является MainView.

Я пробовал это

 [(MainView*)[self superview] resetDrawType];

и

 [(MainView*)self.superview resetDrawType];

... что не сработало. Я узнал об неофициальных протоколах, поэтому добавил этот код в MainView.h

 @interface NSObject ( resetters )
    - (void) resetDrawType;
 @end

Но все равно ничего. Затем я узнал об этой вещи селектора и попробовал это в подпредставлении:

 if ([self.superview respondsToSelector:@selector(resetDrawType:)])
    [self.superview performSelector:@selector(resetDrawType) withObject:nil];

Это тоже не сработало. Что я делаю неправильно? Спасибо за вашу помощь.

Ответы [ 2 ]

11 голосов
/ 11 февраля 2009

У вас не должно быть подпредставлений, рассказывающих своему суперпредставлению многое о чем-либо. Вы должны сделать superview делегатом вашего класса представления.

// MainView
MyView *myView = [[MyView alloc] initWithFrame:CGRectMake(...) delegate:self];

Затем сохраните делегат в переменной экземпляра, объявленной id delegate. Когда вы закончите рисовать:

// MyView
- (void)doDrawing {
  drawStuff();
  [delegate didFinishDrawingView:(MyView *)self]
}

Теперь вернемся к вашему MainView, реализуйте этот метод

- (void)didFinishDrawingView:(MyView *)aView;

делать то, что вы хотите.

Смысл всего этого в том, что маленьким классам на границе вашего приложения (например, небольшому подпредставлению) не нужно знать, как работают большие классы над ними. Эта настройка позволяет представлению взаимодействовать по цепочке, но с сообщением, которое передает свой собственный статус вместо сообщения, которое инструктирует другой объект делать что-то конкретное. Таким образом, Какао структурирован так, что классы могут быть легко использованы повторно, а их события могут быть перенаправлены так, как вам нужно.

Ваше суперпредставление должно знать, что делать, когда заканчивается его подпредставление. Подвид должен просто дать людям знать, что он закончен.


Объявите переменную экземпляра в заголовке вашего подпредставления следующим образом:

id delegate;

Напишите initiailizer для вашего подпредставления, который выглядит следующим образом:

- (id)initWithFrame:(CGRect)frame delegate:(id)aDelegate {
  [super initWithFrame:frame];
  delegate = aDelegate;
  return self;
}

Теперь у вас есть инициализатор, который примет делегат, сохранит этот делегат и позволит вам затем вызывать методы для него.

6 голосов
/ 11 февраля 2009

Ну, во-первых, в Objective-C нет необходимости приводить к определенному классу, чтобы отправить ему сообщение. Например, вы можете просто сделать;

[self.superview resetDrawType];

Предоставление родительского представления имеет следующую функцию;

- (void) resetDrawType {

}

Тогда это должно работать правильно. Нет необходимости использовать неформальные протоколы.

Также ваше тестирование селектора неверно, поскольку оно не соответствует определению функции "resetDrawType". @selector (resetDrawType :) проверяет функцию с именем resetDrawType, которая принимает параметр, а ваш - нет.

Это то, как вы должны проверить вышеуказанную функцию;

if ([self.superview respondsToSelector:@selector(resetDrawType)])
    [self.superview performSelector:@selector(resetDrawType)];

(Вместо executeSelector вы также можете отправить сообщение напрямую).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...