UINavigationBar с категорией, действовать как кнопка тоже

В моем приложении для iphone я пытаюсь заставить мою uinavigationbar действовать как кнопку, я имею в виду, что делать что-то, когда я прикасаюсь к ней. Не кнопка возврата ни к одному элементу навигации, а сама панель. Вот как я "категоризировал" это:

@implementation UINavigationBar (UINavigationBarCategory)
- (void)drawRect:(CGRect)rect {
    UIColor *color = [UIColor blackColor];
    UIImage *img    = [UIImage imageNamed: @"bar.png"];
    [img drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    self.tintColor = color;
}

Действие будет переходить к некоторому обзору ..
Есть идеи?
Заранее спасибо!


person Nicolas    schedule 17.08.2010    source источник
comment
Я использовал категорию, потому что думал, что это единственный способ добиться такой настройки UINavigationBar.   -  person Nicolas    schedule 18.08.2010


Ответы (2)


Не используйте категории для переопределения методов из класса. Из языка программирования Objective-C руководство:

Хотя язык в настоящее время позволяет вам использовать категорию для переопределения методов, наследуемых классом, или даже методов, объявленных в интерфейсе класса, вам настоятельно не рекомендуется использовать эту функцию. Категория не заменяет подкласс. Есть несколько существенных недостатков:

  • Когда категория переопределяет унаследованный метод, метод в категории может, как обычно, вызывать унаследованную реализацию через сообщение для super. Однако, если категория переопределяет метод, который уже существовал в классе категории, нет возможности вызвать исходную реализацию.

  • Категория не может надежно переопределить методы, объявленные в другой категории того же класса. Эта проблема имеет особое значение, поскольку многие классы Какао реализованы с использованием категорий. Определяемый платформой метод, который вы пытаетесь переопределить, мог сам быть реализован в категории, поэтому не определено, какая реализация имеет приоритет.

  • Само наличие некоторых методов может вызвать изменение поведения во всех фреймворках. Например, если вы добавляете реализацию windowWillClose: в NSObject, это приведет к тому, что все делегаты окна будут реагировать на этот метод и могут изменить поведение всех экземпляров экземпляров NSWindow. Это может вызвать загадочные изменения в поведении и привести к сбоям.

Вместо этого вам может быть лучше всего просто создать прозрачное представление или кнопку, которая реагирует на прикосновение, и разместить ее над областью панели для вашего UINavigationController. Это прозрачное представление могло затем улавливать события касания, предназначенные для всей области бара.

Тем не менее, я бы очень серьезно подумал о том, чего вы пытаетесь достичь с помощью этого. Отмена стандартного взаимодействия пользователя с помощью встроенного элемента интерфейса может привести к разочарованию пользователя и даже к потенциальному отклонению со стороны Apple.

person Brad Larson    schedule 17.08.2010
comment
В принципе, вы правы, но для этого конкретного устройства я бы сказал, что категория хороша. Николас, похоже, не слишком опытен с Cocoa Touch, судя по drawRect: -method, есть немного других функций, которые можно испортить, а создание подкласса UINavigationBar довольно сложно, по моему опыту. - person eliego; 18.08.2010
comment
Ок, отлично! Я посмотрю, что я могу сделать с обоими ответами. PS. У меня нет опыта работы с Cocoa Touch ... Я стараюсь изо всех сил. - person Nicolas; 18.08.2010
comment
@eliego - в этом случае создание подклассов не требуется. Он просто может поместить прозрачный вид или кнопку на часть экрана с панелью навигации и обработать прикосновения. Пропаганда практики, о которой Apple явно предупреждает, - неправильный способ заставить нового разработчика работать на платформе. Вы хотите, чтобы у людей вырабатывались хорошие привычки, когда они впервые изучают окружающую среду. - person Brad Larson; 18.08.2010
comment
Хорошо, я сделал с этим! Спасибо, Брэд и Элиего! Наконец, я просто добавил imageView в качестве subview в uinavbar, добавил оттенок и удалил категорию. работает действительно хорошо, но не сенсорное управление. Я не буду использовать его, потому что вместо этого я не могу добавить uibutton в качестве subview, я появляется, но он ничего не делает, даже не выделяет. еще раз спасибо! - person Nicolas; 19.08.2010

Попробуйте переопределить эти три функции в своей категории: http://developer.apple.com/iphone/library/documentation/uikit/reference/UIResponder_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006783-CH4-SW13

person eliego    schedule 17.08.2010
comment
Спасибо, я попробую и вернись! - person Nicolas; 17.08.2010
comment
Итак, я должен использовать эти 3 функции: - (void) touchesBegan: (NSSet *) touch withEvent: (UIEvent *) event - (void) touchesMoved: (NSSet *) touch withEvent: (UIEvent *) event - (void ) touchesEnded: (NSSet *) касается события withEvent: (UIEvent *). Я новичок в том, как работает переопределение, поэтому, пожалуйста, будьте вежливы ... Мне нужно писать свой код внутри или мне нужно что-то делать с параметрами? Спасибо за быстрый ответ! изменить: хорошо, я сдаюсь, не знаю, как добавить тег кода в комментарий здесь .. - person Nicolas; 17.08.2010
comment
Начните с простой реализации их в своей категории (точно так же, как вы это сделали с drawRect :) и выведите некоторый NSLog, чтобы понять, как они вызываются. В конце концов, вам, вероятно, нужно будет только добавить код к методу touchesEnded: и выполнить там любое действие, которое вы хотите. - person eliego; 17.08.2010
comment
Ок, отлично! Спасибо. кстати, я оставлю вопрос открытым, чтобы я мог вернуться к вам, если у меня возникнут проблемы. - person Nicolas; 17.08.2010
comment
Категория - неподходящее место для размещения пользовательского кода обработки касания. См. Мой ответ для получения дополнительной информации. - person Brad Larson; 18.08.2010