在iPhone中将UIViewController显示为弹出窗口


75

由于此常见问题没有完整,确定的答案,因此我将在此处提出并回答。

通常,我们需要呈现一个UIViewController不覆盖全屏的图片,如下图所示。

在此处输入图片说明

苹果提供了几种类似的UIViewController,如UIAlertViewTwitter或Facebook共享视图控制器等。

对于定制控制器,我们如何实现这种效果?


10
请评论一下您为何投反对票,以便我改善。
CRDave

我建议您使用STPopup,就像UINavigationController一样使用它。
凯文(Kevin)

我发现这个吊舱很好:github.com/huynguyencong/EzPopup
huync

Answers:


95

注意:此解决方案在iOS 8中已损坏。我将尽快发布新解决方案。

我将在此处使用情节提要进行回答,但也可以不使用情节提要。

  1. 初始化:UIViewController在情节提要中创建两个。

    • 假设FirstViewController哪个正常,SecondViewController哪个会弹出。

  2. 莫代尔Segue公司:UIButton在FirstViewController和创建这个SEGUEUIButtonSecondViewController莫代尔SEGUE。

  3. 设为透明:现在选择UIViewUIView默认情况下使用创建UIViewController)的,SecondViewController然后更改其背景颜色以清除颜色。

  4. 制作背景暗淡:添加UIImageViewSecondViewController覆盖整个屏幕,并将其图像变暗一些半透明图像。您可以从这里获取示例:UIAlertView背景图片

  5. 显示设计:现在添加一个,UIView并进行您想要显示的任何类型的设计。这是我的故事板的屏幕截图 故事板

    • 在这里,我在登录按钮上添加了segue,该按钮SecondViewController作为弹出窗口打开,询问用户名和密码
  6. 重要提示:现在是主要步骤。我们希望这SecondViewController不会完全隐藏FirstViewController。我们已经设置了清晰的颜色,但这还不够。默认情况下,它会在模型​​演示文稿后面添加黑色,因此我们必须在的viewDidLoad中添加一行代码FirstViewController。您也可以在其他位置添加它,但是它应该在segue之前运行。

    [self setModalPresentationStyle:UIModalPresentationCurrentContext];

  7. 解除:什么时候解除取决于您的用例。这是一个模态演示,因此,请驳回我们所做的模态演示工作:

    [self dismissViewControllerAnimated:YES completion:Nil];

就这样.....

欢迎任何形式的建议和评论。

演示: 您可以从此处获得演示源项目:弹出演示

:有人在这个概念上做得非常好:MZFormSheetController
:我发现了另一个代码来获得这种功能:KLCPopup


iOS 8更新:我采用了这种方法,可同时在iOS 7和iOS 8中使用

+ (void)setPresentationStyleForSelfController:(UIViewController *)selfController presentingController:(UIViewController *)presentingController
{
    if (iOSVersion >= 8.0)
    {
        presentingController.providesPresentationContextTransitionStyle = YES;
        presentingController.definesPresentationContext = YES;

        [presentingController setModalPresentationStyle:UIModalPresentationOverCurrentContext];
    }
    else
    {
        [selfController setModalPresentationStyle:UIModalPresentationCurrentContext];
        [selfController.navigationController setModalPresentationStyle:UIModalPresentationCurrentContext];
    }
}

可以在prepareForSegue这样的内部使用此方法

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    PopUpViewController *popup = segue.destinationViewController;
    [self setPresentationStyleForSelfController:self presentingController:popup]
}

1
呈现第二个视图控制器时,设置[self setModalPresentationStyle:UIModalPresentationCurrentContext];似乎破坏了模式过渡动画(UIModalTransitionStyleCrossDissolve例如),因此它只是弹出而没有动画。有什么想法如何解决这个问题?
filwag 2013年

@cevitcejbo感谢您的关注。如果我们将transition属性设置为提供动画但仅在不显示时关闭的过渡属性,则可以选择segue。直到我不知道该怎么解决。找到时,我会编辑答案。如果你发现那片菜告诉我。
CRDave 2013年

5
如您上面建议的那样,@ CRDave[self setModalPresentationStyle:UIModalPresentationCurrentContext];不能单独工作。[self.navigationController setModalPresentationStyle:UIModalPresentationCurrentContext];您还必须按照演示项目中的描述使用。
Vasu

@Kailash是的,如果您使用的是navigationController而不是必需的,那么您是对的。我在这里写它:github.com/Chintan-Dave/popupDemo/issues/1。感谢在这里添加。
CRDave

如何更改弹出框的矩形?
Govind 2014年

51

接口构建器(故事板)中的模态弹出窗口

第1步

