Как определить, есть ли у UIView делегат, соответствующий протоколу - PullRequest
1 голос
/ 08 февраля 2010

Я написал собственный класс, который существенно зависит от перетаскивания / позиционирования касанием вне его собственных границ вида. Существует связанный протокол, определенный различными соответствующими методами. Примером чего-то, что могло бы использовать этот протокол, было бы представление, которое позволяет вещам быть добавленными в него из моего пользовательского класса.

Проблема, с которой я столкнулся, заключается в том, чтобы выяснить, когда касание заканчивается (объект «уронен»), независимо от того, есть ли объект, который заботится ниже этой позиции. (Для «забот» читайте «соответствует протоколу»!).

Если это представление, которое соответствует моему протоколу, это легко, я могу найти его с помощью - (CALayer *)hitTest:(CGPoint)thePoint или что-то в этом духе и запросить с помощью conformsToProtocol:@protocol(xx).

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

Итак, по сути, как мне пройти вверх по иерархии представлений с самого нижнего UIView, спрашивая, соответствует ли каждое представление моему протоколу; и если это не так, есть ли у него делегат, и это соответствует ..?

Или есть куда более простой способ, о котором я не думал?

Большое спасибо ..


решаемые

Благодаря moshy , у меня есть решение:

- (UIView *)viewThatConformsToProtocol:(Protocol *)protocol AtPointInWindow:(CGPoint)point {
   UIView *lowestUIView = [[(AppDelegate).navigationController view] hitTest:point withEvent:nil];
   UIResponder *respondsToProtocol = lowestUIView;
   while ((respondsToProtocol != nil) && (![respondsToProtocol conformsToProtocol:protocol])) {
      respondsToProtocol = [respondsToProtocol nextResponder]; // else try the next responder up the chain
   };
   return (UIView *)respondsToProtocol;
}

Это либо возвращает представление, либо nil, если ничего не соответствует.

Еще раз спасибо ..

1 Ответ

0 голосов
/ 08 февраля 2010

Что ж, если у вас самый низкий вид, вы можете пройтись по цепочке респондента, используя - (UIResponder *)nextResponder.

Из документов:

Класс UIResponder не хранитустановить следующий респондент автоматически, вместо этого возвращая ноль по умолчанию.Подклассы должны переопределить этот метод для установки следующего респондента.UIView реализует этот метод, возвращая объект UIViewController, который управляет им (если он есть) или его суперпредставлением (если это не так);UIViewController реализует метод, возвращая суперпредставление своего представления;UIWindow возвращает объект приложения, а UIApplication возвращает nil.

...