【问题标题】:Pop up UIViewController with an IBAction UIViewController使用 IBAction UIViewController 弹出 UIViewController
【发布时间】:2012-12-02 16:40:52
【问题描述】:

是否可以在 iPad 中弹出 UIViewController(xib 文件)之类的 UIPopOverControl

我有一个单独的 NIB 文件,它链接到 UIViewController。我想弹出该NIB文件以及按下自定义大小(200,200)的按钮。

这可能吗?

我正在尝试在 iPhone 上获得类似的东西 - http://www.freeimagehosting.net/c219p

【问题讨论】:

    标签: objective-c uiviewcontroller ios6 uipopovercontroller


    【解决方案1】:

    您还可以使用这些自定义类之一来显示弹出窗口:

    https://github.com/sonsongithub/PopupView

    https://github.com/werner77/WEPopover

    https://github.com/50pixels/FPPopover

    FPPopover 示例:

    //the view controller you want to present as popover
    YourViewController *controller = [[YourViewController alloc] init]; 
    
    //our popover
    FPPopoverController *popover = [[FPPopoverController alloc] initWithViewController:controller]; 
    
    //the popover will be presented from the okButton view 
    [popover presentPopoverFromView:okButton]; 
    
    //release if you arent using ARC
    [controller release];
    

    【讨论】:

      【解决方案2】:

      是的。在需要时延迟加载您的 pOpOver 控制器。将其视图添加为子视图(您可以为添加设置动画)。使其框架大小符合您的需要并添加您已显示为 pOpOver 控制器的背景子视图的图像以及您想要在弹出窗口中的其他控件。

      祝你好运

      更新:

      好的,我会在我的应用程序Lucid Reality Check(部署目标iOS4.3)中向您展示ii如何做到这一点。

      可以使用 UIPopoverController 来呈现另一个控制器视图。 ii 首先要做的是确保 ii 始终知道设备的当前方向,因此 ii 可以在旋转时重新定位弹出窗口(也许这在 iOS6 上可以自行工作?)。所以在我的基本控制器中(我想显示一个弹出窗口)我有一个这样的实例变量:

        UIInterfaceOrientation toOrientation;
      

      还有:

        UIPopoverController *popover;
        UIButton            *popover_from_button;
        BOOL                 representPopover;
      

      popover 将被所有弹出窗口重复使用,popover_from_button 将保留启动弹出窗口的按钮。

      然后下一个代码进入基本控制器:

      - (void)popoverWillRotate {
        if ([popover isPopoverVisible]) {
            [self dismissPopover];
            representPopover = YES;
        }
      }
      
      - (void)popoverDidRotate {
        if (popover && representPopover) {
            representPopover = NO;
            [self representPopover];
        }
      }
      

      每次旋转设备时都必须调用这两个方法,如下所示:

      - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
        //DLOG(@"willRotateTo %i", toInterfaceOrientation);
        toOrientation = toInterfaceOrientation;
            if ([Kriya isPad ]) {
                [self popoverWillRotate];
            }
      }
      

      可以看到,首先捕获方向,然后调用 popoverWillRotate。这将在方向动画期间隐藏弹出框。旋转后,弹出框必须像这样重新显示:

      - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
              //DLOG(@"didRotateFrom %i", fromInterfaceOrientation);
          //[self layout:toOrientation]; //do some layout if You need 
          if ([Kriya isPad]) {
              [self popoverDidRotate];
          }
      }
      
      - (void)layout:(UIInterfaceOrientation)toInterfaceOrientation {
          //one can do view layout here, and call other controllers to do their layout too
      }
      

      现在已经解决了方向变化,显示弹出框的代码到了这里:

      #pragma mark Popovers
      - (void)presentPopoverWith:(id)controller fromButton:(UIButton*)button {
          if (popover)
             [popover release];
          if (popover_from_button)
              [popover_from_button release];
          popover_from_button = [button retain];
          popover = [[UIPopoverController alloc] initWithContentViewController:controller];
          [popover setDelegate:self];
          [self representPopover];
      }
      
      - (void)representPopover{
          if (popover) {
              UIPopoverArrowDirection arrowDirection = UIPopoverArrowDirectionAny;
              UIViewController *vc = (UIViewController*)[popover contentViewController];
              CGSize contentSize = [vc contentSizeForViewInPopover];
      
              if (contentSize.width > 0 && contentSize.height > 0) {
                  [popover setPopoverContentSize:contentSize animated:NO];
              }
              //DLOG(@"representPopover rect:%@", [Kriya printRect:popover_from_button.frame]);
              [popover presentPopoverFromRect:CGRectOffset(popover_from_button.frame, 0, popover_from_button.frame.size.height + 7.0)  inView:self.view permittedArrowDirections:arrowDirection animated:YES];   
          }
      }
      
      - (void)dismissPopover {
          if (popover) {
              [popover dismissPopoverAnimated:YES];
         }
      }
      

      最后,如果想要在弹出框被关闭时得到通知,基本控制器必须实现一个委托方法:

      #pragma mark UIPopoverControllerDelegate
      - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
          //do something important here like drink some water
      }
      

      并且不要忘记在其标头中将基本控制器设为 UIPopoverControllerDelegate。

      这种弹出窗口的用例如下所示:

      - (void)takeImage {    
          UIImagePickerController *picker = [[[UIImagePickerController alloc] init] autorelease];
          [picker setDelegate:self];
          [picker setAllowsEditing:NO];
          if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
              [picker setSourceType:UIImagePickerControllerSourceTypeCamera];         
              if ([Kriya isPad]) {            
                  [self presentPopoverWith:picker fromButton:backgroundImageButton];
              } else {
                  //modals on iPhone/iPod
                  //DLOG(@"takeImage addSubview picker");
                  [self presentModalViewController:picker animated:YES];
              }
          } else {
              //DLOG(@"no camera");
          }
      }
      

      这将使用图像选择器作为弹出窗口的内容,但可以使用任何具有有效视图的控制器。所以就这样做吧:

      [self presentPopoverWith:popupsContentController fromButton:tappedButton];

      一个不应该有任何遗漏的信息,:),方法[Kriya isPad]就是这样:

      + (BOOL)isPad {
        #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
          // iPad capable OS
              if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
                  //this is an iPad
                  return YES;
              }else {
                  //this is an iPod/iPhone
                  return NO;
              }
        #else
            //can not pissible be iPad
                return NO;
        #endif
        }
      

      尽情享受吧!

      【讨论】:

      • 你能帮我写代码吗?谢谢
      • 如果您自己还没有完成,请用代码更新我的答案;)
      • 在我添加了很棒的示例代码之后,为什么你对我的答案投了反对票?
      • 感谢@BigAppleBump 重新接受我的回答,我知道其他解决方案有利于快速“插入”代码,但有时当您想真正了解代码中发生了什么时,我的简单直接实现是最好的。你成功了吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-22
      • 1970-01-01
      • 2023-04-10
      • 2016-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多