简体   繁体   English

iPhone Interface Builder 中的自定义控件

[英]Custom Control in iPhone Interface Builder

This appears to be a common question, but I haven't seen it answered clearly or succinctly - and as such I'm having trouble making it work.这似乎是一个常见问题,但我没有看到它得到清晰或简洁的回答 - 因此我无法让它发挥作用。

I have created a Widget.xib file in Interface Builder.我在 Interface Builder 中创建了一个 Widget.xib 文件。 It consists of:它包括:

View (UIView)
  ImageView (UIImageView)
  Button (UIButton)
  Label (UILabel)

I have created Widget.h and Widget.m, which implement class Widget, which derives from UIView.我创建了 Widget.h 和 Widget.m,它们实现了 class Widget,它派生自 UIView。 In Interface Builder, Widget.xib has its File's Owner set to the Widget class.在 Interface Builder 中,Widget.xib 的 File's Owner 设置为 Widget class。

Widget.h looks like this: Widget.h 看起来像这样:

@interface IconView : UIView {
IBOutlet UIButton *widgetButton;
IBOutlet UILabel *widgetLabel;
IBOutlet UIView *widgetView;
IBOutlet UIImageView *widgetImage;
}

@property (nonatomic, retain) IBOutlet UIButton *widgetButton;
@property (nonatomic, retain) IBOutlet UILabel *widgetLabel;
@property (nonatomic, retain) IBOutlet UIView *widgetView;
@property (nonatomic, retain) IBOutlet UIImageView *widgetImage;

Widget.h includes: Widget.h 包括:

@synthesize widgetButton, widgetLabel, widgetView, widgetImage;

And its dealloc releases those four objects.它的 dealloc 释放了这四个对象。 In Interface Builder, the button, label, view, and imageview are all connected to the appropriate IBOutlets.在 Interface Builder 中,按钮、label、视图和 imageview 都连接到相应的 IBOutlets。

Back in Interface Builder, I've opened another XIB from the project.回到 Interface Builder,我从项目中打开了另一个 XIB。 This is Playfield.xib.这是 Playfield.xib。 It's a more traditional view, backed with PlayfieldViewController.h and.m.这是一个更传统的视图,由 PlayfieldViewController.h 和.m 支持。 It contains:它包含:

View (UIView)
  ImageView (with a static graphic) (UIImageView)
  Button (UIButton)
  Widget
  Widget
  Widget

In Playfield.h, I've created IBOutlets for the button and the three Widgets.在 Playfield.h 中,我为按钮和三个小部件创建了 IBOutlets。

@interface LinkViewController : UIViewController {
IBOutlet UIButton *buttonBack;
IBOutlet Widget *widget0;
IBOutlet Widget *widget1;
IBOutlet Widget *widget2;
}

@property (nonatomic, retain) IBOutlet Widget *widget0;
@property (nonatomic, retain) IBOutlet Widget *widget1;
@property (nonatomic, retain) IBOutlet Widget *widget2;
- (IBAction)buttonBackClicked:(id)sender;

These are also synthesized and released in Playfield.h.这些也在 Playfield.h 中合成和发布。 In Interface Builder, Playfield.xib shows three empty rectangles where the widgets have been placed, which is what I expected.在 Interface Builder 中,Playfield.xib 显示了三个放置小部件的空矩形,这是我所期望的。 Those are wired up to their corresponding IBOutlets in Playfield.h.这些连接到 Playfield.h 中相应的 IBOutlets。

So, at this point I assume everything is ready to go.因此,此时我假设 go 一切就绪。 In Playfield.m's viewDidLoad, I do this:在 Playfield.m 的 viewDidLoad 中,我这样做:

self.widget0.label.text = @"Feed Me"; self.widget0.label.text = @"喂我";

In my mind, that references the widget0 IBOutlet declared in Playfield.h.在我看来,这引用了 Playfield.h 中声明的 widget0 IBOutlet。 That connects to the first Widget item in Playfield.xib.它连接到 Playfield.xib 中的第一个 Widget 项。 That, in turn, has a declared label IBOutlet in Widget.xib and Widget.h.反过来,它在 Widget.xib 和 Widget.h 中有一个声明的 label IBOutlet。 A UILabel has a Text property. UILabel 有一个 Text 属性。 So it should change the text on the label within the widget.所以它应该改变小部件内 label 上的文本。

But it doesn't.但事实并非如此。 What am I doing wrong?我究竟做错了什么?

(I want to emphasize that I'm not looking to make an Interface Builder plugin. I know those are complicated. Within IB, I'm fine manipulating my Widgets as empty rectangles. I'll also note that I've set the background color for the widget's View, in Widget.xib, to white. When I run the project, I can clearly see the white rectangles atop the playfield graphic, so I know the widgets are "in" there. I just can't seem to access them.) (我想强调一下,我不想制作一个 Interface Builder 插件。我知道这些很复杂。在 IB 中,我可以将我的小部件操作为空矩形。我还要注意我已经设置了背景Widget.xib 中小部件视图的颜色为白色。当我运行项目时,我可以清楚地看到运动场图形顶部的白色矩形,所以我知道小部件“在”那里。我似乎无法访问它们。)

Where did you call the loadNibNamed:owner:options: method to load your Widget subviews from your Widget.XIB?你在哪里调用了loadNibNamed:owner:options:方法来从你的 Widget.XIB 加载你的 Widget 子视图?

Also you did connect your views in your Widget.XIB file to the File's Owner (which is a Widget object) so the IBOutlets are connected and give you access to the views… but did you add the views as a subview to your Widgets?此外,您确实将 Widget.XIB 文件中的视图连接到文件所有者(这是一个 Widget 对象),因此连接了 IBOutlets 并允许您访问视图……但是您是否将视图作为子视图添加到您的 Widget?

Is the outlet nil when you try to access it using self.widget0.label ?当您尝试使用self.widget0.label访问它时,插座是否为零? Check if self.widget0 is not nil (I guess for that it is OK) but also if self.widget0.label is not nil too (I guess that's the real the problem).检查self.widget0是否不nil (我猜它没问题),但如果self.widget0.label也不nil (我想这是真正的问题)。 If it is, you probably forgot to load your Widget.xib for each widget view.如果是这样,您可能忘记为每个小部件视图加载 Widget.xib。 If it isn't, then it probably means that you have your label, but it isn't added to the view hierarchy.如果不是,则可能意味着您拥有 label,但它没有添加到视图层次结构中。

Your description of your XIB setup doesn't mention the label outlet on Widget being actually connected to its label in the XIB.您对 XIB 设置的描述没有提到 Widget 上的label插座实际上连接到 XIB 中的 label。 Check that, maybe?检查一下,也许? It sounds as if you've got everything else set up, though you don't need to declare the IBOutlet attribute on the instance variable, just the property.听起来好像您已经设置了所有其他内容,尽管您不需要在实例变量上声明IBOutlet属性,只需声明属性即可。

A common one I often miss is setting the class type to widget in IB.我经常错过的一个常见问题是将 class 类型设置为 IB 中的小部件。

在 IB 中选择的 Widget 类的屏幕截图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM