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

Как вернуться к корневому контроллеру, но затем нажать на другое представление?

Я пишу простое приложение, которое имеет 3 контроллера вида. Контроллер корневого представления представляет собой табличный вид item listing. Выключив этот контроллер, я нажимаю два разных контроллера представлений на основе некоторого пользовательского взаимодействия - контроллера просмотра create item или контроллера представления view item.

Итак, раскадровка segues просто выглядит как V или что-то в этом роде.

В моем диспетчере представлений create item я хотел бы, чтобы он вернулся к контроллеру корневого представления, когда пользователь создает новый элемент, но затем нажмите на контроллер view item, чтобы я мог посмотреть на вновь созданный элемент.

Я не могу заставить это работать. Достаточно легко вернуться к контроллеру корневого представления, но я не могу нажать этот контроллер view item.

Любые идеи? Я вставил свой код ниже. Поп-функция работает, но новый вид никогда не появляется.

- (void) onSave:(id)sender {

    CLLocation *currentLocation = [[LocationHelper sharedInstance] currentLocation];

    // format the thread object dictionary
    NSArray* location = @[ @(currentLocation.coordinate.latitude), @(currentLocation.coordinate.longitude) ];
    NSDictionary* thread = @{ @"title": _titleField.text, @"text": _textField.text, @"author": @"mustached-bear", @"location": location };

    // send the new thread to the api server
    [[DerpHipsterAPIClient sharedClient] postPath:@"/api/thread"
                                       parameters:thread
                                          success:^(AFHTTPRequestOperation *operation, id responseObject) {

                                              // init thread object
                                              Thread *thread = [[Thread alloc] initWithDictionary:responseObject];

                                              // init view thread controller
                                              ThreadViewController *viewThreadController = [[ThreadViewController alloc] init];
                                              viewThreadController.thread = thread;

                                              [self.navigationController popToRootViewControllerAnimated:NO];
                                              [self.navigationController pushViewController:viewThreadController animated:YES];

                                          }
                                          failure:^(AFHTTPRequestOperation *operation, NSError *error) {

                                              [self.navigationController popToRootViewControllerAnimated:YES];

                                          }];

}
4b9b3361

Ответ 1

Легкий способ выполнить то, что вы хотите сделать, - это создать простую логику в вашем основном контроллере корневых представлений - (void) viewWillAppear и использовать обратный вызов делегата для переключения логического переключателя. в основном "обратная ссылка" на корневой контроллер. вот краткий пример.

главный корневой контроллер (рассмотрим этот контроллер a) - хорошо назовите его controllerA установить свойство для отслеживания состояния перехода

@property (nonatomic) BOOL jumpNeeded;

установить некоторую логику в

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.jumpNeeded ? NSLog(@"jump needed") : NSLog(@"no jump needed");

    if (self.jumpNeeded) {
        NSLog(@"jumping");
        self.jumpNeeded = NO;
        [self performSegueWithIdentifier:@"controllerC" sender:self];
    }   
}

Теперь, в вашем основном корневом контроллере, когда выбрана строка таблицы, сделайте что-то вроде этого при нажатии на контроллер B в вашем tableView был выбран метод

[self [email protected]"controllerB" sender:self];

затем выполните вашу подготовку к методу segue

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

  //setup controller B
  if([segue.identifier isEqualTo:@"controllerB"]){
    ControllerB *b = segue.destinationViewController;
    b.delegate = self;  //note this is the back reference
  }

  //implement controller c here if needed
}

Теперь перейдите к контроллеру B вам нужно установить свойство "делегат", чтобы сохранить обратную ссылку и вам нужно импортировать файл заголовка из корневого контроллера

#import "controllerA"

@property (nonatomic,weak) controllerA *delegate;

то перед тем, как вы вернетесь к контроллеру A, вы установите флаг

   self.delegate.jumpNeeded = YES;
    [self.navigationController popViewControllerAnimated:YES];

и об этом. Вам не нужно ничего делать с контроллером. Есть еще несколько способов сделать это, но это довольно прямо для ваших нужд. надеюсь, что это сработает для вас.

Ответ 2

Если вы правильно поняли, у вас есть стек контроллеров:

A (root) - B - C - D - E

И вы хотите, чтобы это стало:

A (root) - F

