iPhone - backBarButtonItem 为零并且触摸时不突出显示

发布于 2024-10-23 20:48:38 字数 1055 浏览 7 评论 0原文

我有一个全屏 modalView 调用:

PreferencesController *nextWindow = [[[PreferencesController alloc] initWithNibName:@"Preferences" bundle:nil] autorelease];
UINavigationController* navController = [[[UINavigationController alloc] initWithRootViewController:nextWindow] autorelease];
[self presentModalViewController:navController animated:YES];

然后从这个 modalView 推送另一个视图:

MyController *nextWindow = [[[MyController alloc] initWithNibName:@"tmp" bundle:nil] autorelease];
[self.navigationController pushViewController:nextWindow animated:YES];

在这个新控制器中,我有这个 viewDidLoad :

- (void)viewDidLoad {
    [super viewDidLoad];

    self.title = @"Borders";
    self.navigationController.navigationBarHidden = NO;
}

这样做, backBarButtonItem 不活动,我的意思是触摸它不会突出显示它也不会返回到之前的视图。

事实上, self.navigationController.navigationItem.backBarButtonItem 是 NIL。
self.navigationController.navigationItem 不是 NIL
调用者的 self.navigationController 和被调用视图内部具有相同的引用。

问题是什么 ?

I have a fullscreen modalView called with :

PreferencesController *nextWindow = [[[PreferencesController alloc] initWithNibName:@"Preferences" bundle:nil] autorelease];
UINavigationController* navController = [[[UINavigationController alloc] initWithRootViewController:nextWindow] autorelease];
[self presentModalViewController:navController animated:YES];

Then from this modalView I push another view :

MyController *nextWindow = [[[MyController alloc] initWithNibName:@"tmp" bundle:nil] autorelease];
[self.navigationController pushViewController:nextWindow animated:YES];

In this new controller, I have this viewDidLoad :

- (void)viewDidLoad {
    [super viewDidLoad];

    self.title = @"Borders";
    self.navigationController.navigationBarHidden = NO;
}

Doing like this, the backBarButtonItem is not active, I mean touching it does not highlight it nor goes back to the previous view.

In fact, self.navigationController.navigationItem.backBarButtonItem is NIL.
self.navigationController.navigationItem is not NIL
self.navigationController for caller and inside called view have the same reference.

What is the problem ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

说谎友 2024-10-30 20:48:38

确保您的 nextWindow UIViewController 引用了 UINavigationController。

更新 #1

我当前的应用程序是选项卡栏应用程序,因此当我需要设置导航控制器引用时,我只需让新传入的视图控制器引用控制选项卡的基类中的导航控制器。

很抱歉之前的回答完全错误,希望这对您有所帮助。

更新 #2

请在推送 UIViewController 之前尝试此操作:

UIButton* backButton = [UIButton buttonWithType:101]; 
[backButton addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; [backButton setTitle:Title forState:UIControlStateNormal]; 
UIBarButtonItem *iButton = [[UIBarButtonItem alloc] initWithCustomView:backButton];     
self.navigationController.navigationItem.leftBarButtonItem = iButton;

更新 #3

将 DefinePreferences 方法复制并粘贴到您的项目

 -(IBAction) definePreferences:(id)sender {

 PreferencesController *nextWindow = [[PreferencesController alloc] initWithNibName:@"Preferences" bundle:nil] ;
 nextWindow.caller = self;
 UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:nextWindow];
 [self presentModalViewController:navController animated:YES];
}

更新 #4

  • 我在 Prefrences 2 Nib 文件中添加了一个 NavigationBar
  • 然后将其与 Prefrences 2 UIViewController 中的 UINavigationItem 类型的 IBOutlet 连接起来
  • 在 ViewDidLoad 中: Prefrences2 UIViewController:添加以下代码以确保添加左侧栏项目 [1]
  • 然后将要处理返回的函数[2]

[1]

 -(void)viewDidLoad {
[super viewDidLoad];

UIButton* backButton = [UIButton buttonWithType:101];
[backButton addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];

[backButton setTitle:@"Helo" forState:UIControlStateNormal];
UIBarButtonItem* iButton = [[UIBarButtonItem alloc] initWithCustomView:backButton]; 

self.oUINavigationItem.leftBarButtonItem = iButton;}

[2]

-(IBAction)buttonPressed:(id)sender
{
    [self.navigationController popViewControllerAnimated:YES];
}

如果您需要我解释更多信息,请告诉我。

