从ViewController从UIAlertView加载xib

时间:2011-11-21 21:53:57

标签: iphone ios

在我的应用程序中,我有一个xib,它有几个viewcontrollers和xibs(有更多的viewcontrollers)。

我可以从xib转到xib并加载我想要的控制器。

我的问题是当我从我的视图控制器旁边的一个视图(在主xib或另一个上)时,我在底部有一个导航栏,标有“后面”的单个按钮。现在当这个按钮被击中之前它会让你回来它询问你是否想要发生一些事情。

当您单击“是”时,将弹出UIAlertView并告诉您在单击“确定”时要发生的事情。我知道我的按钮是通过NSLogging我的标签触发的。

但是我需要加载某个xib文件,而不是。

这是我尝试使用的代码 - 现在这个工作原理如果我想从一个按钮从xib转到xib。所以我不确定为什么它不在警报视图中工作。

- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex {
// the user clicked one of the OK/Cancel buttons
if(alert.tag==1)
{
    if (buttonIndex==0) {
        ControllPanelViewController *controllpanel = [[ControllPanelViewController alloc] initWithNibName:nil bundle:nil];
        [self presentModalViewController:controllpanel animated:YES];    
        NSLog(@"index 0");
    }
}

} enter image description here

将pic执行添加到响应中: enter image description here

3 个答案:

答案 0 :(得分:0)

您需要指定要打开的xib:

ControllPanelViewController *controllpanel = [[ControllPanelViewController alloc] initWithNibName:@"XibNameHere" bundle:nil];

答案 1 :(得分:0)

之前我遇到过类似的问题,不是使用UIViewController,而是使用UIActionSheet。当我尝试这样做时,我想根据UIAlertView的选择呈现UIActionSheet。当我在UIAlertView中按下某些内容时,该视图被取消,但我的操作表未显示。这是我的解决方案;而不是:

if(alert.tag==1) {
    if (buttonIndex==0) {
        ControllPanelViewController *controllpanel = [[ControllPanelViewController alloc] initWithNibName:nil bundle:nil];
        [self presentModalViewController:controllpanel animated:YES];    
        NSLog(@"index 0");
    }
}

尝试类似:

if(alert.tag==1)
    if (buttonIndex==0)
        [self performSelector:@selector(presentController) withObject:nil afterDelay:.1];

使用presentController方法:

ControllPanelViewController *controllpanel = [[ControllPanelViewController alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:controllpanel animated:YES];    
NSLog(@"index 0");

问题似乎是UIAlertView需要一些时间来解雇自己(非常少的时间),并且在那段时间呈现另一个视图不起作用。

另外,正如Alan Zeino所说,如果xib的名称与视图控制器的名称不同(例如,如果你有两个不同的xibs-一个用于ipad,一个用于iphone),那么你确实需要指定使用哪个。如果xib的名称与视图控制器相同,则必须指定名称。

编辑:

如果您想使用操作表并希望委托方法在触发操作时起作用,您最好将操作表的委托设置为self,并在接口文件中添加协议。

答案 2 :(得分:0)

由于您已指出您的日志语句确认正确设置委托并实施方法,因此' UIAlertView锁定屏幕'理论似乎是唯一可预期的理论。

正如Rickay所说,performSelector:AfterDelay:可能会奏效,但正如他所说的那样,需要创建第二种方法。我想说这是一个阻挡的最佳时机。

以下是两个选项:要么是复制和粘贴解决方案。

1)假设当前的主runloop只需完成它的当前调用堆栈,然后可以使用新的视图控制器:

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    if (alertView.tag == 1) {
        if (buttonIndex == 0) {
            dispatch_async(dispatch_get_main_queue(), ^{
                ControllPanelViewController *controllpanel = [[ControllPanelViewController alloc] initWithNibName:nil bundle:nil];
                [self presentModalViewController:controllpanel animated:YES]; 
            });
        }
    }
}

这将向主队列添加一个块,一旦主运行循环可用,它将创建并显示ControllPanelViewController

但是,如果这不起作用并且“只是时间问题”,则块仍然有效。像所以:

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    if (alertView.tag == 1) {
        if (buttonIndex == 0) {
            double delayInSeconds = 0.1;
            dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
            dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
                ControllPanelViewController *controllpanel = [[ControllPanelViewController alloc] initWithNibName:nil bundle:nil];
                [self presentModalViewController:controllpanel animated:YES]; 
            });
        }
    }
}

这将创建一个在指定的秒数内“触发”的块。这里设置为0.1秒。

同样,第一个是更清洁,可以说更好,更容易阅读的选项。