ios 解雇视图控制器:不工作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12649834/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:30:05  来源:igfitidea点击:

dismissViewController: not working

iphoneobjective-ciosxcodeviewcontroller

提问by MCKapur

I have a view controller called vc0 which is presented like this:

我有一个名为 vc0 的视图控制器,如下所示:

[self presentViewController: vc1 animated: YES completion: nil];

And in vc1 I have a button to present another view controller:

在 vc1 中,我有一个按钮可以显示另一个视图控制器:

[self presentViewController: vc2 animated: YES completion: nil];

Then in vc2, I have a button to dismiss the view controller:

然后在 vc2 中,我有一个按钮来关闭视图控制器:

[self dismissViewControllerAnimated:YES completion: ^{
// over here I call one method in vc1
}

And as expected it returns back to vc1.. however there is a button in vc1 to go back to vc0 by dismissing the view controller like this:

正如预期的那样,它返回到 vc1 .. 但是,在 vc1 中有一个按钮可以通过关闭视图控制器返回到 vc0,如下所示:

    [self dismissViewControllerAnimated:YES completion:nil];

But for some reason it doesn't work, the view controller does not get dismissed back to vc0. When I first present vc1, I can press the button to dismiss the view controller and it works. But when I press the button to open vc2, and when I dismiss vc2 back to vc1, and THEN I press the button to dismiss the view controller, that is when it doesn't work.

但是由于某种原因它不起作用,视图控制器不会被解散回 vc0。当我第一次展示 vc1 时,我可以按下按钮来关闭视图控制器并且它可以工作。但是当我按下按钮打开 vc2,当我关闭 vc2 回到 vc1,然后我按下按钮关闭视图控制器时,那就是它不起作用的时候。

Sorry if the question is a bit unclear, it is a bit hard to phrase what I am trying to say.

对不起,如果问题有点不清楚,我想表达的意思有点难以表达。

Also one more thing:

还有一件事:

I tried replacing dismissViewControllerAnimated:in vc1 to manually present vc0, but then I get a log in the console saying that I am trying to present a vc0 but vc1's view is not in the window hierarchy. What does this mean?

我尝试dismissViewControllerAnimated:在 vc1 中替换以手动呈现 vc0,但随后我在控制台中收到一条日志,说我正在尝试呈现 vc0 但 vc1 的视图不在窗口层次结构中。这是什么意思?

Thanks for help!

感谢帮助!

UPDATE:

更新:

IN THIS CASE VC0 IS MenuMileIndexViewController- VC1 IS FlightViewController- VC2 IS BookmarksTableViewController

在这种情况下,VC0 IS MenuMileIndexViewController- VC1 IS FlightViewController- VC2 ISBookmarksTableViewController

Here is code involved:

这是涉及的代码:

MenuMileIndexViewController:

MenuMileIndexViewController:

- (IBAction)goToOriginPage {

FlightRecorder *origin = [[FlightRecorder alloc] init];
[self presentViewController:origin animated:YES completion:nil];

}

Flight Recorder:

飞行记录器:

    - (void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar {

        [self bringUpBookmarkkTable];
}

- (void) bringUpBookmarkkTable {

    BookmarkTableViewController *bookmarkTVC = [[BookmarkTableViewController alloc] init];

    [bookmarkTVC setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal];

    [self presentViewController:bookmarkTVC animated:YES completion:nil];
}

- (IBAction)cancel {

[self dismissViewControllerAnimated:YES completion:nil];

}

- (void)endBookmarkProcessWithBookmarkCollection: (NSDictionary *)dict {

    presetBookmarkContext = [dict mutableCopy];

    bookmarkMode = YES;

    NSString *compiledText = nil;

    NSNumber *number1 = [NSNumber numberWithInt: 1];

    if ([dict objectForKey: @"bookmarkTag"] == number1) {

        compiledText = [NSString stringWithFormat: @"%@ to %@", [dict objectForKey: @"origin"], [dict objectForKey: @"destination"]];
    }
    else {

        compiledText = [NSString stringWithFormat: @"%@ to %@", [dict objectForKey: @"destination"], [dict objectForKey: @"origin"]];
    }

    compiledText = [compiledText stringByReplacingOccurrencesOfString:@"Origin: " withString:@""];

    compiledText = [compiledText stringByReplacingOccurrencesOfString:@"Destination: " withString:@""];

    flightContext = [NSDictionary dictionaryWithObjectsAndKeys: [dict objectForKey: @"miles"], @"miles", compiledText, @"location", [[NSUserDefaults standardUserDefaults] objectForKey: @"tempD"], @"date", nil];

    NSString *string = [NSString stringWithFormat: @"\nMiles: %.2f\nFlight: %@\nDate: %@", [[dict objectForKey: @"miles"] floatValue], compiledText, [[NSUserDefaults standardUserDefaults] objectForKey:@"tempD"]];

    UIAlertView *bvkBookmarkAlertView = [[UIAlertView alloc] initWithTitle:@"Confirmation" message:string delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Add", nil];

    [bvkBookmarkAlertView show];
}



 - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {

    if (buttonIndex == 1) {

        [self cancel]; // Even though cancel is an IBAction, IBAction is the same thing as void so it is callable
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {

    if (buttonIndex == 1) {

        [TheMileIndexViewController addDesiredMilesToIndex: [[flightContext objectForKey: @"miles"] doubleValue]];

        [TravelLogViewController addFlight: flightContext];

        if (!bookmarkMode) {

            if ([checkbox isSelected]) {

                [BookmarkHandler uploadBookmark: bookmarkFlightContext];
            }    
        }
    }

    if (buttonIndex == 0) {

        if ([alertView.title isEqualToString: @"Confirmation"]) {

            bookmarkMode = NO;
        }
    }

}

BookmarksTableViewController:

书签TableViewController:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    [tableView deselectRowAtIndexPath:indexPath animated: YES];

    NSDictionary *dict = [[BookmarkHandler bookmarkCollection] objectAtIndex: indexPath.row];

    fl = [[FlightRecorder alloc] init];

    [self dismissViewControllerAnimated:YES completion:^{

        [fl endBookmarkProcessWithBookmarkCollection: dict];
    }];
}

NOW, I have created a screen recording of the app in simulator showing what is the problem. I can email that to you for reference. So I can email that to you.

现在,我在模拟器中创建了应用程序的屏幕录制,显示了问题所在。我可以发邮件给你参考。所以我可以通过电子邮件将其发送给您。

采纳答案by user387184

I would recommend to always dismiss a VC from the VC that actually presented it - using a delegate. This is actually also the Apple recommended way - as was pointed out in a previous answer to my question regarding this issue.

我建议始终从实际呈现它的 VC 中解散 VC - 使用委托。这实际上也是 Apple 推荐的方式——正如我之前对我关于这个问题的问题的回答中所指出的那样。

So if you have VC0 presenting VC1, have the dismiss VC1 code in VC0 too, using delegate scheme.

因此,如果您让 VC0 呈现 VC1,请使用委托方案在 VC0 中也使用解除 VC1 代码。

I have learned that this is the savest way to handle presenting and dismissing - even though sometimes it works to dismiss VC1 within VC1 itself.

我了解到这是处理呈现和关闭的最省钱的方法 - 即使有时它可以在 VC1 本身中关闭 VC1。

I have asked a very related question, you might be interested to check this too. It shows the code...

我问了一个非常相关的问题,你可能也有兴趣检查一下。它显示了代码...

ps I also read that some dismiss only VC1 - which in turn will also dismiss VC2. However, if my previous suggestion works, I would not do this. Sometimes I get information during execution (no crash) that the VC does not exist anymore or anything related to that - so I assumed this is not the best solution. But if my prvious suggestion does not work, you may try the second one.

ps 我还读到有些人只解雇 VC1 - 这反过来也会解雇 VC2。但是,如果我之前的建议有效,我就不会这样做。有时我在执行过程中(没有崩溃)得到 VC 不存在或任何与此相关的信息 - 所以我认为这不是最好的解决方案。但是,如果我之前的建议不起作用,您可以尝试第二个。

Though no guarantee that this will last the updates to new iOS, since this issue keeps hauting me for several iOS updates now :-), so I decided to go the standard recommended route.

虽然不能保证这会持续更新到新的 iOS,因为这个问题现在一直困扰着我进行几个 iOS 更新:-),所以我决定走标准的推荐路线。

EDIT: This is my modified code - it works without problems - however it is not clear what you intend to happen AFTER the user reponds to the Alert and whether the Alert should be on VC1 or VC0. Anyway using delegate and callbacks I do not see any issue. Please explain should I have missed your point...

编辑:这是我修改后的代码 - 它可以正常工作 - 但是不清楚在用户回复警报后您打算发生什么以及警报应该在 VC1 还是 VC0 上。无论如何使用委托和回调我没有看到任何问题。如果我错过了你的观点,请解释一下......

FlightViewControllerProtocol.h

FlightViewControllerProtocol.h

@protocol FlightViewControllerProtocol <NSObject>
-(void) dismissVCAndEndBookmark;
@end

FlightViewController.m

FlightViewController.m

#import "FlightViewController.h"
#import "FlightViewControllerProtocol.h"
#import "BookmarksTableViewController.h"
@interface FlightViewController ()

@end

@implementation FlightViewController
@synthesize delegate;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar {

    [self bringUpBookmarkkTable];
}

- (IBAction) bringUpBookmarkkTable {

    BookmarksTableViewController *bookmarkTVC = [[BookmarksTableViewController alloc] init];
    bookmarkTVC.delegate = self;
    [bookmarkTVC setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal];

    [self presentViewController:bookmarkTVC animated:YES completion:nil];
}

- (IBAction)cancel {

    [self dismissViewControllerAnimated:YES completion:nil];

}

- (void)endBookmarkProcessWithBookmarkCollection: (NSDictionary *)dict {

//    presetBookmarkContext = [dict mutableCopy];

//    bookmarkMode = YES;

    NSString *compiledText = nil;

    NSNumber *number1 = [NSNumber numberWithInt: 1];

    if ([dict objectForKey: @"bookmarkTag"] == number1) {

        compiledText = @"Text1";
    }
    else {
        compiledText = @"Text2";
    }


//    flightContext = [NSDictionary dictionaryWithObjectsAndKeys: [dict objectForKey: @"miles"], @"miles", compiledText, @"location", [[NSUserDefaults standardUserDefaults] objectForKey: @"tempD"], @"date", nil];

    NSString *string = compiledText;

    UIAlertView *bvkBookmarkAlertView = [[UIAlertView alloc] initWithTitle:@"Confirmation" message:string delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Add", nil];

    [bvkBookmarkAlertView show];
}


- (void) dismissVCAndEndBookmark {
    [self dismissViewControllerAnimated:YES completion:nil];
     [self endBookmarkProcessWithBookmarkCollection: nil];
}

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {

    if (buttonIndex == 1) {

        [self cancel]; // Even though cancel is an IBAction, IBAction is the same thing as void so it is callable
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {

    if (buttonIndex == 1) {

        NSLog(@"alertView1");
           }

    if (buttonIndex == 0) {
        NSLog(@"alertView2");

    }

}

@end

BookmarksTableViewController.h

书签TableViewController.h

 @interface BookmarksTableViewController : UIViewController
{
    id delegate;
}

@property (nonatomic,strong)   id delegate;

@end

BookmarksTableViewController.m

书签TableViewController.m

- (IBAction)goBack {
    [self.delegate dismissVCAndEndBookmark];
}

Esp the callback in BookmarksTableViewController.m seems to be the main issue in your implementation if I understood your intentions correctly.

如果我正确理解了您的意图,则尤其是 BookmarksTableViewController.m 中的回调似乎是您实现中的主要问题。

回答by RayInNoIL

[self.navigationController popViewControllerAnimated:YES];

did the trick for me also. In my case, I had a (iPhone) viewController that was pushed on to the stack using a push segue. Since the viewController that was initiating the segue had a navigation bar, I had to send the parent controller's navigationController the popViewControllerAnimated message instead of calling it's own dismissViewControllerAnimated:completion message.

也对我有用。在我的例子中,我有一个(iPhone)viewController,它使用 push segue 推送到堆栈中。由于启动 segue 的 viewController 有一个导航栏,我不得不向父控制器的 navigationController 发送 popViewControllerAnimated 消息,而不是调用它自己的dismissViewControllerAnimated:completion 消息。

Ray

射线

回答by user1573162

First View:

第一个观点:

Firstly embed in navigation controller in first view. and use this code to navigate to another view

首先在第一个视图中嵌入导航控制器。并使用此代码导航到另一个视图

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle: nil]; 
FirstView *rvc = [storyboard instantiateViewControllerWithIdentifier:@"apps"];
[self.navigationController pushViewController:rvc animated:YES];

Second view:

第二种观点:

Add this line in the method for dismiss view

在关闭视图的方法中添加这一行

- (IBAction)back{
    [self.navigationController popViewControllerAnimated:YES];
}