我设法使用nib设置自定义UIView类。
我的.h看起来像
@interface MyView : UIView <UITextFieldDelegate>
@property (nonatomic, weak) IBOutlet UITextField *textField;
@property (nonatomic, strong) MyView *topView;
和.m
@implementation MyView
NSString *_detail;
-(id)initWithCoder:(NSCoder *)aDecoder{
if ((self = [super initWithCoder:aDecoder])&&self.subviews.count==0){
MyView *v = [[[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil] objectAtIndex:0];
self.textField = v.textField;
if (self.topView == nil)self.topView = self;
v.topView = self.topView;
[self addSubview:v];
}
return self;
}
-(NSString *)topDetail{
return _detail;
}
-(NSString *)detail{
return [self.topView topDetail];
}
-(void)setTopDetail:(NSString *)detail{
_detail = detail;
}
-(void)setDetail:(NSString *)detail{
[self.topView setTopDetail:detail];
}
- (BOOL)textFieldShouldReturn{
//here I show an UIAlertView using self.detail for the message
}
注意:我的设置完全符合我的要求。
问题
我想要做的是删除我的手动detail
方法并将NSString *_detail
转为@property (...)NSString *detail
当我使用@property
尝试时,如果我打电话给我ViewController
myView.detail = someString
,myView将引用最顶层的视图。然后,如果因用户互动而调用textFieldShouldReturn
,则会调用尚未设置的嵌套MyView
s _detail
。
我想要的是什么:
无论我在何处访问_detail
,都无需编写额外的代码来访问{{1}}。我只想声明属性并继续我的常规编码。
答案 0 :(得分:1)
您的问题是,您尝试使用对象属性保留类引用topView
。
换句话说,每个物品都是&#39; topView
是对象本身,没有任何意义。
您的定义应该是:
@interface MyView : UIView <UITextFieldDelegate>
// Class "properties"
+ (instancetype)topview;
+ (void)setTopView:(UIView *)topView;
// Object properties
@property (nonatomic, weak) IBOutlet UITextField *textField;
@property (nonatomic, strong) NSString *detail;
现在,您可以跟踪topView
:
static MyView * _topView;
@implementation MyView
+ (instancetype)topView {return _topView}; // You could also create one here lazily
+ (void)setTopView:(UIView *)topView { _topView = topView };
-(id)initWithCoder:(NSCoder *)aDecoder{
if ((self = [super initWithCoder:aDecoder])&&self.subviews.count==0){
JUITextFieldHint *v = [[[NSBundle mainBundle] loadNibNamed:@"JUITextFieldHint" owner:self options:nil] objectAtIndex:0];
self.textField = v.textField;
if ([MyView topView] == nil)[MyView setTopView:self];
v.topView = self.topView;
[self addSubview:v];
}
return self;
}
不再需要手动设置器和吸气器。现在,您可以使用detail
属性,anyInstance.detail
或[MyView topView].detail
,甚至是MyView.topView.detail
,如果您喜欢像我这样的点;)
你的init
方法仍然看起来很奇怪,但应该有用。检查Apples init
模板。
最后,textField
只要有超级视图就会很弱,否则会strong
。
答案 1 :(得分:0)
我的xib包含一个UIView(无控制器)。我为该课程设置了UIView
MyView
。
我将UIView
更改回UIView
,然后将File's Owner
设置为MyView
。这解决了递归问题(这就是为什么我首先有这么奇怪的设置)并导致我的变量和IBOutlets正确链接。
归功于How do I create a custom iOS view class and instantiate multiple copies of it (in IB)?以及我在前几次阅读时错过的一些评论。