将UIWebview呈现在当前显示的视图控制器之上

3

我想以模态的方式在当前显示的视图控制器上方显示一个UIWebview。弹出webview的代码位于静态库中,不知道它所在的应用程序的视图控制器层次结构。下面的代码适用于我的测试案例,但不确定是否适用于所有可能的视图控制器层次结构。

UIViewController *rootViewController = [[[UIApplication sharedApplication] keyWindow] rootViewController];
UIViewController *presentedVC = [rootViewController presentedViewController];
if (presentedVC) {
    // We have a modally displayed viewcontroller on top of rootViewController.
    if (!presentedVC.isBeingPresented) {
    [presentedVC presentViewController:vc animated:YES completion:^{
        //
    }];
} else {
    rootViewController presentViewController:vc animated:YES completion:^{
        //
    }];
}

presentedViewController是否总是给出当前可见的视图控制器?


嗯,如果这个能行我会很惊讶。除非我疯了,keyWindow返回的是最后一次调用makeKeyAndVisisble的当前可见窗口。要获取当前呈现的视图控制器,这完全取决于你的层次结构。如果你有一个模态屏幕,那就是它了;如果没有,并且你有导航控制器作为根,你就必须查看堆栈的顶部。我认为,鉴于设置导航层的方式有很多种,找到顶部视图控制器可能会相当困难。 - feliun
1
我认为你会想把当前视图控制器作为属性传递给你的库。 - Marcus Adams
@MarcusAdams 这绝对是一种选择,但我试图让开发人员使用静态库更加透明。 - pshah
@feliun 我添加了一个检查,以确保presentedVC不为空。如果在rootViewController上没有模态显示的视图控制器,则presentedVC似乎始终为空。 - pshah
1个回答

2
如果您想在应用程序中显示UIWebView,并以模态方式覆盖当前显示的任何视图控制器,则不需要"最顶层"视图控制器。 获取根视图控制器就足够了。每当我想要在所有其他内容上方呈现视图时,我都会这样做。在库中,您只需要对根视图控制器进行引用。
self.rootVC = [[[[UIApplication sharedApplication] delegate] window] rootViewController];

现在你有两个选择:

第一个选择是使用UIViewController的方法presentViewController:animated:completion:来显示另一个视图控制器,该视图控制器将包含你的UIWebView

第二个选择是通过添加一个子视图来伪造模态视图控制器,该子视图覆盖整个屏幕,具有(半)透明背景,并包含你想要“模态”显示的视图。以下是一个示例:

@interface FakeModalView : UIView // the *.h file

@property (nonatomic, retain) UIWebView *webView;
@property (nonatomic, retain) UIView *background; // this will cover the entire screen

-(void)show; // this will show the fake modal view
-(void)close; // this will close the fake modal view

@end

@interface FakeModalView () // the *.m file

@property (nonatomic, retain) UIViewController *rootVC; 

@end

@implementation FakeViewController
@synthesize webView = _webView;
@synthesize background = _background;
@synthesize rootVC = _rootVC;

-(id)init {
    self = [super init];
    if (self) {

        [self setBackgroundColor: [UIColor clearColor]]; 
        _rootVC = self.rootVC = [[[[[UIApplication sharedApplication] delegate] window] rootViewController] retain];
        self.frame = _rootVC.view.bounds; // to make this view the same size as the application

        _background = [[UIView alloc] initWithFrame:self.bounds];
        [_background setBackgroundColor:[UIColor blackColor]];
        [_background setOpaque:NO];
        [_background setAlpha:0.7]; // make the background semi-transparent

        _webView = [[UIWebView alloc] initWithFrame:CGRectMake(THE_POSITION_YOU_WANT_IT_IN)];

        [self addSubview:_background]; // add the background
        [self addSubview:_webView]; // add the web view on top of it
    }
    return self;
}

-(void)dealloc { // remember to release everything

    [_webView release];
    [_background release];
    [_rootVC release];

    [super dealloc];
}

-(void)show {

    [self.rootVC.view addSubview:self]; // show the fake modal view
}

-(void)close {

    [self removeFromSuperview]; // hide the fake modal view
}

@end

如果您有其他问题,请告诉我。希望这能帮到您!

1
第一种选项(使用rootViewController)不起作用,因为您可能已经有一个视图控制器在rootViewController之上以模态方式显示。我最初采用了这种方法,并针对我上述描述的情况收到了此警告:<PopupViewController:0x7ce37a0>在<MyRootViewController:0x798e050>上,其视图不在窗口层次结构中! - pshah
我会尝试第二个选项并告诉你。 - pshah

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