iOS 7中UIAlertView的按钮(子视图)没有显示

5

以下是用于iOS 6的代码,UIAlertView可以正常工作。但是,当我们使用iOS 7时,子视图(即我的代码中的“yes”和“no”按钮)在调用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;


  }

3
UIAlertView的视图层次结构长期以来一直是私有的。自iOS7起,苹果公司开始强制执行此规定。您无法操纵视图层次结构,而必须创建一个UIView子类来模仿UIAlertView。 - Matthias Bauch
@MatthiasBauch,你能用编程代码回答吗?例如如何创建并添加UIView到UIAlertView中。 - lreddy
1
你不能将视图添加到UIAlertView中。你需要子类化UIView并使其看起来像UIAlertView。查看cocoapods以获取符合你需求的类。 - Matthias Bauch
3个回答

1

当UIAlertView被呈现时,我们可以通过将子视图添加到presentedViewController的视图中来向其添加子视图。我已经按照以下方式访问了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 方法中,我通过访问显示的视图控制器的视图,向 UIAlertView 添加了子视图。
您可以在 这里 找到关于此的解释和代码示例。

1
我认为iOS7问题的根源在于苹果改变了UIAlertView的外观机制。从现在开始,任何alertView的显示都是在初始化两个私有视图控制器之后进行的。
_UIModalItemAppViewController
_UIModalItemsPresentingViewController

换句话说,现在UIAlertView不再是一个纯视图 - 它是一些复杂的视图控制器集合的一部分,并具有完整的视图控制器生命周期。
但好消息是,在标准警报视图中,您可以将accessoryView更改为自定义的customContentView。
[alertView setValue:customContentView forKey:@"accessoryView"];

请注意,在调用 [alertView show] 之前必须调用此方法。

1
你一直在做错误的事情。不允许将自己的子视图添加到UIAlertView中。好消息是 - 在iOS 7中,您不必这样做!新的自定义转换动画机制可以让您创建自己的视图,它的行为就像警报视图一样,但由于它是您的视图,您可以将任何您喜欢的东西放入其中,如下所示:

enter image description here

注意右侧屏幕截图中假的“警报视图”如何浮在原始视图前面,并使其背后的屏幕变暗,就像真正的警报视图一样。但它完全由自定义内容组成;“真正的”警报视图永远不可能包含图像和开关!
有关创建此视图的代码(您可以轻松地适应自己的目的),请参见我的github网站:https://github.com/mattneub/custom-alert-view-iOS7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接