我知道这很简单,但是在拉扯太多头发之后,我离解决方案还差得很远。
我已经看到了解释如何使用 XIB 和所有创建视图的教程。但他们都没有解决我在这里遇到的情况。
我有一个 XIB 文件,一个自定义 UIView 子类,标签和按钮很少。UIView 子类是可重用的,这就是我在任何单个 View 控制器中都不能有插座的原因。结果,我将此视图的各个控件(子视图)存储在我的自定义 UIView 本身中。这是合乎逻辑的,因为任何视图控制器都不应拥有此自定义视图的子视图,该自定义视图将包含在每个视图控制器中。
问题是,我不知道如何完全初始化整个 UI。
这是我的 UIView 子类代码:
@interface MCPTGenericView : UIView
+(id)createInstance : (bool) bPortrait;
@property (weak, nonatomic) IBOutlet UIView *topView;
@property (weak, nonatomic) IBOutlet UIView *titleView;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UIButton *logoButton;
@property (weak, nonatomic) IBOutlet UITextField *searchTextField;
@property (weak, nonatomic) IBOutlet UIButton *menuButton;
@end
稍后,我还计划将此相同的 XIB 文件也用于此 UIView 的横向,并且我计划在同一 XIB 中使用与横向控件相同的上述插座。
这是实现:
@implementation MCPTGenericView
//@synthesize topView, titleLabel, titleView;
+(id)createInstance : (bool) bPortrait
{
UIView * topLevelView = nil;
MCPTGenericView * instance = [MCPTGenericView new];
NSArray * views = [[NSBundle mainBundle] loadNibNamed:@"MoceptGenericView" owner:instance options:nil];
int baseTag = (bPortrait)?PORTRAIT_VIEW_TAG_OFFSET:LANDSCAPE_VIEW_TAG_OFFSET;
// make sure customView is not nil or the wrong class!
for (UIView * view in views)
{
if (view.tag == baseTag)
{
topLevelView = view;
break;
}
}
instance.topView = (MCPTGenericView *)[topLevelView viewWithTag:baseTag + 1];
instance.searchTextField = (UITextField *)[topLevelView viewWithTag:baseTag + 2];
instance.menuButton = (UIButton *)[topLevelView viewWithTag:baseTag + 3];
instance.logoButton = (UIButton *)[topLevelView viewWithTag:baseTag + 4];
instance.titleView = [topLevelView viewWithTag:baseTag + 5];
instance.titleLabel = (UILabel *)[topLevelView viewWithTag:baseTag + 6];
return instance;
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
if ((self = [super initWithCoder:aDecoder]))
{
[self addSubview:[[[NSBundle mainBundle] loadNibNamed:@"MCPTGenericView" owner:self options:nil] objectAtIndex:0]];
}
return self;
}
-(void)awakeFromNib
{
[super awakeFromNib];
[self addSubview: self.titleView];
[self addSubview:self.topView];
}
- (id) init
{
self = [super init];
if (self)
{
[[NSBundle mainBundle] loadNibNamed:@"MCPTGenericView" owner:self options:nil];
[self addSubview:self.topView];
[self addSubview:self.titleView];
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// Initialization code
[[NSBundle mainBundle] loadNibNamed:@"MCPTGenericView" owner:self options:nil];
[self addSubview:self.topView];
[self addSubview:self.titleView];
}
return self;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
@end
有用的东西:
我成功地从我的视图控制器调用initWithFrame:frame
。这样,我可以看到所有控件都已正确初始化。但是,如果我已经绘制了 XIB,为什么还要提供框架呢?loadNibNamed 不应该处理框架设置和布局的东西,因为这是 XIB 的预期用途?
我也对 loadNibNamed 需要所有者对象的方式感到困惑。为什么我们已经需要一个对象来从 XIB 获取相同的对象?那也是半生不熟的吗?
请帮忙...