How to load a `.xib` / `.nib` file within a framework?

痞子三分冷 提交于 2020-01-30 12:26:09

问题


I'm working on an iOS library as a Cocoa Pod. In this library, I have a custom view:

@interface PlayerView : UIView

@property (strong, nonatomic) IBOutlet UIView *contentView;

@end
@implementation PlayerView

- (instancetype) initWithCoder:(NSCoder*)coder
{
    self = [super initWithCoder:coder];
    [self initialize];
    return self;
}

- (instancetype) initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    [self initialize];
    return self;
}

- (void)initialize
{
    [[NSBundle mainBundle] loadNibNamed:@"PlayerView" owner:self options:nil];
    [self addSubview:contentView];
}

@end

In this case contentView is the entire View defined in the .xib, which includes an image and a label.

When I build my demo app (and the library) the app runs, but when it comes time to display this view I get the following error:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/stevenbarnett/Library/Developer/CoreSimulator/Devices/EC244A5F-CE57-4CCD-9BB4-CDC834D74812/data/Containers/Bundle/Application/446EB609-B663-4BD5-8F8D-F22D03BC0B18/bfsdk_Example.app> (loaded)' with name 'PlayerView''

Inspecting the .app file by hand, the PlayerView.nib file can be found buried in the Frameworks/bfsdk.framework directory, but I'm guessing since it's not at the root it isn't being located:

I've verified:

  • That the file owner is set to PlayerView
  • That PlayerView.xib is added to the "copy bundle resources" build phase

How can I load a .xib file that's within my library from a class that's within my library when running an app that just includes my library as a .framework?

I believe I could get it working if I manually specified the path to the file with something like:

NSString* resourcePath = [[NSBundle mainBundle] pathForResource:@"bfsdk" ofType:@"framework"];
[[NSBundle mainBundle] loadNibNamed:[resourcePath stringByAppendingPathComponent:@"PlayerView"]];

However I don't like that this has me hard-coding my framework's name into one of my classes. If I change the name in a year I don't want everything to break because of this one buried line of code that no one remembers exists.


回答1:


It should be enough to use

[NSBundle bundleForClass:[self class]] instead of [NSBundle mainBundle]

So basically [NSBundle mainBundle] returns bundle for current module which is your app, but not the actual framework

Here you can find more details [NSBundle bundleForClass:[self class]]] what does that mean?



来源:https://stackoverflow.com/questions/57013152/how-to-load-a-xib-nib-file-within-a-framework

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!