Подтвердить что ты не робот

Как удалить предыдущий ViewController

Я студент и довольно новичок в программировании. Я пытаюсь научиться Objective-C/Swift в свободное время. Я сделал игру, используя spriteKit с быстрым, который имеет несколько меню/сцен.

Я пытаюсь перейти от одного контроллера представления к другому. Для этого я использовал этот код:

@IBAction func PlayButtonPressed(sender: AnyObject) {
    let playStoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let vc : UIViewController = playStoryboard.instantiateViewControllerWithIdentifier("playGame") as UIViewController
    self.presentViewController(vc, animated: true, completion: nil)
}

Это работает для перехода на новую сцену VC, однако, я считаю, что предыдущий VC все еще находится в стеке и занимает память, замедляя мою программу.

Я прочитал несколько других сообщений, которые вы можете использовать навигационным контроллером для удаления VC. Однако у меня нет контроллера навигации; только контроллеры просмотра. Я видел кое-что о removeFromParentViewController() и view.removeFromSuperview(), но я действительно не знаю, как его реализовать. Кроме этого, я не нашел ответа, который я искал.

Итак, вопрос, который я задаю, заключается в том, как удалить предыдущий VC из стека? Любая помощь будет оценена! (предпочел бы, чтобы помощь была быстрой, но Objective-C тоже помогла бы). Спасибо заранее!

Примечание для справки: Я верю в Objective-C, мой код будет выглядеть примерно так:

-(IBAction) PlayButtonPressed: (id) sender {
    UIStoryboard *playStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    UIViewController *vc = [playStoryboard instantiateViewControllerWithIdentifier:@"playGame"];
    [self presentViewController:vc animated:YES completion:nil];
}
4b9b3361

Ответ 1

Как я могу предположить, просмотр контроллера, представленного на экране, был создан автоматически из основной раскадровки или путем установки свойства app window.rootViewController.

В любом случае вы можете снова установить rootViewController в качестве vc. Чтобы изменить rootViewController вашего приложения, вам нужно заменить эту строку кода:

self.presentViewController(vc, animated: true, completion: nil)

... с одним из вариантов ниже.

"Навигация" без анимации перехода:

Objective-C

UIWindow *window = (UIWindow *)[[UIApplication sharedApplication].windows firstObject];
window.rootViewController = vc;

Swift

let window = UIApplication.sharedApplication().windows[0] as UIWindow;
window.rootViewController = vc;

"Навигация" с анимацией перехода:

Objective-C

UIWindow *window = (UIWindow *)[[UIApplication sharedApplication].windows firstObject];
[UIView transitionFromView:window.rootViewController.view
                    toView:vc.view
                  duration:0.65f
                   options:UIViewAnimationOptionTransitionCrossDissolve // transition animation
                completion:^(BOOL finished){
                    window.rootViewController = vc;
                }];

Swift

let window = UIApplication.sharedApplication().windows[0] as UIWindow;
UIView.transitionFromView(
    window.rootViewController.view,
    toView: vc.view,
    duration: 0.65,
    options: .TransitionCrossDissolve,
    completion: {
        finished in window.rootViewController = vc
    })

Примечания: После того как значение rootViewController изменится, исходный счетчик ссылок на просмотр должен стать 0, поэтому он будет удален из памяти!

Ответ 2

Я предполагаю, что лучшая реализация заключается в размещении на предыдущем контроллере View следующего: Swift

    // Override to remove this view from the navigation stack
    override func viewDidDisappear(animated: Bool) {
        super.viewDidDisappear(animated)
        // Remove self from navigation hierarchy
        guard let viewControllers = navigationController?.viewControllers,
            let index = viewControllers.indexOf(self) else { return }
        navigationController?.viewControllers.removeAtIndex(index)
    }

Ответ 3

Прежде всего, вы используете шаблон модального представления, а не шаблон навигационного стека (UINavigationController). Вы не можете избавиться от контроллера представления представления, а также не должны, поскольку это приведет к поломке навигации.

Короткий ответ здесь заключается в том, что вам не нужно беспокоиться об этом. Объем памяти, который сам сам контроллер просмотра занимает тривиальным образом, будет выпущен автоматически, если на нем больше нет ссылок (вы его отклоните или вытащите из стека навигации).

Более длительный ответ будет зависеть от вашей конкретной реализации. Если вы каким-то образом находитесь в ситуации, когда вы бесконечно увеличиваете размер стека, это проблема. Например, если у вас есть поток навигации, где вы можете свободно перемещаться между двумя "экранами", но внутри каждый экран продолжает представлять новый, а не просто переключается на существующий. Если вы испытываете что-то вроде этого, тогда вам лучше всего будет использовать UITabBarController или что-то подобное, где вы можете перемещаться по бокам между контроллерами представления без создания новых.

Ответ 4

Для быстрого 3 вы можете заменить

self.present(ViewController(), animated: false, completion: nil);

с

if let window = UIApplication.shared.keyWindow{
            window.rootViewController = UINavigationController(rootViewController: ViewController());
        }