Кнопка Назад не отображается на панели навигации, пока вы не поверните - PullRequest
7 голосов
/ 22 октября 2011

У меня есть три контроллера вида: A -> B -> C, управляемый контроллером навигации. A - это контроллер переходных процессов. Он просит у сервера что-то. Если сервер говорит, что все в порядке, то A помещает B в стек. B должен скрыть кнопку возврата, потому что я не хочу, чтобы пользователи вручную возвращались к A.

// B view controller
- (void)viewDidLoad 
{
    [super viewDidLoad];
    self.navigationItem.hidesBackButton = YES;
    self.title = @"B";
}

B затем помещает C в стек, когда пользователь касается ячейки таблицы.

// B view controller
- (void)tableView:(UITableView *)tableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    C *c = [[C alloc] 
        initWithStyle:UITableViewStyleGrouped
    ];
    [self.navigationController 
        pushViewController:c 
        animated:YES
    ];
    [c release];
}

.

// C view controller
- (void) viewDidLoad
{
    [super viewDidLoad];
    self.navigationItem.hidesBackButton = NO;
    self.title = @"C";
}

Если все пойдет хорошо, поток должен выглядеть следующим образом:

-------------    -------------    -------------
|_____A_____|    |_____B ____|    | <B|__ C___|
|           | => |           | => |           |
| loading...|    |   cells   |    |   detail  |
|           |    |           |    |           |
-------------    -------------     -----------

По какой-то причине C не отображает кнопку возврата для возврата к B , пока я не поверну устройство. После поворота кнопка «Назад» появляется во всех направлениях. Кажется, проблема в том, что B скрывает кнопку «назад» и C пытается открыть ее снова, потому что если я не позволю B скрыть ее, у меня нет этой проблемы. Так как же заставить C показать кнопку «назад», не заставляя пользователя поворачивать устройство как обезьяна?

Обновление

  • Сломано на двух разных Verizon iPhone 4, оба на iOS 4.2.10
  • Прекрасно на AT & T iPhone 3GS на iOS 5.0
  • Отлично на AT & T iPhone 4 на iOS 4.3

Ответы [ 6 ]

4 голосов
/ 26 октября 2011

После некоторых поисков я нашел это решение для iPhone 4.2 (поскольку вы сообщили, что оно работает в более поздних версиях) в каком-то старом сообщении на форуме.

-(void)viewDidLoad { 
                     [super viewDidLoad];
                     self.navigationItem.hidesBackButton = YES; 
                   }

-(void)viewDidAppear:(BOOL)animated { 
                                       [super viewDidAppear:animated];
                                       self.navigationItem.hidesBackButton = NO; 
                                    }

Может, это тебе поможет. (Проверьте это: Кнопка «Назад» не отображается в навигационном контроллере )

1 голос
/ 22 октября 2011

Я думаю, вы должны поместить свой код, как это для C

-(void)viewDidAppear:(BOOL)animated {
      [super viewDidAppear:animated];
      self.navigationItem.hidesBackButton = NO;
}
0 голосов
/ 25 октября 2011

Не уверен, сработает ли это в вашей ситуации с кнопкой «Назад», но я знаю, что когда я использую пользовательскую кнопку «Назад», мне нужно установить пользовательскую кнопку «Назад» в элементе alloc'd, прежде чем я нажму на нее (а не на себя, как в предыдущем посте).Надеюсь, это сработает и в вашей ситуации - стоит попробовать.

Другими словами, попробуйте:

// B view controller
- (void)tableView:(UITableView *)tableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    C *c = [[C alloc] 
        initWithStyle:UITableViewStyleGrouped];

    // *** set on c's navigationItem (not self) before you push
    [[c navigationItem] setHidesBackButton: NO];

    [self.navigationController 
        pushViewController:c 
        animated:YES
    ];

    [c release];
}
0 голосов
/ 25 октября 2011

Попробуйте добавить это в свой класс C:

-(id) init
 {
   [super init];
   self.navigationItem.hidesBackButton = NO;
 }
0 голосов
/ 25 октября 2011

Попробуйте вставить self.navigationItem.hidesBackButton = NO; в метод init или в любое место перед вызовом pushViewController.

ViewDidLoad вызывается, когда вы впервые запрашиваете у контроллера представление, это означает, что оно, вероятно, вызывается из[self.navigationController pushViewController:c animated:YES].Но обратите внимание, что панель навигации не является частью вашего представления, она создается и обрабатывается UINavigationController, поэтому в принципе она может существовать и рисоваться даже до вызова viewDidLoad и viewDidAppear.Если вы обновите там панель навигации, она фактически не будет перекрашена.

