UINavBar似乎在其他按钮上有一个不可见的图层

Bot*_*Bot 6 objective-c uinavigationbar uinavigationcontroller ios5

我创建了一个带有像facebook这样的侧边菜单的应用程序.我有一个根视图控制器,它自己添加一个视图,然后当用户按下"菜单"按钮时,它将滑动视图,以便您可以看到菜单.

我的问题是,当视图首次加载时,看起来UINavBar大约比它应该低20个像素左右.(下面的图像看起来有点偏离中心,因为它是一个模态水平翻转)

在此输入图像描述

然后,当模态转换完成时,它会自动调整自身并向上移动到该状态栏下方.

在此输入图像描述

以下是按"菜单"按钮时发生的情况的屏幕截图.它将顶视图滑动到右侧

在此输入图像描述

正如您在上面的图像中看到的那样,我将左箭头和右箭头框架背景设置为红色,这样我就可以看到可点击/可点击区域的位置.我有另一张图像,我在上面画了一条蓝线,如果我点击蓝线或上面那么它就不会触发右箭头.如果我点击左侧相同的一般区域,菜单按钮将会触发.我能够在模拟器和移动设备上重现这一点(所以我不会用手指按钮).

在此输入图像描述

在我看来,由于导航栏的加载低于iPhone应该认为它仍处于该位置,因此当我在UIButton框架内单击时,它仍然触发菜单而不触发箭头选择器.如果我在箭头中间直接点击,它会触发箭头选择器,但只是图像外的一点点,它不会触发箭头选择器.

这是我的RootViewControllerviewDidLoad

AppointmentViewController *appointmentViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"AppointmentViewController"];
NSLog(@"B: %@",NSStringFromCGRect(appointmentViewController.view.frame));
self.navController = [[UINavigationController alloc] initWithRootViewController:appointmentViewController];
NSLog(@"B2: %@",NSStringFromCGRect(appointmentViewController.view.frame));
NSLog(@"Nav Bounds: %@",NSStringFromCGRect(self.navController.view.frame));
NSLog(@"Bounds: %@",NSStringFromCGRect(self.contentView.bounds));
self.navController.view.frame = self.contentView.bounds;
NSLog(@"Nav Bounds2: %@",NSStringFromCGRect(self.navController.view.frame));
[self addShadowToMenu];
[self.contentView addSubview:self.navController.view];
Run Code Online (Sandbox Code Playgroud)

RootViewController日志

2012-04-30 12:24:44.533 My-App[19929:fb03] B: {{0, 20}, {320, 460}}
2012-04-30 12:24:44.535 My-App[19929:fb03] B2: {{0, 20}, {320, 460}}
2012-04-30 12:24:44.535 My-App[19929:fb03] Nav Bounds: {{0, 0}, {320, 480}}
2012-04-30 12:24:44.535 My-App[19929:fb03] Bounds: {{0, 0}, {320, 460}}
2012-04-30 12:24:44.535 My-App[19929:fb03] Nav Bounds2: {{0, 0}, {320, 460}}
Run Code Online (Sandbox Code Playgroud)

AppointmentViewController

self.title = [dataObj.preferences objectForKey:@"appts_name_plural"];
self.navigationItem.title = self.title;
dayView = [[APCalendarDayView alloc] initWithCalendarView:(APCalendarView *)self];
APListView = [self.storyboard instantiateViewControllerWithIdentifier:@"AppointmentListView"];
APListView.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];


SideMenuView *myDelegate = [[SideMenuView alloc] init];
[self setSideMenuDelegate:myDelegate];
//set the delegate's currentViewController property so that we can add a subview to this View. 
[sideMenuDelegate setCurrentViewController:self];

UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *today = [[UIBarButtonItem alloc] initWithTitle:@"Today" style:UIBarButtonItemStyleBordered target:nil action:@selector(todayPressed)];
NSArray *appointmentNavigationItems = [[NSArray alloc] initWithObjects:@"Day",@"List",@"Month", nil];
navcontrol = [[UISegmentedControl alloc] initWithItems:appointmentNavigationItems];
[navcontrol setSegmentedControlStyle:UISegmentedControlStyleBar];
[navcontrol addTarget:self action:@selector(appointmentNavigationClicked:) forControlEvents:UIControlEventValueChanged];
[navcontrol setSelectedSegmentIndex:0];
UIBarButtonItem *segmentItems = [[UIBarButtonItem alloc] initWithCustomView:navcontrol];

NSArray *items = [NSArray arrayWithObjects:today,flexSpace,segmentItems, flexSpace, nil];
[appointmentToolbar setItems:items animated:NO];
[appointmentToolbar setAutoresizesSubviews:YES];


[[self.view superview] addSubview:myDelegate.view];
[self setViewSizeOffset:(appointmentToolbar.bounds.size.height)];
Run Code Online (Sandbox Code Playgroud)

