6

我创建了一个带有侧边菜单的应用程序,例如 facebooks。我有一个根视图控制器,它在自身上添加一个视图,然后当用户按下“菜单”按钮时,它将滑动视图,以便您可以看到菜单。

我的问题是,当视图第一次加载时,它看起来 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];

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}}

约会视图控制器

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)];

日历日视图

- (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];

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

任何人都知道为什么导航栏会阻止点击的顶部headerView?要清楚被阻止的 headerView 部分是从蓝线的底部向上。带有红色背景的UIButton动作与框架相关联,因此它应该触发事件,但似乎导航栏阻止了一半的UIButton接收点击。

4

1 回答 1

1

这种行为是由于 UIWindow 没有传播与导航栏框架一致的触摸。覆盖此行为的唯一方法是继承 UIWindow 并覆盖 hitTest: 方法。这将允许您检测该区域的触摸,并将它们转发给适当的响应者。

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

于 2012-04-30T20:40:41.920 回答