从 XIB 加载自定义视图,如何使其响应自定义子类?

Posted

技术标签:

【中文标题】从 XIB 加载自定义视图,如何使其响应自定义子类?【英文标题】:Loading Custom View from XIB, How to Make it Respond to Custom Subclass? 【发布时间】:2016-02-24 21:35:18 【问题描述】:

我创建了一个带有 XIB (MyXIB) 的视图并创建了一个 UIView 子类 (MyViewSubclass)。我将MyViewSubclass 设置为MyXIB 视图的“自定义类”。

我已将MyXIB 中的按钮连接到MyViewSubclass 中的 IBAction。

在应用程序的主视图控制器中,我调用:

NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"MyXIB" owner:self options:nil];
MyUIViewSubclass *myView = [subviewArray objectAtIndex:0];
[self.view addSubview:myView];

这可以将新视图添加到现有视图控制器之上,但是每当我从MyXIB 中点击按钮时,应用程序就会崩溃并说它是sending an unrecognized selector 到父视图控制器。

如何获得MyXIB 上的按钮以调用MyViewSubclass 中的IBAction?

【问题讨论】:

您必须将按钮操作连接到您的视图控制器类。不是你的自定义视图类。 确保您的自定义视图文件所有者是您的视图控制器。 那么如果我想在我的应用程序的许多不同的屏幕上显示MyXIB,我是否需要在每个访问MyXIB的UIViewController中实现按钮的方法? 对于您所描述的,我建议您在MyXIB 中创建一个protocol,然后在任何必要的控制器上实现您的协议方法。 【参考方案1】:

如果你打算在其他视图控制器中使用该视图,你应该创建一个delegate protocol,如下:

MyXIB.h

#import <UIKit/UIKit.h>

@protocol MyXIBDelegate <NSObject>

@required // if it's not necessary, you can use @optional
- (void)myXIBDelegateMethod;

@end

@interface MyXIB : UIView

@property (weak, nonatomic) id<MyXIBDelegate> delegate;

@end

MyXIB.m

#import "MyXIB.h"

@implementation MyXIB

- (IBAction)buttonAction:(id)sender 
    if (self.delegate && [self.delegate respondsToSelector:@selector(myXIBDelegateMethod)]) 
        [self.delegate myXIBDelegateMethod];
    


@end

由于您的 UIButton 的操作在 MyXIB 视图中链接,因此当按下按钮时,您检查是否设置了 delegate 属性以及它是否响应您的委托方法,然后您调用协议的方法。

@implementation 部分的视图控制器.m 文件中,您将拥有如下内容:

#import "ViewController.h"
#import "MyXIB.h"

@interface ViewController () <MyXIBDelegate>

@end

由于协议方法是@required,你必须在视图控制器中实现该方法:

#pragma mark - MyXIB Delegate Method

- (void)myXIBDelegateMethod 
    // your implementation

【讨论】:

以上是关于从 XIB 加载自定义视图,如何使其响应自定义子类?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 XIB 文件加载自定义创建的视图并添加到 StackView

添加和布局从 xib 加载的子视图到自定义单元格

UIView:从自定义 XIB 加载导致崩溃

从 .xib 加载自定义视图不适合 iPhone 6+

如何获取从 nib ios 加载的自定义视图的实际大小

从 XIB 文件中为 ViewController 视图加载自定义 UIView