CalendarDayView

- (void)addSubviewsToHeaderView:(UIView *)headerView
{
    const CGFloat kChangeMonthButtonWidth = 46.0f;
    const CGFloat kChangeMonthButtonHeight = 44.0f;
    const CGFloat kMonthLabelWidth = 215.0f;
    const CGFloat kHeaderVerticalAdjust = 7.f;

    // Header background gradient
    UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Kal.bundle/kal_grid_background.png"]];
    CGRect imageFrame = headerView.frame;
    imageFrame.origin = CGPointZero;
    backgroundView.frame = imageFrame;
    [headerView addSubview:backgroundView];
    [backgroundView setAutoresizesSubviews:YES];
    [backgroundView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];

    // Create the previous month button on the left side of the view
    CGRect previousMonthButtonFrame = CGRectMake(self.left, 0, kChangeMonthButtonWidth, kChangeMonthButtonHeight);
    UIButton *previousMonthButton = [[UIButton alloc] initWithFrame:previousMonthButtonFrame];
    [previousMonthButton setBackgroundColor:[UIColor redColor]];
    [previousMonthButton setImage:[UIImage imageNamed:@"Kal.bundle/kal_left_arrow.png"] forState:UIControlStateNormal];
    previousMonthButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
    previousMonthButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
    [previousMonthButton addTarget:self action:@selector(showPreviousDay) forControlEvents:UIControlEventTouchUpInside];
    //[previousMonthButton setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin];
    [headerView addSubview:previousMonthButton];

    // Draw the selected month name centered and at the top of the view
    CGRect monthLabelFrame = CGRectMake((self.frame.size.width/2.0f) - (kMonthLabelWidth/2.0f), kHeaderVerticalAdjust, kMonthLabelWidth, kMonthLabelHeight);
    headerTitleLabel = [[UILabel alloc] initWithFrame:monthLabelFrame];
    headerTitleLabel.backgroundColor = [UIColor clearColor];
    headerTitleLabel.font = [UIFont boldSystemFontOfSize:22.f];
    headerTitleLabel.textAlignment = UITextAlignmentCenter;
    headerTitleLabel.textColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Kal.bundle/kal_header_text_fill.png"]];
    headerTitleLabel.shadowColor = [UIColor whiteColor];
    headerTitleLabel.shadowOffset = CGSizeMake(0.f, 1.f);
    //[self setHeaderTitleText:[logic selectedMonthNameAndYear]];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"E, MMM dd, yyyy"];   
    headerTitleLabel.text = [dateFormatter stringFromDate:dataObj.activeDate];
    [headerView addSubview:headerTitleLabel];

    // Create the next month button on the right side of the view
    CGRect nextMonthButtonFrame = CGRectMake(self.frame.size.width - kChangeMonthButtonWidth, 0, kChangeMonthButtonWidth, kChangeMonthButtonHeight);
    UIButton *nextMonthButton = [[UIButton alloc] initWithFrame:nextMonthButtonFrame];
    nextMonthButton.frame = nextMonthButtonFrame;
    [nextMonthButton setImage:[UIImage imageNamed:@"Kal.bundle/kal_right_arrow.png"] forState:UIControlStateNormal];
    [nextMonthButton setBackgroundColor:[UIColor redColor]];
    nextMonthButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
    nextMonthButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
    [nextMonthButton addTarget:self action:@selector(showFollowingDay) forControlEvents:UIControlEventTouchUpInside];
    //[nextMonthButton setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
    [headerView addSubview:nextMonthButton];
}

UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0.f, 0.f, self.frame.size.width, kHeaderHeight)];
    headerView.backgroundColor = [UIColor grayColor];
    [self addSubviewsToHeaderView:headerView];
    [headerView setAutoresizesSubviews:YES];
    [headerView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
    [self addSubview:headerView];
    [self bringSubviewToFront:headerView];
Run Code Online (Sandbox Code Playgroud)

如果我headerView向下移动更远,它将允许我选择红色区域中的任何位置并触发箭头选择器.但是,我希望它与苹果日历相匹配,并且位于导航栏下方.

任何人都知道为什么导航栏会阻止headerView被轻敲的顶部?要清楚的是,被阻止的headerView部分是从蓝线的底部向上.在UIButton与红色背景具有绑在框架所以应该触发事件的动作,但它出现的导航栏是阻塞的一半UIButton接收来自抽头.

Sam*_*Sam 1

此行为是由于 UIWindow 没有传播与导航栏框架一致的触摸。重写此行为的唯一方法是子类化 UIWindow 并重写 hitTest: 方法。这将使您能够检测该区域的触摸,并将其转发给适当的响应者。

下面是一个示例项目,显示了一个自定义 UIWindow 子类,它将响应屏幕上任何位置的触摸。