当视图非全屏时,子类化 UIViewController 或创建自定义 NSObject
我需要创建一个类控制器来管理我创建的自定义视图的行为。 标准方法是子类化 UIViewController,但就我而言,我决定 子类化 NSObject 本质上有三个原因:
- 我的视图需要添加为主视图控制器的小子视图(它不会使用诸如presentModalViewController或pushViewController之类的东西显示......)并且它不需要任何类型的工具栏或导航控件在它的内部
- 很可能我的控制器不需要通知设备方向,因为它的视图将始终以纵向格式使用,所以我对接收通常的旋转消息 willRotateToInterfaceOrientation 等不感兴趣...
- 我需要保留这个类轻如可能最大限度地减少内存消耗。不子类化 UIViewController 的优点是可以获得一个更轻的类,而无需使用一堆我永远不需要使用的方法。
我的控制器的界面非常简单,例如:
@interface MyScrollTabBarController : NSObject <MyTabBarViewDelegate> { }
/**
* The view is created internally by the controller and the client class
* can access to it in readonly mode
*/
@property (nonatomic, readonly) UIView *view;
/**
* A Property to change the view appearance
*/
@property (nonatomic, assign) MyScrollTabBarViewState viewState;
/**
* Others properties used to construct the view's subviews
*/
@property (nonatomic, retain) Location *rootLocation;
@property (nonatomic, readonly, retain) Place *place;
/**
* Designated initializer
*/
- (id)initWithPlace:(Place *)aPlace;
- (void)setRootLocation:(Location *)location animated:(BOOL)animated;
@end
要从父视图控制器显示其内部视图,我将使用类似的东西这个:
tabBarController = [[MyScrollTabBarController alloc] initWithPlace:aPlace];
tabBarController.viewState = MyScrollTabBarViewStateXX;
tabBarController.view.frame = CGRectMake(...);
[self.view addSubview:tabBarController.view];
我想知道你对我的选择有何看法,如果你认为它可能有缺点,以及当你需要为不像我的全屏视图编写控制器时你通常会做什么。
谢谢
I need to create a class controller to manage the behavior of a custom view I created.
The standard approach is to subclass UIViewController, but in my case I instead decided to
subclass the NSObject essentially for three reasons:
- my view needs to be added as small subview of the main view controller (it will not be displayed using something like presentModalViewController or pushViewController...) and it does not require any kind of toolbar or navigation control inside of it
- Most probably my controller will not need to be notified for device orientation because its view will be always used in portrait format, so I'm not interested to receive the usual rotation messages willRotateToInterfaceOrientation etc...
- I need to keep this class as lightweight as possible minimizing memory consumption. Not subclassing UIViewController have the advantage to obtain a lighter class without a bunch of methods that I will never need to use
The interface of my controller is pretty simple, example:
@interface MyScrollTabBarController : NSObject <MyTabBarViewDelegate> { }
/**
* The view is created internally by the controller and the client class
* can access to it in readonly mode
*/
@property (nonatomic, readonly) UIView *view;
/**
* A Property to change the view appearance
*/
@property (nonatomic, assign) MyScrollTabBarViewState viewState;
/**
* Others properties used to construct the view's subviews
*/
@property (nonatomic, retain) Location *rootLocation;
@property (nonatomic, readonly, retain) Place *place;
/**
* Designated initializer
*/
- (id)initWithPlace:(Place *)aPlace;
- (void)setRootLocation:(Location *)location animated:(BOOL)animated;
@end
To display its internal view from the parent view controller, I will use something like this:
tabBarController = [[MyScrollTabBarController alloc] initWithPlace:aPlace];
tabBarController.viewState = MyScrollTabBarViewStateXX;
tabBarController.view.frame = CGRectMake(...);
[self.view addSubview:tabBarController.view];
I'd like to know what do you think about my choice, if you think that there could be drawbacks in it and what do you usually do when you need to write a controller for a view which is not fullscreen like mine.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,这是正确的做法。
UIViewController 专门用于控制全屏视图,而不是子屏幕。在 iOS5 中,有一种以这种方式组合子屏幕视图控制器的机制,但在 iOS4 中,如果没有大量的 hacking,这是不可用的。
在视图和控制器本质上耦合的情况下,您还可以考虑创建一个自定义视图子类作为其自己的控制器,因此例如您可以有一个独立的表视图子类来管理自己的数据,并且可以将其放入一页。
Yes, this is the correct approach.
UIViewControllers are specifically for controlling full-screen views, not for sub-screens. In iOS5 there is a mechanism for composing sub-screen viewcontrollers in this way, but that's not available in iOS4 without lots of hackery.
In cases where the view and controller are inherently coupled, you could also consider making a custom view subclass that is its own controller, so for example you could have a self-contained table view subclass that managed its own data and could just be dropped into a page.
我认为这是一个可以接受的解决方案。
另一个解决方案是创建一个“胖”视图来进行自身控制(例如 MKMapView、UITextView 等)。这可能会使事情更易于管理,并且如果视图非常专业,并且其控制器仅适用于这一类视图,那么您实际上不会失去任何可重用性(因为没有太多)。
I think this is an acceptable solution.
Another solution would be creating a "fat" view that does its controlling itself (like, for instance, MKMapView, UITextView etc.). This might make things a little more manageable, and if the view is very specialized, and its controller is intended to only work with this one class of view, you don't really lose any reusability (because there isn't much).
您的视图不全屏显示并不重要。视图可能(并且通常)由子视图组成,每个子视图都有自己的控制器。
子类化 UIViewController 不会消耗不合理的内存量,因此这不应该是考虑的一部分。
您的解决方案会失去灵活性。您可能会在需要响应 UILifecyle-Messages 或使用其他 UIViewController 功能的上下文中重用您的解决方案。
如果您的视图是轻量级的,您可以考虑使用 UIView 子类并使用委托来处理视图背后的逻辑。
It is not important that your view is not displayed full screen. It is possible (and usual) to have views consisting of subviews which each have their own controller.
Subclassing UIViewController does not consume an unreasonable amount of memory, so this should not be part of the consideration.
With your solution you loose flexibility. It is likely that you will reuse your solution in a context where you need to respond to UILifecyle-Messages or use other UIViewController features.
If your views shall be lightweight you could consider using a UIView subclass and use a delegate for the logic behind your view.
您好,您正在子类化 NSObject 并在其中声明一个 UIView
我建议您应该子类化 UIView,这样您就不必声明额外的视图对象。
因此,您可以简单地引用
self
而不是self.view
Hi You are subclassing NSObject and declaring a UIView inside it
I Suggest you should subclass UIView, so you will not have to declare an additional view object.
so instead of
self.view
you can simply refer asself