UIBarButtonItem: целевое действие не работает?
У меня есть пользовательский вид внутри 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)];
Ответы
Ответ 1
Я не думаю, что цель и действие UIBarButtonItem применимы к пользовательским представлениям. Попробуйте использовать UIButton вместо UIImageView и примените цель и действие к кнопке.
Пример кода в Swift:
let button = UIButton(type: .Custom)
if let image = UIImage(named:"icon-menu.png") {
button.setImage(image, forState: .Normal)
}
button.frame = CGRectMake(0.0, 0.0, 30.0, 30.0)
button.addTarget(self, action: #selector(MyClass.myMethod), forControlEvents: .TouchUpInside)
let barButton = UIBarButtonItem(customView: button)
navigationItem.leftBarButtonItem = barButton
Ответ 2
Вот как я делаю это:
UIButton* infoButton = [UIButton buttonWithType: UIButtonTypeInfoLight];
[infoButton addTarget:self action:@selector(displayAboutUs) forControlEvents:UIControlEventTouchDown];
UIBarButtonItem* itemAboutUs =[[UIBarButtonItem alloc]initWithCustomView:infoButton];
…
Ответ 3
У меня была такая же проблема, но я не хотел использовать UIButton
вместо пользовательского представления для моего UIBarButtonItem
(для обратного ответа).
В качестве альтернативы вы можете добавить 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];
Ответ 4
Вот как я реализовал 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];
Ответ 5
У меня была аналогичная проблема. И я изначально следовал пути, предложенному @drawnonward, но затем столкнулся с трудностями, когда я попытался заставить свои действия представлять собой контроллер popover на iPad. Использование встроенного UIButton в качестве пользовательского представления означает, что UIButton является отправителем события и popover-контроллеры presentPopoverFromBarButtonItem: метод вылетает, когда он пытается отправить его сообщениям, которые подходят только для реальных UIBarButtonItems.
Решение, которое я в конечном итоге нашел, состояло в том, чтобы украсть изображение, которое я хотел использовать (значок "информация" ) из выпадающего 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];
Используя этот инициализатор, вы получаете кнопку панели, цель и селектор которой действительно работают. Это также проще, чем обертывание изображения в пользовательском представлении, но это просто обледенение.
Ответ 6
Джейкоб, все выглядит хорошо, однако вы, возможно, не указали правильный селектор.
Вы можете проверить, действительно ли ваше действие объявлено
- (void) deselectAll;
а не
- (void) deselectAll:(id)sender;
Если это последнее, вам нужно установить действие на @selector(deselectAll:)
. (обратите внимание на запятую в соответствии с объявлением метода)
Кроме того, void может быть IBAction
, но это не относится к этой проблеме.
Ответ 7
Является ли ваш пользовательский просмотр приемом событий касания или передачей их в родительский вид?
Ответ 8
Чтобы упростить работу, я создал категорию в 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 (нажатие на UI-конфигурацию в IB, как вы можете, это хорошая вещь).
Ответ 9
Swift 3. У меня была аналогичная проблема, когда у меня был пользовательский вид внутри элемента кнопки панели. Чтобы заставить кран работать, я назначил жест взгляду и установил действие. Представление должно быть выходом для его назначения. Выполняя это, он работал с пользовательским представлением.
Установка жестов в качестве переменной класса
@IBOutlet weak var incidentView: UIView!
let incidentTap = UITapGestureRecognizer()
In viewDidLoad
incidentTap.addTarget(self, action: #selector(self.changeIncidentBarItem))
incidentView.addGestureRecognizer(incidentTap)
Ответ 10
Если вы не хотите соглашаться с UIImage и иметь пользовательский вид в своем barbuttonitem, установите распознаватель жестов прикосновения к свойству customview barbuttonitem
let tap = UITapGestureRecognizer(target: self, action: #selector(goProButtonPressed))
deviceStatusBarButtonItem.customView?.addGestureRecognizer(tap)
Ответ 11
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
}
Надеюсь, что это поможет