【问题标题】:ABPeoplePickerNavigationController - remove "Cancel" button without using private methods/properties?ABPeoplePickerNavigationController - 删除“取消”按钮而不使用私有方法/属性?
【发布时间】:2009-10-23 05:18:40
【问题描述】:

我正在使用 ABPeoplePickerNavigationController,它是 UINavigationController 的子类,在上下文中我使用的是右侧的默认导航栏按钮“取消”,这没有任何意义。我找不到禁用或隐藏它的方法,并且使用的任何方法都必须是公开的和商店可批准的。 完全摆脱导航栏(picker.navigationBarHidden = YES;)可能是一个选项,除了在弹出回到联系人列表后导航栏重新出现。 继承 ABPeoplePickerNavigationController 并拦截 viewWillAppear 以尝试取消取消按钮无效。 [选择器设置允许取消:否];确实有效,但没有记录,所以我希望永远不会通过批准。

【问题讨论】:

  • 这可能有助于scott-sherwood.com/…
  • 我被困在同一个问题上,只想说这绝对是苹果的嘲笑。是的,如果您使用 setAllowsCancel 或 setAllowsCardEditing,您的应用将被拒绝。

标签: iphone iphone-sdk-3.0 uinavigationbar


【解决方案1】:

这个

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
  UIView *custom = [[UIView alloc] initWithFrame:CGRectMake(0.0f,0.0f,0.0f,0.0f)]; 
  UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithCustomView:custom]; 
  //UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addAction)]; 
  [viewController.navigationItem setRightBarButtonItem:btn animated:NO]; 
  [btn release]; 
  [custom release]; 
}

完美运行!

【讨论】:

    【解决方案2】:

    此处的示例使用委托方法 navigationController:willShowViewController:animated: 确实可以工作,但您可能希望在自己的控制器中添加自己的导航项,并且给定的选项将删除您可能设置的任何内容你自己的控制器。这是我已成功使用的代码,可让此选项正常工作:

    - (void)navigationController:(UINavigationController *)navigationController
          willShowViewController:(UIViewController *)viewController
                        animated:(BOOL)animated {
    
        // Here we want to remove the 'Cancel' button, but only if we're showing
        // either of the ABPeoplePickerNavigationController's top two controllers
        if ([navigationController.viewControllers indexOfObject:viewController] <= 1) {
    
            viewController.navigationItem.rightBarButtonItem = nil;
        }
    }
    

    请注意,导航控制器的堆栈中有两个视图控制器,一个用于联系人组,一个用于联系人列表。这就是为什么我们不能只检查 viewController 是否是导航控制器的顶视图控制器。

    【讨论】:

      【解决方案3】:

      对此没有答案 - 如果您无法忍受取消,请编写一个新的人员选择器。

      【讨论】:

      • 你不能只写一个“person picker”——你需要请求通讯录权限,这会降低转化率; Apple 的默认人员选择器不需要系统权限。
      【解决方案4】:

      您可以通过选择器子视图浏览该结果。就是有点无聊……

      【讨论】:

        【解决方案5】:

        我还没有尝试过,但我认为 Uby 说要遍历选择器的子视图,直到找到 isKindOfClass:[UIBarButtonItem class] 的子视图,然后您可以更改它的标题属性。它也可能在 navigationBar 的 'Item' 数组中。

        【讨论】:

          【解决方案6】:

          将委托设置为 PeoplePickerController 控制器。 在委托类中,有这个委托方法。

          - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
          {
           UIView *pCustomView = [[UIView alloc] initWithFrame:CGRectMake(0,0,0,0)];
           UIBarButtonItem *pBtn = [[UIBarButtonItem alloc] initWithCustomView:pCustomView];
           [viewController.navigationItem setRightBarButtonItem:pBtn animated:NO];
           [pBtn release];
           [pCustomView release];
          }
          

          【讨论】:

            【解决方案7】:

            确保将选取器对象的委托(不是 peoplePickerDelegate,只是委托)设置为实现以下方法的类:

            - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
            UIView *custom = [[UIView alloc] initWithFrame:CGRectMake(0,0,0,0)];
            UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithCustomView:custom];
            [viewController.navigationItem setRightBarButtonItem:btn animated:NO];
            [btn release];
            [custom release];
            } 
            

            【讨论】:

              【解决方案8】:

              它工作正常,但在 iOS 4 中还有一件事。当我使用快速应用切换功能切换回我的应用时,取消按钮再次出现。

              方法

              - (void)navigationController:(UINavigationController *)navigationController  
                    willShowViewController:(UIViewController *)viewController
                                  animated:(BOOL)animated
              

              没有被调用。所以我做了这个:

              - (void)applicationDidEnterBackground:(UIApplication *)application {
                  id topView = pickerControllerDelegate.peoplePicker.topViewController;
                  topView.navigationItem.rightBarButtonItem = nil;
              }
              

              效果很好。

              【讨论】:

                【解决方案9】:

                根据 russel b 你可以覆盖你的 viewdidapper

                这对我有用:

                - (void)viewDidAppear:(BOOL)animated {
                    [super viewDidAppear:animated];
                    UINavigationItem *item = (UINavigationItem *)[self.navigationBar.items lastObject];
                    item.rightBarButtonItems = [[NSArray alloc] init];
                
                    item.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addPerson)];
                }
                

                【讨论】:

                  【解决方案10】:

                  编辑:见下面的 cmets。现在这是一个不该做什么的说明。

                  我尝试通过子类化 ABPeoplePickerNavigationController 并拦截所有更改当前导航视图控制器视图的事件来使用公共 API 获得所需的行为。然后可以浏览视图层次结构并清除所有不需要的按钮。

                  您可以从委托中导航视图层次结构,但您不知道更改视图状态的事件...这使得您很难杀死“取消”按钮并使其保持不变。

                  这段代码有点对我有用(注意:它蛮力杀死了所有右手按钮):

                  - (void)viewDidAppear:(BOOL)animated {
                      [super viewDidAppear:animated];
                      [self killCancelButton];
                  }
                  
                  - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
                      [super pushViewController:viewController animated:animated];
                      [self killCancelButton];
                  }
                  
                  - (UIViewController*)popViewControllerAnimated:(BOOL)animated {
                      UIViewController *result = [super popViewControllerAnimated:animated];
                      [self killCancelButton];
                      return result;
                  }
                  
                  - (void)killCancelButton {
                      for (NSUInteger itemIdx = 0; itemIdx < self.navigationBar.items.count; itemIdx++) {
                          UINavigationItem *item = [self.navigationBar.items objectAtIndex:itemIdx];
                          item.rightBarButtonItems = [[NSArray alloc] init];
                      }
                  }
                  

                  【讨论】:

                  • 顺便说一句,你是对的 viewWillAppear:(BOOL) 不起作用。视图已经生效后,我必须触发 killCancelButton 。在我的 iPhone 4 上看起来没有问题,但在较旧/较慢的设备上看起来很有趣,我想。
                  • 看起来有问题,因为当 ABPeoplePickerNavigationController 显示为模态时,它会使用取消按钮进行动画处理。只有当它停止时,按钮才会被移除。啊。
                  • 我最终构建了自己的视图/控制器,从地址簿框架中获取模型数据,因为如上所述,这最终出现了故障。希望我没有误导任何人进入暴力的安全感。
                  猜你喜欢
                  • 1970-01-01
                  • 2017-04-29
                  • 1970-01-01
                  • 2020-11-02
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-02-01
                  相关资源
                  最近更新 更多