iPhone 在 navigationViewController 模式下旋转视图

发布于 2024-10-21 02:52:52 字数 5998 浏览 1 评论 0原文

几个小时前,我发布了一个有关在 iPhone 中组织纵向和横向模式的问题,现在我想我知道如何使用 willRotateToInterfaceOrientation:duration 来做到这一点。

第一个屏幕是“地图视图”,其中有一个按钮可通往“设置视图”。地图视图不支持旋转,但对于设置视图,我为纵向和横向制作了单独的视图,并且它们在旋转时相应地交换。

在此处输入图像描述在此处输入图像描述, 在此处输入图像描述

正如您所看到的,当按下“设置”按钮时,SettingView 将添加到视图上像往常一样堆叠。所以基本上我使用三个视图控制器;设置、设置风景和设置肖像。

当我使用 navigationViewController 时,我仍然发现 iPhone 中的旋转视图有问题。 分段控制不起作用。它崩溃时没有错误消息。它曾经在没有旋转的情况下正常工作。-当我不使用多个视图进行旋转时-。

rotateViewController.m

这是根视图控制器。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
  return YES;

-(IBAction) buttonPressed{
Setting *settingViewController = [[Setting alloc] initWithNibName:@"Setting" bundle:[NSBundle mainBundle]];
UINavigationController *navController1 = [[UINavigationController alloc] initWithRootViewController: settingViewController];
[self.navigationController presentModalViewController:navController1 animated:YES];
[settingViewController release];
[navController1 release];

Setting.m

这个视图控制器除了在旋转时交换视图并在纵向和横向之间显示适当的视图之外什么也不做

在Setting.m中,我如下交换视图;

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (toInterfaceOrientation==UIInterfaceOrientationLandscapeRight) {
    NSLog(@"to Right");
    SettingLandscape *setting_landscape = [[SettingLandscape alloc] initWithNibName:@"SettingLandscape" bundle:[NSBundle mainBundle]];
    self.view = setting_landscape.view;
    [setting_landscape release];
}
 if (toInterfaceOrientation==UIInterfaceOrientationLandscapeLeft) {
     NSLog(@"to Left");
     SettingLandscape *setting_landscape = [[SettingLandscape alloc] initWithNibName:@"SettingLandscape" bundle:[NSBundle mainBundle]];
     self.view = setting_landscape.view;
     [setting_landscape release];
 }
if (toInterfaceOrientation==UIInterfaceOrientationPortrait) {
    NSLog(@"to Portrait");
    SettingPortrait *settingportrait = [[SettingPortrait alloc] initWithNibName:@"SettingPortrait" bundle:[NSBundle mainBundle]];
    self.view = settingportrait.view;
    [settingportrait release];
}
if (toInterfaceOrientation==UIInterfaceOrientationPortraitUpsideDown) {
    NSLog(@"to PortraitUpsideDown");
    SettingPortrait *settingportrait = [[SettingPortrait alloc] initWithNibName:@"SettingPortrait" bundle:[NSBundle mainBundle]];
    self.view = settingportrait.view;
    [settingportrait release];
}

在viewWillAppear

中,设置视图控制器还有;

self.title = @"Shell ";
self.navigationController.navigationBarHidden = NO; 
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStylePlain target:self action:@selector(Done)] autorelease];

完成后是

- (void) Done{
[self dismissModalViewControllerAnimated:YES];  

}

SettingLandscape.m

当视图旋转时,该视图会堆叠起来。这个视图控制器有它的导航栏。

 - (void)viewWillAppear:(BOOL)animated {
     [super viewWillAppear:animated];
     self.title = @"Setting Landscape";

在viewDidLoad

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;

- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"landscape:viewDidLoad");
//self.title = @"SettingLandscape";//not working!!
//self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Done1" style:UIBarButtonItemStylePlain target:self action:@selector(Done)] autorelease];

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
stringflag4MapType = [[NSString alloc] initWithString:@"blah"];
stringflag4MapType = [defaults stringForKey:@"flag4MapType"];
if (![stringflag4MapType isEqualToString:@"Hybrid"] && ![stringflag4MapType isEqualToString:@"Standard"] && ![stringflag4MapType isEqualToString:@"Satellite"]) {
    segmentedControl4MapType.selectedSegmentIndex = 0;
}else if ([self.stringflag4MapType isEqualToString:@"Standard"]) {
    segmentedControl4MapType.selectedSegmentIndex = 0;
}else if ([self.stringflag4MapType isEqualToString:@"Satellite"]) {
    segmentedControl4MapType.selectedSegmentIndex = 1;
}else if ([self.stringflag4MapType isEqualToString:@"Hybrid"]) {
    segmentedControl4MapType.selectedSegmentIndex = 2;

}