Правильно? В этом случае:

NSArray *viewControllers = self.navigationController.viewControllers;
NSMutableArray *newViewControllers = [NSMutableArray array];

// preserve the root view controller
[newViewControllers addObject:[viewControllers objectAtIndex:0]];
// add the new view controller
[newViewControllers addObject:viewThreadController];
// animatedly change the navigation stack
[self.navigationController setViewControllers:newViewControllers animated:YES];

Ответ 3

Я думаю, что [self.navigationController pushViewController:viewThreadController animated:YES]; использует другой NavigationController, чем выражение перед этим. Поскольку после появления в корневом представлении Controller вы потеряете контроллер навигации, в котором находитесь. Решите, что вместо этого используйте этот код

UINavigationController *nav = self.navigationController; 
[self.navigationController popToRootViewControllerAnimated:NO];
[nav pushViewController:viewThreadController animated:YES];

Я также думаю, что это не решит вашу проблему. Вероятно, вы получите сообщение о том, что два быстрых нажатия и нажатия могут привести к аннулированию функции NavigationController.  И чтобы решить это, вы можете либо нажать на NavigationController в методе viewDidDissappear 2-го контроллера просмотра, либо нажать его в методе viewDidAppear в главном контроллере просмотра (список элементов).

Ответ 4

Обмен категорией в UINavigationController на основе ответа Dave DeLong, который мы используем в нашем приложении, чтобы поддерживать обратную кнопку, всегда работая по мере необходимости.

@implementation UINavigationController (PushNewAndClearNavigationStackToParent)

- (void) pushNewControllerAndClearStackToParent:(UIViewController*)newCont animated:(BOOL)animated
{
    NSArray *viewControllers = self.viewControllers;
    NSMutableArray *newViewControllers = [NSMutableArray array];
    
    // preserve the root view controller
    [newViewControllers addObject:[viewControllers firstObject]];
    // add the new view controller
    [newViewControllers addObject:newCont];
    // animatedly change the navigation stack
    [self setViewControllers:newViewControllers animated:animated];
}

@end

Ответ 5

NSArray *viewControllers = self.navigationController.viewControllers;
NSMutableArray *newViewControllers = [NSMutableArray array];

// preserve the root view controller
for(int i = 0; i < [viewControllers count];i++){
    if(i != [viewControllers count]-1)
        [newViewControllers addObject:[viewControllers objectAtIndex:i]];
}
// add the new view controller
[newViewControllers addObject:conversationViewController];
// animatedly change the navigation stack
[self.navigationController setViewControllers:newViewControllers animated:YES];

Ответ 6

Я не думаю, что это возможно, потому что popping назад освободит все.

Я думаю, что лучший способ - поместить ваши данные в модельный одноэлементный класс, поп-серверу rootviewcontroller и послушать поп-конец. Затем вы проверяете, есть ли какие-то данные, хранящиеся на модели, чтобы вы знали, нужно ли вы нажимать новый диспетчер представлений.

Ответ 7

Я использовал Дэйв в качестве вдохновения и сделал это для Свифта:

let newViewControllers = NSMutableArray()
newViewControllers.addObject(HomeViewController())
newViewControllers.addObject(GroupViewController())
let swiftArray = NSArray(array:newViewControllers) as! Array<UIViewController>
self.navigationController?.setViewControllers(swiftArray, animated: true)
  • Замените HomeViewController() тем, что вы хотите, чтобы ваш контроллер нижнего представления был
  • Замените GroupViewController() тем, что вы хотите, чтобы ваш контроллер верхнего уровня был

Ответ 8

Если то, что вы хотите сделать, это каким-либо образом перемещаться внутри одного и того же навигационного контроллера... вы можете получить доступ к navigationStack A.K.A. viewControllers, а затем установите viewcontrollers в том порядке, который вы хотите, или добавьте или удалите некоторые... Это самый чистый и естественный способ сделать это.

        UINavigationController* theNav = viewControllerToDismiss.navigationController;
        UIViewController* theNewController = [UIViewController new];
        UIViewController* rootView = theNav.viewControllers[0];
        [theNav setViewControllers:@[
                                     rootView,
                                     theNewController
                                     ] animated:YES];

выполните необходимые проверки, чтобы вы не получили никаких исключений.