UINavigationBar UIBarButtonПоказывает гораздо большую область нажатия, чем требуется - PullRequest
35 голосов
/ 16 февраля 2010

надеюсь, что кто-то может мне помочь - я искал сеть для ответа и не могу найти один -

UIBarButtonItems, добавленные в UINavigationBar, имеют гораздо большую область щелчка, чем требуется- например, откройте любой проект, в котором у вас есть панель навигации, при нажатии кнопок в любом месте между концом кнопки и заголовком панели навигации - кнопка щелкает, когда вы явно не нажимали кнопку -

также попробуйте это - нажмите под навигационной панелью, под кнопкой, кнопка нажимается примерно на 5+ пикселей ниже навигационной панели -

Моя проблема в этом-

Я добавил пользовательский заголовок с кнопками в табличное представление, но когда я нажимаю кнопки в заголовке, кнопки UINavigationBar срабатывают для этих 5+ пикселей вместо кнопок в заголовке табличного представления -

Я сделал тест и удалил кнопки из UINavigationBar, и что интересно, что для 5 пикселей ниже навигационной панели кнопки в заголовке не сработают, даже если на навигационной панели нет кнопок-

это почти как навигационная панель зарезервировала около 5+ пикселей под собой как пространство для кликов-

мой вопрос такой-

Может кто-нибудь сказать мне, как заставить навигационную панель не захватывать лишние 5+ пикселей для своих кнопок?

Большое спасибо;)

Ответы [ 8 ]

5 голосов
/ 27 мая 2014

Это единственное решение, которое я нашел. Создайте контейнер для пользовательской кнопки:

//Create a container for the button
UIView *buttonContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 55, 44)];

//Create a smaller button
UIButton *closeButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 55, 25)];
[closeButton setTitle:@"Cancel" forState:UIControlStateNormal];
//center the title
closeButton.titleEdgeInsets = UIEdgeInsetsMake(23, 0, 0, 0);

[buttonContainer addSubview:closeButton];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:buttonContainer];
3 голосов
/ 16 февраля 2011

Я не уверен на 100%, но, возможно, вы можете узнать местоположение касания с помощью класса UITouch?

UIBarButtonItem не расширяет UIResponder, но UINavigationBar делает!

Так что если вы подкласс UINavigationBar и используете этот подкласс в своем приложении, возможно, вы можете поймать координаты касания и проверить, в порядке ли они вам, а затем решите применить либо действие панели навигации, либо действие вашей кнопки (некоторыми пользовательское перенаправление).

2 голосов
/ 16 февраля 2010

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

1 голос
/ 22 мая 2016

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

Я создал подкласс UINavigationBar , который переопределяет только один метод: ' hitTest: withEvent: '. Когда вызывается hitTest: withEvent , он проверяет, произошло ли событие внутри фрейма панели навигации (pointInside: withEvent :) или нет. Если событие произошло снаружи, флаг userInteractionEnabled устанавливается на NO , поэтому событие будет игнорироваться панелью навигации и ее подпредставлениями.

В моем случае подкласс панели навигации вставляется через IB, но, конечно, также можно вставить его через 'UINavigationController initWithNavigationBarClass: toolbarClass:'

Заголовок:

@interface MMMasterNavigationBar : UINavigationBar

@end

Реализация:

@implementation MMMasterNavigationBar

/*
 hitTest:withEvent:

 The hit area in for navigation bar button items is enlarged by default.
 Other objects directly below the navigation bar doesn't receive tap events.
 We avoid the default enlarging of the tappable area by disabling userInteraction
 when the real tap is outside the navigation bar.

 */
-(UIView *)hitTest:(CGPoint)pPoint
         withEvent:(UIEvent *)pEvent {
    //FLog;

    if ([self pointInside:pPoint
                withEvent:pEvent]) {
        //NSLog(@"User interaction enabled");
        self.userInteractionEnabled = YES;

    } else {
        //NSLog(@"User interaction disabled");
        self.userInteractionEnabled = NO;
    }

    return [super hitTest:pPoint
                withEvent:pEvent];
}

@end
1 голос
/ 23 февраля 2011

Попытка обойти заполнение панели UINavigation может привести к проблемам при отправке в магазин приложений. Было бы проще добавить отступ к вашему пользовательскому заголовку. Как «толстый лес» я научился ценить HIG.

1 голос
/ 16 февраля 2011

Насколько я знаю отключить невозможно. Если у вас есть другие кнопки на панели навигации, эти пробелы не будут сталкиваться, но если у вас есть кнопка непосредственно под навигационной панелью без промежутков между ними, вам не повезло. Рассмотрим небольшой отступ в заголовке и его кнопках в качестве решения.

0 голосов
/ 18 июля 2015
    var buttonContainer:UIView = UIView()
    buttonContainer.frame = CGRectMake(0, 0, 32, 32)

    var imagess:UIImage = UIImage(named: "noti@2x.png")!

    var closeButton:UIButton = UIButton()
    closeButton.setImage(imagess, forState: UIControlState.Normal)
    closeButton.frame = CGRectMake(10, 5, 20, 20)
    closeButton.contentMode = UIViewContentMode.Center
    closeButton.titleEdgeInsets = UIEdgeInsetsMake(20, 0, 0, 0)

    buttonContainer.addSubview(closeButton)

    self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: buttonContainer)
0 голосов
/ 18 сентября 2014

Это можно сделать прямо из раскадровки. Перетащите UIView в каждый элемент навигации, установите его фон в clearColor и измените его размер. Перетащите кнопку в каждый UIView и измените их размер в соответствии.

...