Редактировать 1: Пересматривается после прочтения документации для [UIViewController navigationItem]

Следует избегать связывания создания панеликнопки элементов в вашем элементе навигации для создания представления вашего контроллера представления.Элемент навигации контроллера представления может быть извлечен независимо от представления контроллера представления.Например, при перемещении двух контроллеров представления в стек навигации самый верхний контроллер представления становится видимым, но элемент навигации другого контроллера представления может быть извлечен для представления его кнопки «назад».Чтобы убедиться, что элемент навигации настроен, вы можете переопределить это свойство и добавить код для загрузки там элементов панели кнопок или загрузки элементов в код инициализации контроллера представления.

Редактировать 2: Повторно посещено после прочтениякомментарий, что мое решение не работает.Рабочий код (iOS 5, ARC):


//
//  TestAppDelegate.m
//  NavigationTest
//
//  Created by Sulthan on 10/25/11.
//  Copyright (c) 2011 StackOverflow. All rights reserved.
//

#import "TestAppDelegate.h"

@interface TestAppDelegate ()

@property (nonatomic, strong, readwrite) UINavigationController* navigationScreen;

@property (nonatomic, strong, readwrite) UIViewController* screen1;
@property (nonatomic, strong, readwrite) UIViewController* screen2;
@property (nonatomic, strong, readwrite) UIViewController* screen3;

@end

@implementation TestAppDelegate

@synthesize window = window_;
@synthesize navigationScreen = navigationScreen_;
@synthesize screen1 = screen1_;
@synthesize screen2 = screen2_;
@synthesize screen3 = screen3_;

- (UIViewController*)createTestScreenWithLabel:(NSString*)label {
    CGRect bounds = [[UIScreen mainScreen] bounds];

    UIViewController* screen = [[UIViewController alloc] init];
    screen.view = [[UILabel alloc] initWithFrame:bounds];
    screen.view.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);

    ((UILabel*) screen.view).textAlignment = UITextAlignmentCenter;
    ((UILabel*) screen.view).text = label;

    return screen;
}

- (void)pushThirdScreen {
    if (!self.screen3) {
        self.screen3 = [self createTestScreenWithLabel:@"Screen 3"];
        self.screen3.navigationItem.hidesBackButton = NO;
    }

    [self.navigationScreen pushViewController:self.screen3 animated:YES];
}

- (void)pushSecondScreen {
    self.screen2 = [self createTestScreenWithLabel:@"Screen 2"];
    self.screen2.navigationItem.hidesBackButton = YES;

    UIBarButtonItem* button = [[UIBarButtonItem alloc] initWithTitle:@"Go"
                                                               style:UIBarButtonItemStyleBordered
                                                              target:self
                                                              action:@selector(pushThirdScreen)];

    self.screen2.navigationItem.rightBarButtonItem = button;

    [self.navigationScreen pushViewController:self.screen2 animated:YES];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    CGRect bounds = [[UIScreen mainScreen] bounds];

    self.screen1 = [self createTestScreenWithLabel:@"Screen 1"];

    self.navigationScreen = [[UINavigationController alloc] initWithRootViewController:self.screen1];

    self.window = [[UIWindow alloc] initWithFrame:bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window addSubview:self.navigationScreen.view];

    [self.window makeKeyAndVisible];

    [self performSelector:@selector(pushSecondScreen) withObject:nil afterDelay:3.0];

    return YES;
}

@end

Редактировать 3: Пересмотрен после того, как вы заметили, что вы говорите в основном об iOS 4.2.В настоящее время я не могу проверить это на любой iOS 4.2, но я знаю о возможном обходном пути.Вы всегда можете скрыть панель навигации в вашем UINavigationController и просто разместить отдельную панель навигации на каждом экране.Вы будете иметь абсолютный контроль над ними, и вы даже можете редактировать их в Интерфейсном Разработчике.

0 голосов
/ 22 октября 2011

Однажды у меня возникла эта проблема, и я решил ее, присвоив элементу навигации B заголовок

// B view controller
- (void)viewDidLoad 
{
    [super viewDidLoad];
    self.navigationItem.hidesBackButton = YES;
    self.navigationItem.title = @"What you want C's back button to say";
    self.title = @"B";
}

Если вы не хотите, чтобы заголовок появлялся в B, вы можете установить titleView элемента навигации B в пустом виде.О свойстве titleView:

Если значение этого свойства равно nil, заголовок элемента навигации отображается в центре панели навигации, когда получатель является верхним элементом.Если вы установите для этого свойства пользовательский заголовок, он будет отображаться вместо заголовка.Это свойство игнорируется, если значение leftBarButtonItem не равно nil.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...