【问题标题】:Custom UIView loaded from Xib从 Xib 加载的自定义 UIView
【发布时间】:2015-02-03 13:26:20
【问题描述】:

我创建了 UIView 的自定义子类以及 xib 文件,并在自定义类中声明了 IBOutlets 和 IBActions。

@interface ContactUsView : UIView

@property (nonatomic, weak) IBOutlet UIButton *displayCloseButton;

- (IBAction)callButtonPressed:(id)sender;
- (IBAction)emailButtonPressed:(id)sender;
- (IBAction)displayCloseButtonPressed:(id)sender;

@end

在 xib 文件中,我拖入了一个 UIView 来表示我的自定义视图。我已经设置:

  • 文件所有者 = 我的自定义类
  • 已将 UIView 中的拖动设置为我的自定义类。

然后我添加了连接到上述 3 种方法的各种按钮。

在 ContactUsView.m 我有以下内容:

- (id)initWithFrame:(CGRect)frame 
{
    if (self = [super initWithFrame:frame]) {
        NSArray* array = [[NSBundle mainBundle] loadNibNamed:@"ContactUsView" owner:self options:nil];
        for (id object in array) {
            if ([object isKindOfClass:[ContactUsView class]])
                self = (ContactUsView *)object;
        }
    }
    return self;
}

当我开始创建此视图时,我会执行以下操作:

- (void)viewWillAppear:(BOOL)animated
{
    ContactUsView *contactUs = [[ContactUsView alloc] initWithFrame:CGRectZero];

    CGPoint origin = self.view.frame.origin;
    CGSize size = self.view.frame.size;
    [contactUs setFrame:CGRectMake(origin.x,
                              CGRectGetMaxY(self.view.frame) - 100,
                              size.width,
                              contactUs.frame.size.height)];

    [self.view addSubview:contactUs];
}

问题 当我按下其中一个按钮时,应用程序崩溃: 线程 1:EXC_BAD_ACCESS(code=2, address=0xb0c

谁能帮我解决这个问题。我觉得在从 xibs 创建和加载自定义 uiview 方面我可能在某处犯了错误。

如果您需要更多信息,请告诉我。非常感谢。

未来参考 使用 xib 创建自定义视图时,请勿设置文件所有者。而是像往常一样创建所有 IBOutlets 和 IBActions,然后将它们连接起来,打开 Utilities 选项卡并从那里控制拖动。

【问题讨论】:

  • 你能发布整个错误吗?或者错误实际发生的那一行?在 XCode 中启用异常断点。
  • 如果我在被调用的方法之一中设置了断点,它永远不会到达断点。它只是与上面的代码崩溃,输出中没有显示任何内容。我添加了一个“所有异常”断点,但输出中仍然没有显示任何内容。

标签: ios objective-c uiview xib custom-view


【解决方案1】:

• 文件所有者 = 我的自定义类

错了。文件所有者应为空。视图本身是文件所有者。这意味着您应该在您的 xib 中使用ContactUsView 连接所有操作和出口。

[[NSBundle mainBundle] loadNibNamed:@"ContactUsView" owner:self options:nil]

...

self = (ContactUsView *)object;

在您将self 传递为owner参数之后。你改变它。这意味着先前分配的ContactUsView (self) 将被销毁,因为-loadNibNamed:owner:options: 不保留它。如果您应用我的第一个建议,您应该将nil 作为owner 参数发送

forloop 这里没有必要只使用array[0],因为如果您的 xib 中有有效的视图层次结构,这始终是您的视图

【讨论】:

  • 非常感谢精灵宝钻。这已经解决了我的问题。为了将来创建自定义视图时参考,您需要打开实用程序标签并从那里控制拖动。
【解决方案2】:

如果您正在为 xib 加载 UIView,那么您应该创建一个类方法来加载视图。

在你的 customview.h 中

+(id)customView;

& 在您的 customview.m 中

+ (id)customView
{
    CustomView *customView = [[[NSBundle mainBundle] loadNibNamed:@"CustomView" owner:nil options:nil] lastObject];
    if ([customView isKindOfClass:[CustomView class]])
        return customView;
    else
        return nil;
}

你可以在任何地方初始化它:

CustomView *myView = [CustomView customView];

编辑:确保您在身份检查器中更改了自定义视图的类,并确保您的 IBActions 连接使用该类的方法。

【讨论】:

  • 嗨,阿杰。是的,我可能会将其实现为类方法。但是,您方法中的代码与我的代码相同,仍然会导致相同的崩溃。
  • Silmaril 的回答让我意识到我做错了什么。在看到您编辑的具有相同解决方案的答案之前,我已经接受了他的答案。我也对你的答案投了赞成票。非常感谢。
【解决方案3】:

您可以为此使用委托 这就是你可以这样做的方法

        @protocol CustomViewDelegate <NSObject>
- (void)callButtonPressed:(id)sender;
- (void)emailButtonPressed:(id)sender;
- (void)displayCloseButtonPressed:(id)sender;

@end

@interface ContactUsView : UIView

@property (nonatomic, weak) IBOutlet UIButton *displayCloseButton;

@property (nonatomic, weak) id<CustomViewDelegate> ButtonDelegate;

- (IBAction)callButtonPressed:(id)sender;

- (IBAction)emailButtonPressed:(id)sender;
- (IBAction)displayCloseButtonPressed:(id)sender;


@end

在.m文件中

- (IBAction)callButtonPressed:(id)sender
{
[self.ButtonDelegate callButtonPressed:sender];
}

- (IBAction)emailButtonPressed:(id)sender{
[self.ButtonDelegate emailButtonPressed:sender];
}

- (IBAction)displayCloseButtonPressed:(id)sender{
[self.ButtonDelegate displayCloseButtonPressed:sender];
}

之后,只需使用 viewcontroller refrence 设置委托并在此处使用这些委托

- (void)viewWillAppear:(BOOL)animated

{

ContactUsView *contactUs = [[ContactUsView alloc] initWithFrame:CGRectZero];
contactUs.ButtonDelegate = self;

CGPoint origin = self.view.frame.origin;
CGSize size = self.view.frame.size;
[contactUs setFrame:CGRectMake(origin.x,
                          CGRectGetMaxY(self.view.frame) - 100,
                          size.width,
                          contactUs.frame.size.height)];

[self.view addSubview:contactUs];

}

- (void)callButtonPressed:(id)sender

{}

- (void)emailButtonPressed:(id)sender

{}

- (void)displayCloseButtonPressed:(id)sender

{}

我已经做到了,并且工作得很好

【讨论】:

  • 感谢您的回复。您是否以与我相同的方式加载 xib?当我单击与 IBAction 相关联的按钮时,我的应用程序崩溃。但是,它立即崩溃,这意味着该方法中没有任何事情发生。如果在我看来,加载视图时与内存有关。
猜你喜欢
  • 2017-10-01
  • 2020-05-16
  • 1970-01-01
  • 2016-07-31
  • 1970-01-01
  • 2016-10-31
  • 2015-04-08
  • 1970-01-01
  • 2019-11-26
相关资源
最近更新 更多