Iphone 最佳实践:将子类UIView(具有自己的xib)作为UIViewController的子视图
我的目标是,在自己的XIB中设计一个子类Iphone 最佳实践:将子类UIView(具有自己的xib)作为UIViewController的子视图,iphone,ios,uiview,uiviewcontroller,interface-builder,Iphone,Ios,Uiview,Uiviewcontroller,Interface Builder,我的目标是,在自己的XIB中设计一个子类UIView(我们称之为infoView),这样我就可以在许多UIViewController中展示它 问题是: 到目前为止,当我将UIView添加到UIViewController时,我始终必须使UIViewController成为UIView的.xib文件的所有者,以加载视图,例如: ... //this is inside the calling UIViewController's method // InfoView *infoView is i
UIView
(我们称之为infoView
),这样我就可以在许多UIViewController
中展示它
问题是:
到目前为止,当我将UIView
添加到UIViewController
时,我始终必须使UIViewController
成为UIView
的.xib文件的所有者,以加载视图,例如:
...
//this is inside the calling UIViewController's method
// InfoView *infoView is ivar and a subclass of UIView
infoView = nil;
NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:@"InfoView"
owner:self options:nil];
for (id object in bundle) {
if ([object isKindOfClass:[InfoView class]])
infoView = (InfoView *)object;
}
[[self view] addSubview:infoView];
...
但是我想在许多不同的UIViewController
中使用相同的UIView
,所以我实际上不想要文件的所有者,除了类本身。在中,他将UIView
本身设置为文件的所有者,但没有成功
在那里的答案中,我找到了一个解决方案,将文件的所有者设置为零。为此,我必须将所有调用的UIViewController
对象从Interface Builder对象库添加到InfoView.xib文件中,并将它们与InfoView
插座连接起来
但这感觉不对所以我想在这里收集解决方案将
UIView
与他的xib文件封装在一起,以便在许多不同的视图控制器中使用它。你们是怎么处理的?
谢谢你的帮助
编辑:
infoView
类似于一个覆盖,当用户按下其中一个视图控制器上的按钮时,它就会出现。它不是视图控制器的“主”视图。它提供有关其superviews视图控制器视图的详细信息,随后将消失。我只使用不同的内容填充infoView
,所有调用的视图控制器都被丢弃。infoView需要是子视图吗
在viewController中:
-(id) init {
self = [super initWithNibName:@"myNib" bundle:nil];
if (self) {
// code here
}
}
因此,您希望从要在多个
UIViewController
中使用的nib加载UIView
,并将其连接到每个视图控制器上的插座。对吗
然后用IBOutlet
属性创建一个UIViewController
子类(我们称之为FakeViewController
)。将该FakeViewController
设置为nib文件的所有者,并将您的UIView
连接到其出口
完成了
您只需确保所有其他视图控制器也具有这些outlet属性(尽管它们不需要是IBOutlets
),但nib加载程序不会实际检查以确保传递到owner
参数的类等于您在Interface Builder中指定的类名。所以你可以假装
哦,如果您是OS4.0或更高版本,请使用UINib
加载nib文件。就像Hollence指出的那样,我正在使用UINib
要使用它,请保留.xib文件所有者nil
,并将infoView的所有自定义项放在infoView类实现的initWithCoder:
方法中。如果您获得InfoView.xib
之类的文件,则会调用此文件:
// here InfoView is the name of the .xib file
UINib *infoNib = [UINib nibWithNibName:@"InfoView" bundle:nil];
NSArray *topLevelObjects = [infoNib instantiateWithOwner:self options:nil];
QInfoView *infoView = [topLevelObjects objectAtIndex:0];
另一种方法是基于
NSObject
创建自己的“控制器”,以定义自己的生命周期(而不是标准的UIViewController
生命周期)
例如:
BaseSubview.h:
@interface BaseSubview : NSObject {
UIView* _view;
}
@property (nonatomic, retain) IBOutlet UIView* view;
- (void)myMethod;
@end
#import "BaseSubview.h"
@implementation BaseSubview
@synthesize view = _view;
- (id)init
{
self = [super init];
if (self) {
// ...
}
return self;
}
- (void)dealloc
{
[_view removeFromSuperView];
[super dealloc];
}
- (void)myMethod
{
// view specific logic here
_view.backgroundColor = [UIColor redColor];
}
@end
#import "BaseSubview"
@interface InfoView : BaseSubview {
UILabel* _labelInfo;
}
@property (nonatomic, retain) IBOutlet UILabel* labelInfo;
@end
#import "InfoView.h"
@implementation InfoView
@synthesize labelInfo = _labelInfo;
- (id)init
{
self = [super init];
if (self) {
// ...
}
return self;
}
- (void)myMethod
{
// view specific logic here
_labelInfo.text = @"current time...";
[super myMethod];
}
@end
// ...
// among other var definitions
InfoView* _infoView;
// ...
BaseSubview.m:
@interface BaseSubview : NSObject {
UIView* _view;
}
@property (nonatomic, retain) IBOutlet UIView* view;
- (void)myMethod;
@end
#import "BaseSubview.h"
@implementation BaseSubview
@synthesize view = _view;
- (id)init
{
self = [super init];
if (self) {
// ...
}
return self;
}
- (void)dealloc
{
[_view removeFromSuperView];
[super dealloc];
}
- (void)myMethod
{
// view specific logic here
_view.backgroundColor = [UIColor redColor];
}
@end
#import "BaseSubview"
@interface InfoView : BaseSubview {
UILabel* _labelInfo;
}
@property (nonatomic, retain) IBOutlet UILabel* labelInfo;
@end
#import "InfoView.h"
@implementation InfoView
@synthesize labelInfo = _labelInfo;
- (id)init
{
self = [super init];
if (self) {
// ...
}
return self;
}
- (void)myMethod
{
// view specific logic here
_labelInfo.text = @"current time...";
[super myMethod];
}
@end
// ...
// among other var definitions
InfoView* _infoView;
// ...
InfoView.h:
@interface BaseSubview : NSObject {
UIView* _view;
}
@property (nonatomic, retain) IBOutlet UIView* view;
- (void)myMethod;
@end
#import "BaseSubview.h"
@implementation BaseSubview
@synthesize view = _view;
- (id)init
{
self = [super init];
if (self) {
// ...
}
return self;
}
- (void)dealloc
{
[_view removeFromSuperView];
[super dealloc];
}
- (void)myMethod
{
// view specific logic here
_view.backgroundColor = [UIColor redColor];
}
@end
#import "BaseSubview"
@interface InfoView : BaseSubview {
UILabel* _labelInfo;
}
@property (nonatomic, retain) IBOutlet UILabel* labelInfo;
@end
#import "InfoView.h"
@implementation InfoView
@synthesize labelInfo = _labelInfo;
- (id)init
{
self = [super init];
if (self) {
// ...
}
return self;
}
- (void)myMethod
{
// view specific logic here
_labelInfo.text = @"current time...";
[super myMethod];
}
@end
// ...
// among other var definitions
InfoView* _infoView;
// ...
InfoView.m:
@interface BaseSubview : NSObject {
UIView* _view;
}
@property (nonatomic, retain) IBOutlet UIView* view;
- (void)myMethod;
@end
#import "BaseSubview.h"
@implementation BaseSubview
@synthesize view = _view;
- (id)init
{
self = [super init];
if (self) {
// ...
}
return self;
}
- (void)dealloc
{
[_view removeFromSuperView];
[super dealloc];
}
- (void)myMethod
{
// view specific logic here
_view.backgroundColor = [UIColor redColor];
}
@end
#import "BaseSubview"
@interface InfoView : BaseSubview {
UILabel* _labelInfo;
}
@property (nonatomic, retain) IBOutlet UILabel* labelInfo;
@end
#import "InfoView.h"
@implementation InfoView
@synthesize labelInfo = _labelInfo;
- (id)init
{
self = [super init];
if (self) {
// ...
}
return self;
}
- (void)myMethod
{
// view specific logic here
_labelInfo.text = @"current time...";
[super myMethod];
}
@end
// ...
// among other var definitions
InfoView* _infoView;
// ...
InfoView.xib:
@interface BaseSubview : NSObject {
UIView* _view;
}
@property (nonatomic, retain) IBOutlet UIView* view;
- (void)myMethod;
@end
#import "BaseSubview.h"
@implementation BaseSubview
@synthesize view = _view;
- (id)init
{
self = [super init];
if (self) {
// ...
}
return self;
}
- (void)dealloc
{
[_view removeFromSuperView];
[super dealloc];
}
- (void)myMethod
{
// view specific logic here
_view.backgroundColor = [UIColor redColor];
}
@end
#import "BaseSubview"
@interface InfoView : BaseSubview {
UILabel* _labelInfo;
}
@property (nonatomic, retain) IBOutlet UILabel* labelInfo;
@end
#import "InfoView.h"
@implementation InfoView
@synthesize labelInfo = _labelInfo;
- (id)init
{
self = [super init];
if (self) {
// ...
}
return self;
}
- (void)myMethod
{
// view specific logic here
_labelInfo.text = @"current time...";
[super myMethod];
}
@end
// ...
// among other var definitions
InfoView* _infoView;
// ...
- 文件所有者是InfoView
- 照常分配门店
- 视图是所有其他控件(如标签等)的父控件。
@interface BaseSubview : NSObject {
UIView* _view;
}
@property (nonatomic, retain) IBOutlet UIView* view;
- (void)myMethod;
@end
#import "BaseSubview.h"
@implementation BaseSubview
@synthesize view = _view;
- (id)init
{
self = [super init];
if (self) {
// ...
}
return self;
}
- (void)dealloc
{
[_view removeFromSuperView];
[super dealloc];
}
- (void)myMethod
{
// view specific logic here
_view.backgroundColor = [UIColor redColor];
}
@end
#import "BaseSubview"
@interface InfoView : BaseSubview {
UILabel* _labelInfo;
}
@property (nonatomic, retain) IBOutlet UILabel* labelInfo;
@end
#import "InfoView.h"
@implementation InfoView
@synthesize labelInfo = _labelInfo;
- (id)init
{
self = [super init];
if (self) {
// ...
}
return self;
}
- (void)myMethod
{
// view specific logic here
_labelInfo.text = @"current time...";
[super myMethod];
}
@end
// ...
// among other var definitions
InfoView* _infoView;
// ...
HugeAndComplementedViewController.m,最有趣的部分:
// when you decide to show your view
// probably in loadView
_infoView = [[InfoView alloc] init];
[[NSBundle mainBundle] loadNibNamed:@"InfoView" owner:_infoView options:nil];
[self.view addSubview:_infoView.view];
// possibly perform specific logic
[_infoView myMethod];
// no need sub-view any more
// probably in dealloc
[_infoView release];
所以现在您有了自己的子视图,逻辑和设计与“庞大而复杂”的视图控制器分离。它可以具有当前项目所需的任何生命周期。是的,它必须是子视图。这对我的问题不起作用。infoView不是viewController的“主”视图。它更多的是一个叠加,按需显示,例如按信息按钮。多多少少有点像UIAlertView…你明白我的意思了!虽然我喜欢您使用face ViewController的想法,但这种方法感觉不太正确,因为在示例中,他们说:“您不应该使用多个自定义视图控制器来管理同一视图层次结构的不同部分”。但是非常感谢您指出UINib类!在我的理解中,UIViewController类似于UIView,具有额外的层次逻辑,我不需要在屏幕上显示部分视图。FakeViewController仅用于将UIView连接到您正在加载它的任何视图控制器的出口。因此,您可以让ViewControllerA、ViewControllerB和ViewControllerC加载UIView,即使它们是不同的类。UIView认为它正在加载到FakeViewController中,但实际上没有FakeViewController的实例,您正在将它加载到ViewControllerA/B/C中。好的,谢谢!因此,您认为这种方法比我在上面描述的方法更有效吗?我在上面描述的方法是将视图控制器对象添加到xib文件中,以便将每个视图控制器的出口与视图连接起来?是的。虽然我不确定你是如何添加所有这些视图控制器的;作为真实视图控制器对象还是占位符?您可能对我在回答这个问题时所描述的“具有xib的可重用UIView小部件”问题的解决方案感兴趣:@Bogatyr thx,这是一个很好的答案。