自定义UIView变量/属性Access

时间:2014-03-22 00:52:19

标签: ios objective-c uiview

我设法使用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}}。我只想声明属性并继续我的常规编码。

2 个答案:

答案 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)?以及我在前几次阅读时错过的一些评论。