Make sure that you're nextWindow UIViewController has reference to the UINavigationController.

Update #1

My current Application is a Tab Bar Application, so when i need to set the navigation controller reference i just let me new incoming View Controller referenced the navigation controller from the base class that controls the tabs.

i am sorry the previous answer i was totally wrong, i hope this would help you.

Update #2

Please try this before pushing the UIViewController:

UIButton* backButton = [UIButton buttonWithType:101]; 
[backButton addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; [backButton setTitle:Title forState:UIControlStateNormal]; 
UIBarButtonItem *iButton = [[UIBarButtonItem alloc] initWithCustomView:backButton];     
self.navigationController.navigationItem.leftBarButtonItem = iButton;

Update #3

copy and paste definePreferences method to your project

 -(IBAction) definePreferences:(id)sender {

 PreferencesController *nextWindow = [[PreferencesController alloc] initWithNibName:@"Preferences" bundle:nil] ;
 nextWindow.caller = self;
 UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:nextWindow];
 [self presentModalViewController:navController animated:YES];
}

Update #4

  • I Added a NavigationBar in the Prefrences 2 Nib file
  • Then connected it with IBOutlet of type UINavigationItem in Prefrences 2 UIViewController
  • In ViewDidLoad: of Prefrences2 UIViewController: add the following code to ensure there is a left bar item is being added [1]
  • Then the function that is going to handle going back[2]

[1]

 -(void)viewDidLoad {
[super viewDidLoad];

UIButton* backButton = [UIButton buttonWithType:101];
[backButton addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];

[backButton setTitle:@"Helo" forState:UIControlStateNormal];
UIBarButtonItem* iButton = [[UIBarButtonItem alloc] initWithCustomView:backButton]; 

self.oUINavigationItem.leftBarButtonItem = iButton;}

[2]

-(IBAction)buttonPressed:(id)sender
{
    [self.navigationController popViewControllerAnimated:YES];
}

please let me know if you need me to explain more.

冷夜 2024-10-30 20:48:38

当您将视图控制器推入导航控制器时,将设置 backBarButtonItem 以返回上一个视图控制器,而不是 leftBarButtonItem。如果设置了 leftBarButtonItem,则 backBarButtonItem 将被隐藏,并且相同位置将被 leftBarButtonItem 替换。

而且您的代码根本没有设置 leftBarButtonItem,所以它当然是 nil。

编辑:
我的测试代码。我通过以下代码检查了 backButtonItem 和 leftBarButtonItem,它们都是零。你是对的。但是当我触摸后退按钮到上一个视图时,它的颜色确实发生了变化,因此它被突出显示。它可以很好地回到以前的视图控制器。所以我认为你的代码在其他地方是错误的,它使后退按钮无效。

清单 1,RootViewController 类

// RootViewController.h 
#import <UIKit/UIKit.h>

@interface RootViewController : UIViewController {
}
@end

// RootViewController.m
#import "RootViewController.h"
#import "MyViewController.h"

@implementation RootViewController

- (void)viewDidLoad {
    [super viewDidLoad];

self.title = @"RootView";

MyViewController *childView = [[[MyViewController alloc] init] autorelease];
UINavigationController *navCtrl = [[[UINavigationController alloc] initWithRootViewController:childView] autorelease];

[self.navigationController presentModalViewController:navCtrl animated:YES];
}
@end

清单 2,MyViewController

// MyViewController.h
    #import <UIKit/UIKit.h>
@interface MyViewController : UIViewController {
}
@end

// MyViewController.m
#import "MyViewController.h"
#import "MyAnotherViewController.h"

@implementation MyViewController

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];

    self.title = @"MyView";

    NSLog(@"%s backBarButtonItem:%@ leftBarButtonItem:%@",__FUNCTION__ ,self.navigationItem.backBarButtonItem, self.navigationItem.leftBarButtonItem);
    MyAnotherViewController *childView = [[[MyAnotherViewController alloc] init] autorelease];
    [self.navigationController pushViewController:childView animated:YES];

}

@end

清单 3,MyAnotherViewController

// MyAnotherViewController.h
#import <UIKit/UIKit.h>

@interface MyAnotherViewController : UIViewController {
}

@end

// MyAnotherViewController.m
#import "MyAnotherViewController.h"
@implementation MyAnotherViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"Another View";
}

@end

When you push view controller into navigation controller, it's backBarButtonItem will be set up for back to previous view controller, not leftBarButtonItem. If you set up leftBarButtonItem, the backBarButtonItem will be hide and the same place will be replaced by the leftBarButtonItem.

