У меня есть собственный вид внутри UIBarButtonItem
, установленный путем вызова -initWithCustomView
. Элемент моей кнопки на панели отображается нормально, но когда я нажимаю на него, он не вызывает действие с моим целевым объектом.
Вот мой код:
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"someImage.png"]];
UIBarButtonItem *bbItem = [[UIBarButtonItem alloc] initWithCustomView:imageView];
self.navigationItem.leftBarButtonItem = bbItem;
[imageView release];
[bbItem setTarget:self];
[bbItem setAction:@selector(deselectAll)];
iphone
ios
objective-c
cocoa-touch
Яков Релкин
источник
источник
UIBarButtonItem
наследуется отUIBarItem
иNSObject
поэтому ничего не знает о прикосновениях. Было бы неплохо, если бы в документации упоминалось, что свойстваaction
иtarget
применяются только в том случае, если настраиваемое представление является UIButton.У меня была такая же проблема, но я не хотел использовать
UIButton
для моего пользовательского представленияUIBarButtonItem
(согласно ответу drawonward).В качестве альтернативы вы можете добавить
UIGestureRecognizer
к настраиваемому представлению, прежде чем использовать его для инициализацииUIBarButtonItem
; похоже, это работает в моем проекте.Вот как я бы изменил ваш исходный код:
UIImageView *SOCImageView = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"cancel_wide.png"]]; UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(deselectAll:)]; [SOCImageView addGestureRecognizer:tapGesture]; SOItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:SOCImageView] autorelease]; [tapGesture release]; [SOCImageView release];
источник
Вот как я заставляю это работать:
UIButton* infoButton = [UIButton buttonWithType: UIButtonTypeInfoLight]; [infoButton addTarget:self action:@selector(displayAboutUs) forControlEvents:UIControlEventTouchDown]; UIBarButtonItem* itemAboutUs =[[UIBarButtonItem alloc]initWithCustomView:infoButton]; …
источник
Вот как я реализовал UIButton внутри UIBarButtonItem:
UIButton *logoButton = [UIButton buttonWithType:UIButtonTypeCustom]; [logoButton setImage: [UIImage imageNamed:@"icon.png"] forState:UIControlStateNormal]; logoButton.frame = CGRectMake(0, 0, 30, 30); [logoButton addTarget:self action:@selector(showAbout:) forControlEvents:UIControlEventTouchUpInside]; UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:logoButton]; self.navigationItem.rightBarButtonItem = barItem; [barItem release];
источник
У меня была аналогичная проблема. И я сначала пошел по пути, предложенному @drawnonward, но затем столкнулся с проблемой, когда попытался представить своим действием всплывающий контроллер на iPad: использование встроенного UIButton в качестве настраиваемого представления означает, что UIButton является отправителем события, и Метод presentPopoverFromBarButtonItem: контроллера всплывающего окна дает сбой при попытке отправить ему сообщения, которые подходят только для фактических элементов UIBarButtonItem.
Решение, которое я в конце концов нашел, заключалось в том, чтобы украсть изображение, которое я хотел использовать (значок «информация») из одноразового UIButton, и сконструировать мой UIBarButtonItem следующим образом:
// Make the info button use the standard icon and hook it up to work UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; UIBarButtonItem *barButton = [[[UIBarButtonItem alloc] initWithImage:infoButton.currentImage style:UIBarButtonItemStyleBordered target:self action:@selector(showInfo:)] autorelease];
Использование этого инициализатора дает кнопку-полосу, цель и селектор которой действительно работают. Это также проще, чем оборачивать изображение в пользовательском представлении, но это просто глазурь.
источник
Если вы не хотите соглашаться с UIImage и иметь настраиваемое представление в своем barbuttonitem, установите распознаватель касаний для свойства customview вашего barbuttonitem
let tap = UITapGestureRecognizer(target: self, action: #selector(goProButtonPressed)) deviceStatusBarButtonItem.customView?.addGestureRecognizer(tap)
источник
Джейкоб, все выглядит хорошо, но, возможно, вы не предоставили правильный селектор.
Можете ли вы убедиться, что ваше действие действительно объявлено
- (void) deselectAll;
и нет
- (void) deselectAll:(id)sender;
Если это последнее, вам нужно будет установить действие
@selector(deselectAll:)
. (обратите внимание на точку с запятой, чтобы соответствовать объявлению метода)Кроме того, может быть void
IBAction
, но это не имеет отношения к вашей проблеме.источник
deselectAll
не звонят? Установив точку останова отладчика, или вы просто не видите ожидаемых результатов?Swift 3. У меня была аналогичная проблема, когда у меня был настраиваемый вид внутри элемента кнопки панели. Чтобы кран работал, я назначил представлению жест и установил действие. Представление должно было быть отдушиной, чтобы его присвоить. При этом он работал с пользовательским представлением.
Установка жеста как переменной класса
@IBOutlet weak var incidentView: UIView! let incidentTap = UITapGestureRecognizer()
В viewDidLoad
incidentTap.addTarget(self, action: #selector(self.changeIncidentBarItem)) incidentView.addGestureRecognizer(incidentTap)
источник
Swift 3 : Ниже представлена моя полная реализация настройки кнопок и обработки событий.
override func viewDidLoad() { super.viewDidLoad() let button = UIButton.init(type: .custom) button.setTitle("Tester", for: .normal) button.setTitleColor(.darkGray, for: .normal) button.layer.borderWidth = 1 button.layer.cornerRadius = 5 button.layer.borderColor = UIColor.darkGray.cgColor button.addTarget(self, action: #selector(self.handleButton), for: .touchUpInside) self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if let button = self.navigationItem.rightBarButtonItem?.customView { button.frame = CGRect(x:0, y:0, width:80, height:34) } } func handleButton( sender : UIButton ) { // It would be nice is isEnabled worked... sender.alpha = sender.alpha == 1.0 ? 0.5 : 1.0 }
Надеюсь это поможет
источник
Ваше пользовательское представление использует события касания или передает их родительскому представлению?
источник
UIImageView
. Итак, это не съедает никаких событий, нет.Чтобы упростить работу с этим, я создал категорию на UIBarButtonItem, которая выглядит так:
@implementation UIBarButtonItem (CustomButtonView) - (void)setButtonImage:(UIImage *)image { UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setBackgroundImage:image forState:UIControlStateNormal]; [button sizeToFit]; [button addTarget:self.target action:self.action forControlEvents:UIControlEventTouchUpInside]; self.customView = button; } - (UIImage *)buttonImage { return [(UIButton *)self.customView imageForState:UIControlStateNormal]; } @end
В вашем клиентском коде просто используйте:
myBarButtonItem.buttonImage = [UIImage imagedNamed:@"image_name"];
Сделав это таким образом, вы по-прежнему можете подключать свои цели и действия в IB (добавление в IB как можно большего количества конфигурации пользовательского интерфейса - это хорошо).
источник