并且以下调用不会被调用。奇怪的。无论如何,旋转都没关系。

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (toInterfaceOrientation==UIInterfaceOrientationPortrait) {
    NSLog(@"to Portrait");// does not print out.
    SettingPortrait *settingportrait = [[SettingPortrait alloc] initWithNibName:@"SettingPortrait" bundle:[NSBundle mainBundle]];
    self.view = settingportrait.view;
    [settingportrait release];

}
if (toInterfaceOrientation==UIInterfaceOrientationPortraitUpsideDown) {
    NSLog(@"to PortraitUpsideDown");
    SettingPortrait *settingportrait = [[SettingPortrait alloc] initWithNibName:@"SettingPortrait" bundle:[NSBundle mainBundle]];
    self.view = settingportrait.view;
    [settingportrait release];

}

现在好了

,正如您从这些快照中看到的那样,有两个导航栏,每个导航栏都有其栏按钮:“完成”和“项目”。 “完成”按钮来自“设置”,“项目”按钮来自“设置纵向”或“设置横向”。所有按钮的选择器都是相同的,可返回地图视图。 “完成”按钮工作正常,但“项目”按钮崩溃。旋转后我需要在导航栏上有一个按钮,其作用类似于后退按钮。我想有一次我做了“self.view=settingportrait.view;”问题开始了。

我需要“项目”按钮工作的原因是,一旦我添加支持旋转的代码,分段控件就开始崩溃。如果我找到了如何使项目按钮(位于旋转视图内)工作的原因,我想我也可以使分段控件工作。

您可以在 https://github.com/downloads/bicbac/rotation-test/rotate-1.zip

hours ago I post a question on organizing portrait and landscape mode in iPhone and now I think I know how to do it using willRotateToInterfaceOrientation:duration.

The first screen is 'Map View' with one button that leads to 'Setting View'. The Map View does not support rotate but for the Setting View I made separate view for portrait and landscape and they swap accordingly when rotated.

enter image description here, enter image description here, enter image description here

As you can see when Setting button pressed SettingView is added on the view stack as usual. So basically I use three view controllers; Setting, SettingLandscape and SettingPortrait.

I still found problem in rotating view in iPhone when I use navigationViewController. Segmented control is not working. it crashes without error message. It used to working fine without rotation.- when I'm not using multiple view for rotation-.

rotateViewController.m

This is root view controller.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
  return YES;

}

-(IBAction) buttonPressed{
Setting *settingViewController = [[Setting alloc] initWithNibName:@"Setting" bundle:[NSBundle mainBundle]];
UINavigationController *navController1 = [[UINavigationController alloc] initWithRootViewController: settingViewController];
[self.navigationController presentModalViewController:navController1 animated:YES];
[settingViewController release];
[navController1 release];

}

Setting.m

This view controller does nothing but swap views when rotate and shows appropriate view between portrait and landscape.

In Setting.m, I swap view as follow;

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (toInterfaceOrientation==UIInterfaceOrientationLandscapeRight) {
    NSLog(@"to Right");
    SettingLandscape *setting_landscape = [[SettingLandscape alloc] initWithNibName:@"SettingLandscape" bundle:[NSBundle mainBundle]];
    self.view = setting_landscape.view;
    [setting_landscape release];
}
 if (toInterfaceOrientation==UIInterfaceOrientationLandscapeLeft) {
     NSLog(@"to Left");
     SettingLandscape *setting_landscape = [[SettingLandscape alloc] initWithNibName:@"SettingLandscape" bundle:[NSBundle mainBundle]];
     self.view = setting_landscape.view;
     [setting_landscape release];
 }
if (toInterfaceOrientation==UIInterfaceOrientationPortrait) {
    NSLog(@"to Portrait");
    SettingPortrait *settingportrait = [[SettingPortrait alloc] initWithNibName:@"SettingPortrait" bundle:[NSBundle mainBundle]];
    self.view = settingportrait.view;
    [settingportrait release];
}
if (toInterfaceOrientation==UIInterfaceOrientationPortraitUpsideDown) {
    NSLog(@"to PortraitUpsideDown");
    SettingPortrait *settingportrait = [[SettingPortrait alloc] initWithNibName:@"SettingPortrait" bundle:[NSBundle mainBundle]];
    self.view = settingportrait.view;
    [settingportrait release];
}

}

In viewWillAppear, Setting view controller also has ;

self.title = @"Shell ";
self.navigationController.navigationBarHidden = NO; 
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStylePlain target:self action:@selector(Done)] autorelease];

and Done is

- (void) Done{
[self dismissModalViewControllerAnimated:YES];  

}

SettingLandscape.m

This view stacked on when the view is rotated. This view controller has it's navigation bar.

 - (void)viewWillAppear:(BOOL)animated {
     [super viewWillAppear:animated];
     self.title = @"Setting Landscape";

}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;

}

in viewDidLoad;

- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"landscape:viewDidLoad");
//self.title = @"SettingLandscape";//not working!!
//self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Done1" style:UIBarButtonItemStylePlain target:self action:@selector(Done)] autorelease];

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
stringflag4MapType = [[NSString alloc] initWithString:@"blah"];
stringflag4MapType = [defaults stringForKey:@"flag4MapType"];
if (![stringflag4MapType isEqualToString:@"Hybrid"] && ![stringflag4MapType isEqualToString:@"Standard"] && ![stringflag4MapType isEqualToString:@"Satellite"]) {
    segmentedControl4MapType.selectedSegmentIndex = 0;
}else if ([self.stringflag4MapType isEqualToString:@"Standard"]) {
    segmentedControl4MapType.selectedSegmentIndex = 0;
}else if ([self.stringflag4MapType isEqualToString:@"Satellite"]) {
    segmentedControl4MapType.selectedSegmentIndex = 1;
}else if ([self.stringflag4MapType isEqualToString:@"Hybrid"]) {
    segmentedControl4MapType.selectedSegmentIndex = 2;

}

and following call does not get invoked. strange. doesn't matter rotation works anyway.

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (toInterfaceOrientation==UIInterfaceOrientationPortrait) {
    NSLog(@"to Portrait");// does not print out.
    SettingPortrait *settingportrait = [[SettingPortrait alloc] initWithNibName:@"SettingPortrait" bundle:[NSBundle mainBundle]];
    self.view = settingportrait.view;
    [settingportrait release];

}
if (toInterfaceOrientation==UIInterfaceOrientationPortraitUpsideDown) {
    NSLog(@"to PortraitUpsideDown");
    SettingPortrait *settingportrait = [[SettingPortrait alloc] initWithNibName:@"SettingPortrait" bundle:[NSBundle mainBundle]];
    self.view = settingportrait.view;
    [settingportrait release];

}

}

ok now, as you can see from those snap shots there are two navigation bar and each has its bar button, Done and Item. The Done button came from Setting and the Item button from SettingPortrait or SettingLandscape. All button's selector is same, that leads back to map view. The button Done works fine, but the button Item crashes. I need a button on navigation bar after rotation that acts like back button . I guess once I did 'self.view = settingportrait.view;' the problem starts.

The reason why I need the Item button work is that the segmented control started crashing once I add code to support rotation. If I found reason how to make the Item button-that is inside rotation view- work I think I can make the segmented control work as well.

You can download the whole code at https://github.com/downloads/bicbac/rotation-test/rotate-1.zip

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

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

发布评论

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

评论(2

安静被遗忘 2024-10-28 02:52:52

https://github.com/downloads/bicbac/rotation-test/rotate -1.zip
这个示例代码对我来说太棒了。它通过简单的委托方法解决了我的旋转视图问题

  • (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    返回是;
    }

https://github.com/downloads/bicbac/rotation-test/rotate-1.zip
this sample code is amazing for me. It solve my problem of rotating view just by simple delegate method

  • (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
    }
無處可尋 2024-10-28 02:52:52
  • 我最好的尝试是在不看代码的情况下回答问题(今晚没有时间:()

当您以模态方式呈现设置视图控制器时,您的顶部视图控制器正在设置。

当旋转发生时,您加载setting_landscape或setting_portrait视图控制器,但只保留内部视图因此,当设备旋转时,setting_landscape/portrait 视图控制器被释放,可能是“setting”视图控制器接收旋转消息,而不是“setting_landscape/portrait”视图控制器,因为它们没有被推送到。 您

因此,当您单击项目或段控件时,它会调用委托,该委托可能已设置为已释放的“setting_landscape|portrait”。

在崩溃时收到的消息是什么 。 ?

我的建议是使用分段控件构建设置视图控制器,然后使用“willAnimateRotationToInterfaceOrientation:duration:”函数将分段控件重新定位到正确的位置和框架。只要对所有方向返回 YES,就应该支持旋转,不是吗?

使用两个单独的视图控制器进行横向/纵向的原因是什么? (我有时这样做,但很少)

编辑*您需要使用“willAnimateRotationToInterfaceOrientation”回调来动画更改,而不是“willRotate...”

  • my best attempt to answer question without looking at code (don't have time tonight :( )

When you present setting viewcontroller modally, your top viewcontroller is setting.

When rotation happens, you load setting_landscape or setting_portrait viewcontroller, but only retain the view inside setting_landscape|portrait. Thus, setting_landscape/portrait viewcontrollers are released. When device is rotated, it's probably "setting" viewcontroller receiving rotation message, not the "setting_landscape/portrait" viewcontroller because they are not pushed on to the viewcontroller stack.

So, when you click on item or segment control, it will call delegate, which is probably set to setting_landscape|portrait which is released already.

What is the message in console you get with crash?

My recommendation would be to build setting viewcontroller with segmented control, then use "willAnimateRotationToInterfaceOrientation:duration:" function to reposition the segmented control to the right position and frame. Just by returning YES to all orientation, rotation should be supported, doesn't it?

What was the reason for using two separate viewcontroller for landscape/portrait? (I do this sometimes, but rarely)

Edit* you need to use "willAnimateRotationToInterfaceOrientation" callback to animate the changes, not "willRotate..."

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