且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-02-17 13:16:11

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

我将在这里使用故事板回答,但也可以不使用故事板.

  1. 初始化:在storyboard中创建两个UIViewController.

    • 让我们说 FirstViewController 是正常的,而 SecondViewController 将是弹出窗口.

  2. Modal Segue:UIButton 放入 FirstViewController 并在此 UIButton 上创建一个 segue 到 SecondViewController作为模态转场.

  3. Make Transparent: 现在选择 UIView(UIView 默认使用 UIViewController 创建)SecondViewController 并将其背景颜色更改为清除颜色.

  4. 使背景变暗:SecondViewController 中添加一个 UIImageView 覆盖整个屏幕并将其图像设置为一些变暗的半透明图像.您可以从此处获取示例:

    :有人在这个概念上做得很好:MZFormSheetController
    :我又找到了一个代码来获得这种功能:KLCPopup

    iOS 8 更新:我使这个方法适用于 iOS 7 和 iOS 8

    + (void)setPresentationStyleForSelfController:(UIViewController *)selfController presentingController:(UIViewController *)presentingController{如果(iOS版本> = 8.0){presentingController.providesPresentationContextTransitionStyle = YES;presentingController.definesPresentationContext = YES;[presentingController setModalPresentationStyle:UIModalPresentationOverCurrentContext];}别的{[selfController setModalPresentationStyle:UIModalPresentationCurrentContext];[selfController.navigationController setModalPresentationStyle:UIModalPresentationCurrentContext];}}

    可以像这样在prepareForSegue中使用这个方法

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {PopUpViewController *popup = segue.destinationViewController;[self setPresentationStyleForSelfController:self presentingController:popup]}

    Since there is no complete, definitive answer to this common recurring question, I'll ask and answer it here.

    Often we need to present a UIViewController such that it doesn't cover full screen, as in the picture below.

    Apple provides several similar UIViewController, such as UIAlertView, Twitter or Facebook share view controller, etc..

    How can we achieve this effect for a custom controller?

    NOTE : This solution is broken in iOS 8. I will post new solution ASAP.

    I am going to answer here using storyboard but it is also possible without storyboard.

    1. Init: Create two UIViewController in storyboard.

      • lets say FirstViewController which is normal and SecondViewController which will be the popup.

    2. Modal Segue: Put UIButton in FirstViewController and create a segue on this UIButton to SecondViewController as modal segue.

    3. Make Transparent: Now select UIView (UIView Which is created by default with UIViewController) of SecondViewController and change its background color to clear color.

    4. Make background Dim: Add an UIImageView in SecondViewController which covers whole screen and sets its image to some dimmed semi transparent image. You can get a sample from here : UIAlertView Background Image

    5. Display Design: Now add an UIView and make any kind of design you want to show. Here is a screenshot of my storyboard

      • Here I have add segue on login button which open SecondViewController as popup to ask username and password
    6. Important: Now that main step. We want that SecondViewController doesn't hide FirstViewController completely. We have set clear color but this is not enough. By default it adds black behind model presentation so we have to add one line of code in viewDidLoad of FirstViewController. You can add it at another place also but it should run before segue.

      [self setModalPresentationStyle:UIModalPresentationCurrentContext];

    7. Dismiss: When to dismiss depends on your use case. This is a modal presentation so to dismiss we do what we do for modal presentation:

      [self dismissViewControllerAnimated:YES completion:Nil];

    Thats all.....

    Any kind of suggestion and comment are welcome.

    Demo : You can get demo source project from Here : Popup Demo

    NEW : Someone have done very nice job on this concept : MZFormSheetController
    New : I found one more code to get this kind of function : KLCPopup


    iOS 8 Update : I made this method to work with both iOS 7 and 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];
        }
    }
    


    Can use this method inside prepareForSegue deligate like this

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    
        PopUpViewController *popup = segue.destinationViewController;
        [self setPresentationStyleForSelfController:self presentingController:popup]
    }