- 浏览: 537989 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
landerson:
明显就有要求的嘛
ANDROID轻量级JSON序列化和反序列化[转] -
jimode2013:
很不错,就是需要这个方法
多个UIViewController使用addSubView,第二个 UIViewController 不响应旋转[转] -
w11h22j33:
...
[转]NSMutableArray中的自动释放对象让我郁闷了一整天 -
w11h22j33:
UILabel* label = [[UILabel a ...
Iphone开发 -
w11h22j33:
http://mobile.51cto.com/iphone- ...
获得通讯录中联系人的所有属性[转]
-----------------------------------
根 UIViewController 响应更改方向,但第二个 UIViewController 不会
我张贴这因为后争夺这一问题的更好的部分的一天 (和很多、 很多的谷歌和计算器搜索),我终于找到了这个问题,但是我没有看到任何地方此解决方案。
我有 UINavigationController 作为根控制器的应用软件和两个 UIViewControllers 所拥有的根控制器。所有编程方式创建,我根本不使用界面生成器。这两个 UIViewControllers 成立,处理所有方向的旋转 (据称),但只根 UIViewController 旋转正确。对于第二个 UIViewController, shouldAutoRotateToInterfaceOrientation
触发一次,但永远不会触发再次,和 willRotateToInterfaceOrientation 永远不会触发的根本。
有问题的视图控制器已只标准控件的子视图: UILabel、 UITextView 和 UISwitch。作为子视图,它不包括 tabBar 或任何其他视图控制器。视图和 VC 都是在范围中,似乎另有健康。与该视图的所有交互除了旋转的都正常运行。
我特别呼吁:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications
和实施:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:@"UIDeviceOrientationDidChangeNotification" object:nil];
随着 didRotate
方法不做差异。
2条回答
回答#1
在 iOS 5,如果您要手动添加意见它很有可能可能,你必须应用的方法addChildViewController:
------------------------------------
什么对象是dipatching的UIViewController旋转的方法调用,即负责:
- shouldAutorotateToInterfaceOrientation:
- willRotateToInterfaceOrientation:时间:
- willAnimateFirstHalfOfRotationToInterfaceOrientation:时间:
- willAnimateSecondHalfOfRotationFromInterfaceOrientation:时间:
- didRotateFromInterfaceOrientation:
我猜想,UIApplication(但也许是AppDelegate或UIWindow)。
看来,UIApplication是派遣一个信息,活动视图控制器。
但如何做你的视图控制器实例得到这些信息?
该邮件被转发到的第一个视图控制器的观点已被添加到UIWindow实例。
这可以归结为3个基本情况:
-
-
他们的观点是的ViewController
直接添加到UIWindow
(例如单一视图的应用程序)
-
-
-
在导航控制器
导航的应用程序,则
导航控制器转发
信息的积极的意见看法
控制器。
-
-
-
在一个标签栏标签栏控制器
基于应用程序,那么标签栏
控制器转发邮件
活动的意见看法控制器(或
积极导航控制器)。
-
您将有问题,如果你是建立一个与多个视图的应用程序,但不使用导航控制器或一个标签栏控制器。 如果您在交换意见,并出UIWindow实例手动,您将不会收到这些消息可靠。
首先重写UIViewController方法:
Java代码
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return YES;
}
你也可以根据toInterfaceOrientation的不同值来判断是否允许旋转。这个传入参数有四种取值:
Java代码
UIInterfaceOrientationLandscapeLeft 横向Home键在左
UIInterfaceOrientationLandscapeRight 横向Home键在右
UIInterfaceOrientationPortrait 正常
UIInterfaceOrientationPortraitUpsideDown 反向Home键在上
可以在下面的方法中处理旋转后要重画的组件,或者重载另一个NIB文件。
Java代码
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
// 重新加载一个Nib文件
if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft || self.interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
[[NSBundle mainBundle] loadNibNamed:@"LoginViewLandscape" owner:self options:nil];
}else {
[[NSBundle mainBundle] loadNibNamed:@"LoginView" owner:self options:nil];
}
// 重写Toolbar
// Set Toolbar
UIBarButtonItem *newChat = [[UIBarButtonItem alloc] initWithTitle:@"新增" style:UIBarButtonItemStylePlain target:self action:@selector(createChat:)];
UIBarButtonItem *refresh = [[UIBarButtonItem alloc] initWithTitle:@"刷新" style:UIBarButtonItemStylePlain target:self action:@selector(refresh:)];
UIBarButtonItem *deleteChat = [[UIBarButtonItem alloc] initWithTitle:@"删除" style:UIBarButtonItemStylePlain target:self action:@selector(deleteChat:)];
self.deleteItem = deleteChat;
self.deleteItem.enabled = NO;
UIBarButtonItem *fixedItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:NULL];
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
fixedItem.width = 155;
}else {
fixedItem.width = 75;
}
NSArray *toolBarItems = [[NSArray alloc] initWithObjects:newChat, fixedItem, refresh, fixedItem, self.deleteItem, nil];
[self setToolbarItems:toolBarItems];
[toolBarItems release];
[newChat release];
[deleteChat release];
[fixedItem release];
[refresh release];
}
----------------------------------------
一.UIViewController
做iOS开发的经常会和UIViewController打交道,从类名可知UIViewController属于MVC模型中的C(Controller),说的更具体点它是一个视图控制器,管理着一个视图(view)。
UIViewController的view是lazy loading的,当你访问其view属性的时候,view会从xib文件载入或者通过代码创建(覆盖loadView方法,自定义其view hierarchy),并返回,如果要判断一个View Controller的view是否已经被加载需要通过其提供的isViewLoaded方法来判断。
view加载后viewDidLoad会被调用,这里可以进行一些数据的请求或加载,用来更新你的界面。
当view将被加入view hierarchy中的时候viewWillAppear会被调用,view完成加入的时候viewDidAppear会被调用,同样当view将要从view hierarchy中移除的时候viewWillDisappear会被调用,完成移除的时候viewDidDisappear会被调用。
当内存紧张的时候,所有的UIViewController对象的didReceiveMemoryWarning会被调用,其默认实现是 如果当前viewController的view的superview是nil的话,则将view释放且viewDidUnload会被调用,viewDidUnload中你可以进行后继的内存清理工作(主要是界面元素的释放,当再次加载的时候需要重建)。
如果想要展示一个View Controller,一般有如下一种途径
- 设置成Window的rootViewController(iOS 4.0之前UIWindow并没有rootViewController属性,只能通过addSubview的方式添加一个View Controller的view)
- 使用某个已经存在的Container来展示,比如使用UINavigationController来展示某个View Controller [navigationController pushViewController:vc animated:YES];
- 以模态界面的方式展现出来 presentModalViewController
- 以addSubview的方式将使其view作为另一个View Controller的view的subView
直接使用4种方法是比较危险的,上一级 View Controller并不能对当前View Controller的 生命周期相关的函数进行调用,以及旋转事件的传递等。
二.Hierarchy
我们知道一个View可以将另一个View添加为子View(subview),构成一个View Hierarchy.当某一个View添加到window的View Hierarchy中时,将被“显示”。每一个View Controller管理着的其实就是一个View Hierarchy.而View Controller本身可以有Child View Controller,所以也存在一个 View Controller Hierarchy的概念,当View Controller收到上层传来的诸如旋转,显示事件的时候,需要传递给它的Child View Controller. 一般情况下,View Hierarchy 和 View Controller Hierarchy需要保持一致性,比如一个View Controller的view的superView是由其parent view controller管理着
三.Container
一个iOS的app很少只由一个ViewController组成,除非这个app极其简单。 当有多个View Controller的时候,我们就需要对这些View Controller进行管理。 那些负责一个或者多个View Controller的展示并对其视图生命周期进行管理的对象,称之为容器,大部分容器本身也是一个View Controller,这样的容器可以称之为Container View Controller,也有极少数容器不是View Controller,比如UIPopoverController,其继承于NSObject。
我们常用的容器有 UINavigationController,UITabbarController等,一般容器有一些共同的特征:
- 提供对Child View Controller进行管理的接口,比如添加Child View Controller,切换Child View Controller的显示,移除Child View Controller 等
- 容器“拥有”所有的Child View Controller
- 容器需要负责 Child View Controller的appearance callback的调用(viewWillAppear,viewDidAppear,viewWillDisaapper,viewDidDisappear),以及旋转事件的传递
- 保证view hierarchy 和 view controller hierarchy 层级关系一致,通过parent view controller将child view controller和容器进行关联
从上面可以看出来,实现一个Container View Controller并不是一个简单的事情,好在iPhone的界面大小有限,一般情况下一个View Controller的view都是充满界面或者系统自带容器的,我们无需自己创建额外的容器,但是在iPad中情况就不同了。
四.Custom Container View Controller
在iOS 5之前框架并不支持自定义 Container View Controller, iOS 5开始开放了一些新的接口来支持支持自定义容器
addChildViewController:
removeFromParentViewController
transitionFromViewController:toViewController:duration:options:animations:completion:
willMoveToParentViewController:
didMoveToParentViewController:
其中前两个接口比较重要,可以直接改变View Controller 的 Hierarchy。
有点意外的是,在不做任何额外设置的情况下进行如下操作
[viewController.view addSubview:otherViewController.view]
iOS 5中otherViewController是可以立刻收到viewWillAppear和viewDidAppear的调用。
至于旋转事件的传递以及其他时机viewWillAppear viewDidAppear的调用是需要建立在 [viewController addChildViewController:otherViewController]基础上的。
当我们需要在iOS 4上实现自定义容器,或者有时候我们不想让viewWillAppear这类方法被自动调用,而是想自己来控制,这个时候我们就得需要手动来调用这些方法,而不是由框架去自动调用。 iOS 5中可以很方便的禁用掉自动调用的特性,覆盖automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers返回NO
但是单单覆盖这个方法在iOS5下还是有问题的,当执行下面的语句的时候
[viewController.view addSubview:otherViewController.view]
otherViewController还是是可以立刻收到viewWillAppear和viewDidAppear的调用。
解决这一问题的方法就是在iOS5的时候调用[viewController.view addSubview:otherViewController.view]之前 进行如下操作
[viewController addChildViewController:otherViewController]
总的来说实现兼容iOS 4和iOS 5的容器有不少问题和注意点的
- view加入view层级前后分别调用viewWillAppear和viewDidAppear;容器的viewWillAppear,viewDidAppear,viewWillDisappear,viewDidDisappear中需要对当前显示的Child View Controller调用相同的方法,容器需要保证Child View Controller的viewWillAppear调用之前Child View Controller的view已经load了.还有一点就是保证容器的View不会出现bounds为CGRectZero的情况,因为如果此View包含多个subview,其bounds改变的时候subview会根据自己的autoresizingMask改变frame,但是当bounds变为0再变为非0的时候,subview的frame就有可能不是你想要的了(比如某个subview的autoresizingMask为UIViewAutoresizingFlexibleBottomMargin)
- 容器的shouldAutorotateToInterfaceOrientation中需要检测每一个Child View Controller的shouldAutorotateToInterfaceOrientation如果一个不支持,则看做不支持
- 容器的willRotateToInterfaceOrientation,didRotateFromInterfaceOrientation,willAnimateRotationToInterfaceOrientation方法中需要将这些事件传递给所有的Child View Controller
- 由于UIViewController的parentViewController属性为只读,且iOS4中没有提供容器支持的接口(iOS 5中容器支持的接口会间接的维护这个属性),所以为了使得childViewController和容器得以关联,我们可以顶一个View Controller的基类,添加一个比如叫做superController的属性用来指定对应的parentViewController
- 由于UIViewController的interfaceOrientation为只读属性,且iOS5中没有提供容器接口,所以UIViewController的这个interfaceOrientation变的不可信,为了取得当前UIViewController的orientation我们可以用UIWindow下的rootViewController的interfaceOrientation的值
- 容器的viewDidUnload方法中需要对view未释放的childViewController的view进行释放,且调用其viewDidUnload方法
苹果对UIViewController以及其使用有着非常详细的文档 UIViewController Reference , ViewController Programming Guide。
------------------------------------------
对于iPhone app,UIViewController类提供了基本的视图管理模式。当设备改变方向的时候view controller的视图会自动随之旋转的。如果视图和子视图的autoresizing属性设置是对的,这时候视图又没有随着设备一起旋转,可能是以下的原因:
1.view controller没有完成代理方法
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;
也要实现了shouldAutorotateToInterfaceOrientation方法,同时shouldAutorotateToInterfaceOrientation方法要返回YES来支持所有的旋转方向
2.view controller的UIView属性嵌入在UIWindow中,并非是一个附加的view controller
你可能会发现shouldAutorotateToInterfaceOrientation方法只会在view controller启动的时候被调用,不会因为设置的旋转而在被调用。这是因为view controller束缚着他们所管理的视图,view controller是用来处理时间的响应链的一部分。view controller是从UIResponder继承而来,同时他被插入到他所管理的视图和他的superview之间。因此,通常的做法是在你的app中有一个主view controller来作为响应链的一部分。通常来说会添加一个主view controller,例如UINavigationController, UITabBarController或者UIViewController到UIWindow上。
例如
[myWindow addSubview:primaryViewController.view];
如果你添加了另外一个view controller的UIView属性到UIWindow(anotherController和主view controller在同一个等级上)
[myWindow addSubview:anotherController.view];
anotherController将不会接受旋转事件,只有第一个view controller(primaryViewController)会接受旋转事件。
3.你添加了view controller的UIView属性到UIWindow作为subview,但是过早的release它。
UIWindow会retain视图,而不是view controller。你不能过早的release他。在UIApplicationDelegate子类中定义他为retain属性。
4.在UITabBarController或者UINavigationController中的子view controller没有对同一方向的支持。
为了确保所有的子view controller旋转正确,你的每一个view controller,每一个tab或者额navigation都要完成shouldAutorotateToInterfaceOrientation,而且必须支持对于同一方向的旋转,也就是说对于同一方向的位置要返回为YES。
5.重写-(id)init:或者 -(id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle 方法的时候没有调用super。
对于对象的初始化,在你的view controller的init或者initWithNibName方法中必须要调用super。
发表评论
-
iOS App性能优化
2014-01-03 11:23 1694http://www.hrchen.com/2013/05/ ... -
iOS多线程编程Part 3/3 - GCD
2014-01-03 11:21 1649http://www.hrchen.com/2013/07/ ... -
iOS多线程编程Part 2/3 - NSOperation
2014-01-03 11:20 4544http://www.hrchen.com/2013/06/ ... -
iOS多线程编程Part 1/3 - NSThread & Run Loop
2014-01-03 11:17 7105http://www.hrchen.com/2013/06/ ... -
iOS移动网络环境调优那些事[转]
2014-01-02 17:10 2700http://xiangwangfeng.com/201 ... -
生成APNS Service证书的步骤[转]
2013-05-23 09:19 5678要进行推送服务的第一件事就是获取推送证书。它用来对你通过SS ... -
xcode 环境,多工程联编设置【转】
2013-02-28 21:59 8964http://blog.csdn.net/vienna_zj ... -
干掉你程序中的僵尸代码【转】
2012-12-22 11:05 966随着万圣节越来越流行,我感觉有必要跟大家讨论一下一个 ... -
一个文本框搞定信用卡相关信息的输入[转]
2012-12-22 11:03 1139http://beforweb.com/node/134 ... -
【转】深度技术分析“为什么ios比android流畅”
2012-09-23 19:41 1438原文 Andorid更新了一个版本又一个版本,硬 ... -
Iphone开发
2012-09-17 22:46 12061. NSClassFromString 这个方法 ... -
HowTo: Install iPhone SDK 2.0 – 3.1 for XCode 3.2[转]
2012-09-06 09:00 1222原文链接 So… you’ve installe ... -
Xcode 中设置部分文件ARC支持[转]
2012-08-03 10:57 1736ARC是什么 ARC是iOS 5推出的新功 ... -
xcode4 设置调试错误信息小结【转】
2012-07-19 14:37 1811方案1:NSZombieEnabled 先选中工程, ... -
Finding iPhone Memory Leaks: A “Leaks” Tool Tutorial【转】
2012-07-19 14:36 1266Finding iPhone Memory Lea ... -
[Cocoa]XCode的一些调试技巧【转】
2012-07-19 14:35 1205XCode 内置GDB,我们可以在命令行中使用 GDB ... -
[IPhone]如何使用Leak检查内存泄漏[转]
2012-07-19 14:34 1235简介 在IPhone程式开发中,记忆体泄漏(内存泄漏)是 ... -
获得通讯录中联系人的所有属性[转]
2012-06-21 14:04 1616获得通讯录中联系人的所有属性 ,看代码: ABAdd ... -
shouldAutorotateToInterfaceOrientation 不触发或者不执行的问题[转]
2012-06-20 22:58 1462今天遇到一个很郁闷 ... -
UIViewController生命周期-学习笔记[转]
2012-06-20 22:57 1135UIViewController生命周 ...
相关推荐
本节将深入探讨如何使用Swift创建一个UIViewController的自定义缩放过渡动画。 首先,我们需要了解UIViewController的生命周期和过渡动画的基础知识。UIViewController提供了`present`和`dismiss`方法来显示和隐藏...
这个Demo可能包含了如何设置屏幕旋转支持、使用Auto Layout进行响应式布局、以及在不同设备尺寸下展示正确界面的实践。通过学习和分析这个Demo,开发者可以更好地理解和掌握iOS中的屏幕旋转和大小调节技术。 总之,...
在iOS应用开发中,`UIViewController`是苹果提供...在实践中,根据项目需求,你可能会需要添加更多的子视图、设置约束、响应触摸事件、集成网络请求、处理数据模型等,这些都可以在`UIViewController`及其子类中实现。
对于视图的缩放效果,我们可以使用`transform`属性,它支持对视图进行平移、旋转、缩放等多种变换。 缩放动画的基本思路是改变`transform`中的`scale`子属性。假设我们有一个名为`myView`的`UIView`实例,我们可以...
在iOS开发中,"iphonecontrol立方体旋转"指的是利用苹果的Core Animation框架,特别是`CATransition`类,来实现一种视觉效果,即立方体旋转,用于在多个视图(views)之间平滑地切换。这种效果给用户带来动态且...
这样,我们就实现了使用UIViewController自带的特性来创建类似QQ加号下拉菜单的功能。用户点击加号按钮后,将弹出一个包含多个选项的下拉菜单。通过调整大小、样式和位置,我们可以让这个菜单与QQ应用中的效果相似。...
在iOS开发中,Spinner通常指的是一个正在加载或者处理数据时显示的动画视图,它向用户传达了应用程序正在进行后台操作的信息。"iOS Spinner"是指在iOS应用中实现这种旋转指示器的方法,它可以帮助提高用户体验,让...
本教程将深入讲解如何在iPhone应用中使用工具栏(Toolbar)来实现简单的多视图切换,这对于初学者来说是一个非常实用的例子。 首先,我们需要了解iOS的基础架构。iOS应用基于Cocoa Touch框架,其中UIWindow、...
// 创建第二个标签 let label2 = UILabel() label2.text = "标签2的内容" label2.font = UIFont.boldSystemFont(ofSize: 24) label2.textColor = .blue label2.frame = CGRect(x: 20, y: label1.frame.maxY + ...
在iOS的UIKit框架中,虽然有内置的转场动画支持,但往往不能满足所有设计需求,因此Hero应运而生。 首先,我们需要了解Hero的基本用法。在项目中引入Hero库后,只需通过在视图控制器上添加`hero_id`标识符,就可以...
在iOS开发中,一个控制器(UIViewController)管理多个TableView是一种常见的设计模式,特别是在构建复杂界面时。这个场景下,每个TableView可以展示不同的数据集或者有不同的功能,但都由同一个控制器进行控制。...
在iOS应用开发中,导航控制器(UINavigationController)是不可或缺的一部分,它主要用于管理多个视图控制器的堆栈,提供了一个在不同控制器之间平滑过渡的机制。这篇教程将深入讲解如何在Objective-C环境下使用导航...
Demo: ... 横向菜单 页面滑动 例子 ... UIViewController *VC1 = [[UIViewController alloc]init];... [VC1.view setBackgroundColor:[UIColor redColor]];... UIViewController *VC2 = [... [self.view addSubview:LyMenu];
在iOS开发中,UIPageViewController是一种非常有用的控件,它允许用户通过滑动来浏览多个视图控制器,常用于创建类似电子书、相册或滚动式界面的效果。本篇文章将深入探讨UIPageViewController的使用,结合源码分析...
当需要在当前视图控制器之上显示一个新的视图控制器时,可以使用这个方法。但是,它并不直接涉及UIWindow,而是通过当前视图控制器进行呈现。 ```objc UIViewController *presentedController = [[UIViewController...
`UIViewController` 是一个控制器类,它的主要职责是管理一个或者多个`UIView`实例。`UIViewController`的`view`属性是它默认显示的视图,你可以通过这个属性设置自定义的视图类。`initWithNibName:bundle:`是初始化...
此外,苹果官方并不推荐这种强制转屏的方式,建议尽可能遵循系统的自动旋转规则,除非有特殊需求。 最后,文中还提到了其他与iOS开发相关的文章,包括验证码倒计时、粒子移动效果、QQ拖动效果、微信二维码识别方式...
本压缩包“ios-swift-demo6-TabbarVc的使用.zip”显然是一个关于如何在Swift项目中使用TabbarViewController(标签栏控制器)的示例代码。TabbarController是iOS应用中常见的组件,它允许用户通过底部的标签栏在多个...
在iOS开发中,刷新框架是实现用户界面动态更新的关键组件,尤其对于数据流式布局或者列表展示的应用来说更是必不可少。本教程将详细讲解如何在iOS应用中实现左右滑动界面以及下拉刷新、点击加载等功能。 一、下拉...
在iOS开发中,创建第一个应用通常是从"HelloWorld"开始的。这个教程将带你深入理解如何在不使用XIB(Interface Builder的接口文件)的情况下,重写HelloWorld应用。我们将会使用Swift编程语言,它是Apple为iOS、...