在 iPhone 上显示弹出透明窗口的最佳方法?

Posted

技术标签:

【中文标题】在 iPhone 上显示弹出透明窗口的最佳方法?【英文标题】:Best Method to Show a Popup Transparent Window on iPhone? 【发布时间】:2013-10-22 05:06:48 【问题描述】:

我正在 Xcode 4.6 中构建一个 ios 6 iPhone 应用程序,我想知道实现以下类型弹出窗口的最佳方法:

具体来说,是右侧的 iPhone 屏幕截图,如果用户在主窗口中点击人脸或 UIView,则会出现一个部分透明的弹出框,其中包含更详细的信息——例如肖像照片和文本数据——但是原始视图(此处为照片集)仍然可见,并且计时器/计数器在该视图中继续滴答作响。

我认为这是一个可能的解决方案iPhone Modal View Smaller that the screen,但它对我不起作用。上面没有显示的是一个取消按钮,我也计划将它放在弹出窗口中,以便用户可以返回到下面的视图。当计时器到期时,详细视图也会消失。

我应该使用 presentModalViewController 和 Presenter/presented 方案,还是使用带有故事板 segue 的父子视图关系,或者我应该使用 loadNibNamed,还是使用某种 hack 来克服 iPhone 显示非完整内容的限制-屏幕模式视图?它将覆盖大部分屏幕,但我想确保下面的视图可见并且仍然处于活动状态,因为它向用户提供了不在弹出窗口中的信息(计时器等)。用户不需要与下面的屏幕进行交互,但我希望它是部分可见的。

我在主故事板中将弹出视图设计为单独的视图控制器,而不是作为 xib 文件。连接和出口是从界面生成器到我的代码形成的,称为 ProfileViewController。

警告:我的术语可能不正确和不准确。弹出窗口或弹出窗口可以是 UIView、UIViewController、UIWindow 或任何最适合以编程方式解决问题的方法。只要功能反映了我正在寻找的功能,我就不会将其绑定为某种小部件类型。

提前感谢您的建议!

【问题讨论】:

我的建议是使用 UIView 并将其 alpha 属性设置为黑色,即 view.alpha=0.8f 可以使viewcontroller的颜色清晰,并根据你的意愿设计新的uiview..然后[self.view addsubview:your_viewcontroller.view]; 回复:卡尔佩什。谢谢。我应该为弹出窗口子类化 UIView,还是为它创建一个随附的 ViewController?不太确定将出现在 UIView 中的项目的句柄(出口连接)放在哪里——底层的 ViewController?我之前将 UIView 子类化以创建可以放置在 IB 中的小部件,但从未在 Interface Builder 中设计过自定义小部件。 @Cindeselia 您可以在运行时以编程方式创建弹出视图。将其添加到窗口中。检查我的答案。 【参考方案1】:

你想实现这个吗?

这里有两个不同的viewControllers 一个在另一个之上。 vc2childViewControllervc1transparent 背景。在您的情况下,您可以将 UILabelbackgroundColor blackalpha = 0.5 放在堆栈顶部。

vc2 的所有事件都将在 vc2.m 上触发。在图片点击上使用此代码:

- (IBAction)imageClick 

    vc2 *viewController = [[vc2 alloc]init];
    [self addChildViewController:viewController];
    viewController.view.frame = self.view.frame;
    [self.view addSubview:viewController.view];
    viewController.view.alpha = 0;
    [viewController didMoveToParentViewController:self];

    [UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^
     
         viewController.view.alpha = 1;
     
                     completion:nil];

vc2.m 中将其放在viewDidLoad 上以使viewController透明。

self.view.backgroundColor = [UIColor clearColor];
self.view.opaque = YES;

将透明视图设为viewController 将使您的代码干净,因为vc2 的所有代码都将在一个单独的类中。

编辑

所以做一件事,首先将UIView 添加到您的xib,这将是一个圆形边框,并且根据您的屏幕截图,框架将是您想要的。

对于圆形边框,您可以使用此categorybackgroundColor 这个UIView 将是clearColor

