UIAlertView 按钮(子视图)未在 iOS 7 中显示

Posted

技术标签:

【中文标题】UIAlertView 按钮(子视图)未在 iOS 7 中显示【英文标题】:UIAlertView Buttons(subviews) is not Showing in iOS 7 【发布时间】:2013-09-23 16:13:15 【问题描述】:

UIAlertView 在 ios 6 中使用以下代码运行良好。但是当涉及到 ios 7 时,子视图(我的代码中的“是”和“否”按钮)在调用 alertview 时不显示,仅显示文本消息。可以有人告诉我如何解决这个问题吗?

viewController.m 文件

 [Utilities prCustomAlert:@"Textmessage" inTitle:@"Alert view title" delegate:self inTag:300];
 CustomAlertView *alertView    = [Utilities sharedUtility].customAlertView;
alertView.numberOfBtns  = 2;
UIButton *btn= (UIButton *)[alertView viewWithTag:10];
[btn setTitle:@"no" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(dontlogout) forControlEvents:UIControlEventTouchDown];

btn = (UIButton *)[alertView viewWithTag:11];
[btn setTitle:@"yes" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(logout) forControlEvents:UIControlEventTouchDown];    
[Utilities displayCustomAlertForDelegate:self];

UIAlertView.m 文件

  CGRect viewFrame    = self.frame;
  CGRect buttonFrame  = button.frame;
  if(self.numberOfBtns==2)

  CGRect labelFrame   = [self viewWithTag:15].frame;        
  button.frame    = CGRectMake(10, 0, 40, 30);
        button.hidden   = NO;

        //yes...
        btn          = (UIButton *)[self viewWithTag:11];       
        btn.frame    = CGRectMake(60, 0, 40, 30);
        btn.hidden   = NO;

        //no..    
        btn          = (UIButton *)[self viewWithTag:10];
        btn.hidden   = YES;


  

【问题讨论】:

UIAlertView 的视图层次结构已经私有很长时间了。 Apple 开始在 iOS7 中强制执行此操作。您必须创建一个模仿 UIAlertView 的 UIView 子类,而不是操纵视图层次结构。 @MatthiasBauch 你能用编码回答吗?比如如何创建 UIViews 并将其添加到 UIAlertView 您无法将视图添加到 UIAlertView。您将 UIView 子类化并使其看起来像 UIAlertView。检查 cocoapods 以获取符合您要求的课程。 【参考方案1】:

当 UIAlertView 出现时,我们可以通过向presentedViewController 的视图添加子视图来向 UIAlerView 添加子视图。我已经通过以下方式访问了 UIAlertView:

NSArray *subviews = [UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController.view.subviews;

我创建了 UIAlerView 的子类:

头文件:

@interface MLKLoadingAlertView : UIAlertView

- (id)initWithTitle:(NSString *)title;

@end

实施文件:

#import "MLKLoadingAlertView.h"

#define ACTIVITY_INDICATOR_CENTER   CGPointMake(130, 90)

@implementation MLKLoadingAlertView

- (id)initWithTitle:(NSString *)title

    if ( self = [super init] )
    
        self.title = title;
        self.message = @"\n\n";

        [self setDelegate:self];
    

    return self;


// You can Customise this based on your requirement by adding subviews.
- (void)didPresentAlertView:(UIAlertView *)alertView

    NSArray *subviews = [UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController.view.subviews;

    if( subviews.count > 1 )
    
        // iOS while presenting an alertview uses a presening view controller. That controller's view has several subviews. I have picked one
        // subview from it which has frame similar to the alertview frame.
        UIView *presentedView = [subviews objectAtIndex:1];

         UIActivityIndicatorView *customActivityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
        [customActivityIndicator startAnimating];
        customActivityIndicator.center = ACTIVITY_INDICATOR_CENTER;

        [presentedView addSubview:customActivityIndicator];
    


@end

在 - (void)didPresentAlertView:(UIAlertView *)alertView 方法中,我通过访问 Presented View Controller 的视图将子视图添加到 UIAlertView。

你可以在Here找到解释和代码示例

【讨论】:

【参考方案2】:

你所做的总是错的。不允许将自己的子视图添加到 UIAlertView。好消息是 - 在 iOS 7 中,您不必这样做!新的自定义过渡动画机制让您可以创建自己的视图,该视图的行为只是一个警报视图,但由于它是您的视图,您可以将任何您喜欢的内容放入其中,如下所示:

请注意,假的“警报视图”如何漂浮在右侧屏幕截图中的原始视图前面,并使其后面的屏幕变暗,就像真正的警报视图一样。但它完全由自定义内容组成; “真正的”警报视图永远不能包含图像和开关!

有关创建此视图的代码,您可以轻松地根据自己的目的进行调整,请参阅我的 github 站点:https://github.com/mattneub/custom-alert-view-iOS7

【讨论】:

【参考方案3】:

我认为iOS7问题的根源在于Apple改变了UIAlertView的外观机制。 从现在开始,在启动两个私有视图控制器之后,任何显示的 alertView 都会出现

_UIModalItemAppViewController
_UIModalItemsPresentingViewController

换句话说,现在 UIAlertView 不是一个纯粹的视图 - 它是一些复杂的视图控制器集合的一部分,具有完整的视图控制器生命周期。

但好消息是您可以在标准警报视图中将 accessoryView 更改为您的 customContentView

[alertView setValue:customContentView forKey:@"accessoryView"];

请注意,您必须在 [alertView show] 之前调用它。

【讨论】:

以上是关于UIAlertView 按钮(子视图)未在 iOS 7 中显示的主要内容,如果未能解决你的问题,请参考以下文章

将 UIImageview 添加到子视图后,无法单击 UIAlertView 中的按钮

如何在 iOS 8 上显示没有按钮的 UIAlertView?

警报视图中的文本字段未在 iOS 7 上显示 [关闭]

在 iOS 7 SDK 中关闭 UIAlertview 后 UIView 没有响应

UILabel 未在 iOS8 中显示子视图

IAP iOS UIAlertView 取消按钮