0

编辑#1

请阅读问题底部的编辑#1;我试图弄清楚 nib 可用于创建自定义视图的所有方式,因此所有示例都处理 nib 文件。

结尾

我一直在尝试找出在控制器中创建使用 nib 的自定义视图的所有技术。我已经在这个问题的底部列出了这些方法。

这是我的 TRtestview 的代码(我如何进行此设置的一个含义是总是会调用 initWithCoder):

// TRtestview.m
-(id)initWithCoder:(NSCoder *)aDecoder{
    self=[super initWithCoder:aDecoder];
    if (self) {
      if (self.subviews.count == 0) {
        UIView *myView=[[[NSBundle mainBundle] loadNibNamed:@"testview" owner:nil options:nil] lastObject];
        myView.userInteractionEnabled=YES;  // doesn't do anything
        [self addSubview:myView];
      }
    }
    NSLog(@"about to return here in initWithCoder");
    return self;
}

编辑 1

-(void)setup
{
       UIView *myView=[[[NSBundle mainBundle] loadNibNamed:@"testview" owner:nil options:nil] lastObject];
      [self addSubview:myView];
}


- (id)initWithFrame:(CGRect)frame
{
    NSLog(@"at top of initWithFrame");
    self = [super initWithFrame:frame];
    if (self) {
      [self setup];
    }
    return self;
}

在 TRViewController.m 中,我尝试将 thisView 设置为 userInteractionEnabled 但并没有改变:

- (void)viewDidLoad
{
  [super viewDidLoad];
  self.thisView.userInteractionEnabled=YES;

这适用于调用 initWithFrame(技术 #1)和 loadNibNamed(技术 #2)的场景。它将通过将视图从对象检查器中拖出然后在自定义类属性检查器中设置类来加载视图(技术#3)。但是,该按钮不起作用,因此这种方式不起作用。

如何使用技术#3 创建一个带有笔尖的自定义视图并允许用户交互?

谢谢

编辑 1

我真的很想了解可以创建和实例化自定义视图的所有方式。理想情况下,我希望能够拥有可以通过 initWithFrame、loadNibNamed 创建或从对象库中拖动的自定义视图。

场景似乎是:

  1. 来自 ViewController 的 initWithFrame;如果与笔尖一起使用,我会在我的 initWithFrame 中调用 loadNibNamed - 我需要防止递归加载
  2. 来自 ViewController(将调用 initWithCoder)的 loadNibNamed 并且只想加载一次
  3. 拖动 UIView 的实例,然后将自定义类设置为我的自定义 UIView(在本例中为 TRtestview)。这将调用 initWithCoder。
4

1 回答 1

1

看起来您正在从 testview 类初始化程序内部加载 testview,并对子视图进行 hacky 检查以防止它变得递归。由于外面的代码可能也加载了笔尖,所以你实际上在这里做的是加载笔尖两次,一次在另一个里面。如果您设置所有者,那么内部的将在外部设置插座。

这只是一个猜测,因为这里没有足够的信息可以确定 - 但是如果您在视图类中为其中的某些子视图设置插座,那么您必须提供一个具有您的类类型的owner对象。因此,您可以在代码中作为所有者loadNibNamed:owner:options:传递,这可能会起作用。self然而,将笔尖用于单视图确实是错误的方式。

不要将 nib 文件中的单一视图作为TRtestView类,而是将单一视图作为其他内部视图的持有者,并将“文件的所有者”占位符对象设置为具有 class TRtestview。为持有人创建一个出口并分配它,然后执行以下操作:

TRtestview* testview = [[TRtestview alloc] initWithFrame:desiredFrame];
[[NSBundle mainBundle] loadNibNamed:@"testview" owner:testview options:nil];

testview现在,加载笔尖时将设置所有插座,包括您可以添加为子视图的支架。

此外,如果您想在不同的 nib 中使用 TRtestview(例如TestViewController),您可以通过拖动视图并将该对象的类设置为来执行此操作TRtestview- 这将创建一个TRtestview并调用它initWithCoder,您可以将它分配给一个插座TestViewController称为testview。然后在awakeFromNibforTestViewController你将把上面的第二行代码,testview作为所有者对象传入插座。

编辑:很难确切地看到您要做什么,但是从任何视图的 init 方法中加载 nib 都是错误的(加载 nib 会创建视图对象,而不是相反)。我想我起初误解了IBOutlet你要设置的 s 在哪里,可能你正在寻找的答案实际上是你可以加载 nib 但是从这样的类构造函数方法:

+ (MyCustomView*)newCustomView
{
    MyCustomView* view = [[NSBundle mainBundle] loadNibNamed:@"testview" owner:nil options:nil][0];
    // Do custom setup things to view here...
    // Perhaps based on additional inputs to this method.
    view.doStuff;
    return view;
}
于 2013-07-10T23:14:33.617 回答