- (void)setRoundedBorder:(float) radius borderWidth:(float)borderWidth color:(UIColor*)color

    CALayer * l = [self layer];
    [l setMasksToBounds:YES];
    [l setCornerRadius:radius];
    // You can even add a border
    [l setBorderWidth:borderWidth];
    [l setBorderColor:[color CGColor]];

现在放置一个UILabel/UIView/UIImage,其帧等于上面的UIView,alpha 为0.5,背景颜色为黑色。您可以直接从xib 执行此操作。无需通过代码设置框架。

然后开始将您的其他控件放入UIView

【讨论】:

是的,您的屏幕截图基本上是我想要的,除了我的屏幕截图是透明的,并且还为用户提供了单击其按钮以将信息返回给调用 ViewController 的选项。让我试试看,我会回来的。 这出现在行 viewController.view.frame = self.view.frame;............由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'*** - [NSPlaceholderMutableString initWithString:]:无参数” ***第一掷调用堆栈:(0x160b012 0x1318e7e 0x160adeb 0xd49e68 0x1d569 0x1d06c 0x33e1c7 0x33e232 0x5724 0x61db 0x52785a 0x52699b 0x5280df 0x52ad2d 0x52acac 0x522a28 0x28f972 0x28fe53 0x26dd4a 0x25f698 0x266ddf9 0x266dad0 0x1580bf5 0x1580962 0x15b1bb6 0x15b0f44 0x15b0e1b 0x266c7e3 0x266c668 0x25cffc 0x221d 0x2145) libc++abi.dylib: 终止调用抛出异常 正如我所说,将一个半透明的UILabellabel.frame = self.view.frame 放在一起。对于十字按钮单击使用此代码:[UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^ self.view.alpha = 0; completion:^(BOOL finished) if(finished) [self.view removeFromSuperview]; ]; 很抱歉问了另一个问题,但为什么我们需要 UILabel?我们不应该让堆栈中的顶部视图类似于具有透明背景的 UIView 或加载了透明图像的 UIImage 吗? (只是想知道,因为这似乎违反直觉) 我只是尝试将 UILabel 或 UIImageView 放在堆栈的顶部,它删除了我已经在堆栈中的所有内容!复制/粘贴也不起作用,它只取了我复制的一个元素并替换了堆栈的顶部;其他一切都消失了。如何将我已经绘制和布局(并附加)的东西保留在顶部视图中?【参考方案2】:

试试这个

// create a new view
  UIView *viewPopup=[[UIView alloc]init];
  [viewPopup setBackgroundColor:[UIColor blackColor]];
  viewPopup.alpha=0.6f;

 // add into window
 AppDelegate *appdelgateobj=(AppDelegate *)[[UIApplication sharedApplication]delegate];
 [appdelgateobj.window addSubview:viewPopup];
 [appdelgateobj.window bringSubviewToFront:viewPopup];

【讨论】:

Kalpesh:谢谢,我喜欢解决方案的简单性。我关心的是如何将自定义元素放入弹出窗口中? (好吧,我知道如何添加属性和成员变量,但我的意思是想知道我想出现在屏幕上的哪些元素需要看起来正确,等等。在 Interface Builder 中设计新视图的任何方式?喜欢而不是文本数字,我有一个动画条形图。我知道如何在代码中实例化它们,但不知道将它们放在正确的位置。这只是试错吗?) @Korben 使用这个 [viewPopup removeFromSuperview]; viewPopup=nil;【参考方案3】:

按照以下步骤进行透明视图:

第 1 步:

第 2 步:

无论何时需要 Transpertview.hidden=NO: 当您不想要时,Transpertview.hidden=YES:

也许会有所帮助。

【讨论】:

Dhaval Bhadania:只有一个问题。如果我拖入那个 UIImageView 或 UIView 并在其中执行我所有的设计和布局,它会去哪里?就像,如果我将它拖到情节提要中调用 ViewController 的顶部,它将覆盖所有内容并阻止我编辑原件。如果我把它放在一边,加载时它不会出现在正确的位置......或者有没有办法以编程方式重新对齐它? 如果您想以编程方式添加,请使用@iPatel 回答。 不,理想情况下我想要两者的混合体,比如在 Interface Builder 中布局我的设计,因为有大量小部件需要小心放置在弹出窗口中,但实例化一个版本代码中的弹出窗口,如果可能的话。【参考方案4】:

在您的 .m 文件中添加#import <QuartzCore/QuartzCore.h> 框架并使用以下代码

UIWindow* window = [UIApplication sharedApplication].keyWindow;
    self.dimView = [[UIView alloc] initWithFrame:window.bounds];
    self.dimView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:.6];
    self.dimView.userInteractionEnabled = YES;
    [window addSubview:self.dimView];

上面这个是透明的dimView,大小和window差不多。

self.searchTblContainerView = [[UIView alloc] init];
    self.searchTblContainerView.frame = CGRectMake(15, (window.frame.size.height - 300) / 2, 290, 300);
    self.searchTblContainerView.layer.cornerRadius = 15.f;
    self.searchTblContainerView.layer.borderColor = [UIColor blackColor].CGColor; /// set color as per your requirement
    self.searchTblContainerView.layer.borderWidth = 2.f;
    self.searchTblContainerView.alpha = 0.80; /// set as per your requirement 
    self.searchTblContainerView.clipsToBounds = YES;
    [self.dimView addSubview:self.searchTblContainerView];

self.searchTblContainerView 上方是包含整个UIControls 的主视图,例如标签、文本字段、按钮等...并根据您的要求进行设置。

默认设置self.dimView.hidden = YES;的隐藏属性 和显示和隐藏通过跟随像alertView的动画(apple)

以下代码用于显示 dimView。

self.searchTblContainerView.transform = CGAffineTransformMakeScale(0.01, 0.01);
        [UIView animateWithDuration:0.30 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^
            self.searchTblContainerView.transform = CGAffineTransformIdentity;
            self.dimView.hidden = NO;
         completion:^(BOOL finished)];

        UIWindow* window = [UIApplication sharedApplication].keyWindow;
        [window bringSubviewToFront:self.dimView];

下面是隐藏 dimView 的代码。

 self.searchTblContainerView.transform = CGAffineTransformIdentity;
    [UIView animateWithDuration:0.30 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^
        self.searchTblContainerView.transform = CGAffineTransformMakeScale(0.01, 0.01);
     completion:^(BOOL finished)
        self.dimView.hidden = YES;
    ];

上面的代码是简单的逻辑,可能对你的情况有用。

【讨论】:

iPatel:感谢您提供的逻辑和代码。我认为我不需要单独的 ViewController 来处理 dimView?只需将 UIView 子类化,并在代码中处理有关在 dimView 中显示的内容的所有内容,并让底层的 PhotoCollectionViewController 处理显示、隐藏、实例化 dimView 吗? (即,当您说 .m 文件时,您的意思是 UnderlyingViewController.m,而不是 DimWindowViewController.m,并且不涉及任何转接,仅显示和隐藏)。 如果你不想使用 dimView 那么它并不重要/不需要使用,我只是使用 dimView 让你的自定义视图看起来像 alertView。 不,我对 dimView 没问题,只是在没有视觉指导的情况下设计 UIView 没有那么自信。我有点被 Interface Building 宠坏了,所以如果我在 IB 中设计弹出窗口并通过 ctrl-drag 在那里建立我的所有插座和连接,我会自动假设我需要一个 ViewController。不知道如何在没有 ViewController 的情况下将其变为 UIView。

以上是关于在 iPhone 上显示弹出透明窗口的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章

iPhone 设备轮换上的弹出窗口更改

iPhone应用程序的灵活弹出菜单窗口

如何在 iPhone/iPad/iOS 上显示临时弹出消息

禁用iPhone“保存图像”弹出窗口[重复]

outlook2010的收到邮件后怎么弹出提示窗口

在网页上显示弹出数据的正确方法?