And your code doesn't set leftBarButtonItem at all, so of course it is nil.

EDIT:
My test codes. I checked the backButtonItem and leftBarButtonItem by following codes, and they are nil. You are right. But when I touched the back button to previous view, its color did change, so it was highlighted. And it worked well back to previous view controller. So I think your code is wrong at some else place, it makes the back button inactive.

Listing 1, RootViewController class

// RootViewController.h 
#import <UIKit/UIKit.h>

@interface RootViewController : UIViewController {
}
@end

// RootViewController.m
#import "RootViewController.h"
#import "MyViewController.h"

@implementation RootViewController

- (void)viewDidLoad {
    [super viewDidLoad];

self.title = @"RootView";

MyViewController *childView = [[[MyViewController alloc] init] autorelease];
UINavigationController *navCtrl = [[[UINavigationController alloc] initWithRootViewController:childView] autorelease];

[self.navigationController presentModalViewController:navCtrl animated:YES];
}
@end

Listing 2, MyViewController

// MyViewController.h
    #import <UIKit/UIKit.h>
@interface MyViewController : UIViewController {
}
@end

// MyViewController.m
#import "MyViewController.h"
#import "MyAnotherViewController.h"

@implementation MyViewController

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];

    self.title = @"MyView";

    NSLog(@"%s backBarButtonItem:%@ leftBarButtonItem:%@",__FUNCTION__ ,self.navigationItem.backBarButtonItem, self.navigationItem.leftBarButtonItem);
    MyAnotherViewController *childView = [[[MyAnotherViewController alloc] init] autorelease];
    [self.navigationController pushViewController:childView animated:YES];

}

@end

Listing 3, MyAnotherViewController

// MyAnotherViewController.h
#import <UIKit/UIKit.h>

@interface MyAnotherViewController : UIViewController {
}

@end

// MyAnotherViewController.m
#import "MyAnotherViewController.h"
@implementation MyAnotherViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"Another View";
}

@end
木緿 2024-10-30 20:48:38

我有最终的解决方案。
事实上,当从相机覆盖层使用新控制器来显示新视图时,会出现问题。
有时,导航栏不起作用。
为了使其正常工作,您必须不是从自身(覆盖层)而是从 ImagePicker 本身调用第一个视图。因此,您需要在覆盖层上保留对选择器的引用:

self.picker = [[UIImagePickerController alloc] init];

[some initialisation of the picker]

// Insert the overlay
self.overlay = [[OverlayViewController alloc] initWithNibName:@"Overlay" bundle:nil];
-- HERE --self.overlay.pickerRef = self.picker;
self.picker.cameraOverlayView = self.overlay.view;

[self presentModalViewController:self.picker animated:NO];

然后在覆盖层中:

- (IBAction) click:(id)sender {

    PreferencesController *nextWindow = [[[PreferencesController alloc] initWithNibName:@"Preferences" bundle:nil] autorelease];
    UINavigationController* navController = [[[UINavigationController alloc] initWithRootViewController:nextWindow] autorelease];

    -- DO --      [self.pickerRef presentModalViewController:navController animated:YES];
    -- DONT DO -- [self presentModalViewController:navController animated:YES];
}

然后就不再有导航问题了......

I have the final solution.
In fact, there is a problem when a new controller is used from a camera overlay to display a new view.
At some moment, the navigationBar does not work.
To make it work fine, you must call the first view not from self (the overlay) but from the ImagePicker itself. So you need to keep a reference to the picker on the overlay :

self.picker = [[UIImagePickerController alloc] init];

[some initialisation of the picker]

// Insert the overlay
self.overlay = [[OverlayViewController alloc] initWithNibName:@"Overlay" bundle:nil];
-- HERE --self.overlay.pickerRef = self.picker;
self.picker.cameraOverlayView = self.overlay.view;

[self presentModalViewController:self.picker animated:NO];

Then in the overlay :

- (IBAction) click:(id)sender {

    PreferencesController *nextWindow = [[[PreferencesController alloc] initWithNibName:@"Preferences" bundle:nil] autorelease];
    UINavigationController* navController = [[[UINavigationController alloc] initWithRootViewController:nextWindow] autorelease];

    -- DO --      [self.pickerRef presentModalViewController:navController animated:YES];
    -- DONT DO -- [self presentModalViewController:navController animated:YES];
}

Then no more navigation problem...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文