在要作为模式弹出窗口的ViewController上,使根UIView的背景颜色清晰可见。 在根视图上设置“清除颜色” 提示:不要将根UIView用作弹出窗口。添加一个较小的新UIView作为弹出窗口。

第2步

创建一个Segue到具有您的弹出窗口的ViewController。选择“模态呈现”。 塞格

从此处创建弹出窗口的两种方法

方法一-使用Segue

选择Segue并将Presentation更改为“ Over Current Context”: 在当前背景下

方法二-使用视图控制器

选择作为弹出窗口的ViewController场景。在“属性检查器”的“视图控制器”部分下,将“表示”设置为“在当前上下文之上”: ViewController

两种方法都可以。那应该做!

完成的产品


如果可以的话,这里还有更多帮助:在您的代码中的MyDialog:UIViewController之类的地方创建一个viewcontroller类。在情节提要中将其设置为新视图控制器的自定义类。放置按钮等,然后使用Control + Drag将其连接到您的代码中。单击按钮时调用dismiss(动画,完成)。
Numan Karaaslan'9

1
太好了。.谢谢
Im Batman

13

您可以在Interface Builder中执行此操作。

  • 对于您希望呈现的视图,以模态将其最外面的视图背景设置为透明
  • 按住Control键并单击并从主机视图控制器拖动到模式视图控制器
  • 模态选择礼物
  • 单击新创建的序列,然后在“属性检查器”(在右侧)中将“演示文稿”设置为“在当前上下文中”

10

可以随意使用我的iPhone表单控制器MZFormSheetController,在示例项目中,有很多示例介绍了如何呈现模态视图控制器,该控制器不会覆盖整个窗口,并且具有多种呈现/转换样式。

您还可以尝试MZFormSheetController的最新版本,称为MZFormSheetPresentationController,并具有许多其他功能。


这个表单控制器看起来很棒,唯一的问题是当我呈现全屏模式视图控制器然后关闭它时,表单控制器也将变为全屏。请帮助
Mazen Kasser 2013年

无需找到您的方便代码;)//显示MZFormSheetController * formSheet = [[MZFormSheetController alloc] initWithViewController:controller]; [formSheet presentAnimated:YEScompleteHandler:nil]; //关闭MZFormSheetController * controller = self.navigationController.formSheetController; [controller dismissFormSheetControllerAnimated:YEScompleteHandler:nil];
Mazen Kasser 2013年

2

您可以使用EzPopup(https://github.com/huynguyencong/EzPopup),它是一个Swift吊舱,非常易于使用:

// init YourViewController
let contentVC = ...

// Init popup view controller with content is your content view controller
let popupVC = PopupViewController(contentController: contentVC, popupWidth: 100, popupHeight: 200)

// show it by call present(_ , animated:) method from a current UIViewController
present(popupVC, animated: true)

1

Imao将UIImageView放在背景上并不是最好的主意。就我而言,我在控制器视图上添加了其他2个视图。第一个视图具有[UIColor clearColor]背景,第二个颜色-您想要透明的颜色(在我的情况下为灰色)。请注意顺序很重要。然后为第二个视图设置alpha 0.5(alpha> = 0 <= 1)。prepareForSegue

infoVC.providesPresentationContextTransitionStyle = YES;
infoVC.definesPresentationContext = YES;

就这样。


1

斯威夫特4:

添加叠加或弹出视图您还可以使用Container View,使用该容器可获取免费的View Controller(您从通常的对象选项板/库中获得Container View)

在此处输入图片说明

脚步:

  1. 有一个包含此容器视图的视图(照片中为ViewForContainer),以在显示容器视图的内容时将其变暗。连接第一个View Controller内部的插座

  2. 在第一个VC加载时隐藏此视图

  3. 单击按钮时取消隐藏 在此处输入图片说明

  4. 要在显示“容器视图”内容时将此视图变暗,请将“视图背景”设置为“黑色”,将不透明度设置为30%

在此处输入图片说明

当您单击按钮时,您将获得此效果 在此处输入图片说明


0

您可以执行此操作以将任何其他子视图添加到视图控制器。首先,将要添加为子视图的ViewController的状态栏设置为“无”,以便可以将大小调整为所需的大小。然后在Present View控制器中创建一个按钮以及一种单击按钮的方法。在方法中:

- (IBAction)btnLogin:(id)sender {
    SubView *sub = [[SubView alloc] initWithNibName:@"SubView" bundle:nil];
    sub.view.frame = CGRectMake(20, 100, sub.view.frame.size.width, sub.view.frame.size.height);
    [self.view addSubview:sub.view];
}

希望这会有所帮助,随时询问是否有任何疑问...


这是SubView是具有xib接口的UIViewController,不是子视图
User-1070892

确定,我不知道这种方式。谢谢。
CRDave
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.