IBOutlet 未在 awakeFromNib 中连接

发布于 2024-11-27 16:17:46 字数 1477 浏览 2 评论 0原文

此处链接的示例代码效果很好,允许 UIScrollView 显示分页图像并预览当前图像之前和之后的图像:

我尝试将示例封装在可以重用的单个控件中。所以我创建了一个 PagingScrollView:

@interface PagingScrollView : UIView {
    IBOutlet UIScrollView * scrollView;
}

@property (nonatomic,retain) IBOutlet UIScrollView * scrollView;

@end

使用简单的实现

- (void) awakeFromNib
{
    [super awakeFromNib];

    NSLog(@"awake from nib");
}

在 PagingScrollView.xib 中,我放置了一个包含 UIScrollView 和 ARScrollViewEnhancer 的视图,与原始 ScrollViewPagingExampleViewController xib 中完全相同。其文件所有者的类设置为 PagingScrollView,其滚动视图出口设置为子 UIScrollView。

在 ScrollViewPagingExampleViewController 中,我只需声明:

IBOutlet PagingScrollView   *pagingScrollView;

在 IB 中,我拖动一个 View,将其类设置为 PagingScrollView,并将其 pagingScrollView 出口挂接到 PagingScrollView。

在 awakeFromNib 中,scrollView 属性为 nil。我认为,由于scrollView是在同一个笔尖的IB中连接的,所以此时它就可用了。

令人困惑的是,在 ScrollViewPagingExampleViewController.xib 中,有一个名为scrollView 的空插座。这可能表明 PagingScrollView 的实例与 PagingScrollView.xib 中定义的实例不同。

因此,我无法使用实际的子视图填充 UIScrollView。我在这里做错了什么?

The sample code linked here works great and allows a UIScrollView to display images with paging and preview of the images before and after the current image:

I'm trying to encapsulate the example in a single control that can be reused. So I created a PagingScrollView:

@interface PagingScrollView : UIView {
    IBOutlet UIScrollView * scrollView;
}

@property (nonatomic,retain) IBOutlet UIScrollView * scrollView;

@end

with dirt simple implementation

- (void) awakeFromNib
{
    [super awakeFromNib];

    NSLog(@"awake from nib");
}

In PagingScrollView.xib, I put a View containing a UIScrollView and a ARScrollViewEnhancer exactly as in the original ScrollViewPagingExampleViewController xib. Its File's Owner's class is set to PagingScrollView, and its scrollView outlet is set to the child UIScrollView.

In ScrollViewPagingExampleViewController, I simply declare:

IBOutlet PagingScrollView   *pagingScrollView;

And in IB, I drag a View, set its class to PagingScrollView, and hook up its pagingScrollView outlet to the PagingScrollView.

In awakeFromNib, the scrollView property is nil. I would think that since the scrollView is hooked up in IB in the same nib, it would be available by this point.

Confusingly, in ScrollViewPagingExampleViewController.xib, there is an empty outlet named scrollView. This might indicate that there is a different instance of PagingScrollView than the one defined in PagingScrollView.xib.

As a result, I can't populate the UIScrollView with the actual child views. What am I doing wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

染柒℉ 2024-12-04 16:17:47

使用 Swift,您可以在设置后在自定义视图中使用 item:

class PointsTableViewCell: UITableViewCell {

    @IBOutlet weak var pointsTitleLabel: UILabel! {
        didSet {
            self.pointsTitleLabel.text = "Points"
        }
    }
}

Using Swift you can use item inside your custom view after it's set:

class PointsTableViewCell: UITableViewCell {

    @IBOutlet weak var pointsTitleLabel: UILabel! {
        didSet {
            self.pointsTitleLabel.text = "Points"
        }
    }
}
深爱成瘾 2024-12-04 16:17:46

这个问题有一个很好的答案: Accessing View in awakeFromNib?

长话短说,视图可能会在 awakeFromNib 中加载,但其内容会延迟加载,这就是为什么您应该使用 viewDidLoad 而不是 awakeFromNib 来实现您想要实现的目标。

There is a very good answer to this question here: Accessing View in awakeFromNib?

Long story short, the view may be loaded in awakeFromNib, but its contents are loaded lazily, which is why you should use viewDidLoad instead of awakeFromNib for what you are trying to achieve.

空心↖ 2024-12-04 16:17:46

对于任何在 Swift 4 中寻找合适答案的人来说,就在这里。

override func awakeAfter(using aDecoder: NSCoder) -> Any? {
    guard subviews.isEmpty else { return self }
    return Bundle.main.loadNibNamed("MainNavbar", owner: nil, options: nil)?.first
}

尽管如此,我发现真正的秘密是您不要对 .xib 文件的主视图进行子类化。相反,让文件所有者成为您想要的类,并像这样在类 init 中添加 Nib:

let bundle: Bundle = Bundle(for: type(of: self))
let nib: UINib = UINib(nibName: "<Nib File Name>", bundle: bundle)
if let view = nib.instantiate(withOwner: self, options: nil).first as? UIView {
    view.frame = bounds
    view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    view.translatesAutoresizingMaskIntoConstraints = true
    addSubview(view)
}

For anyone finding this looking for the appropriate answer in Swift 4, here you go.

override func awakeAfter(using aDecoder: NSCoder) -> Any? {
    guard subviews.isEmpty else { return self }
    return Bundle.main.loadNibNamed("MainNavbar", owner: nil, options: nil)?.first
}

Although, I found the real secret to be that you don't subclass the main view of a .xib file. Instead make the file owner the class you want it to be and add the Nib like so inside of the classes init:

let bundle: Bundle = Bundle(for: type(of: self))
let nib: UINib = UINib(nibName: "<Nib File Name>", bundle: bundle)
if let view = nib.instantiate(withOwner: self, options: nil).first as? UIView {
    view.frame = bounds
    view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    view.translatesAutoresizingMaskIntoConstraints = true
    addSubview(view)
}
孤独岁月 2024-12-04 16:17:46

我遇到了这个问题,和你一样,其他文章不适用。我有一个 ViewController,它有自己的视图。在该 ViewController 的 .xib 文件中,我放置了一个视图并为其指定了 CustomView 类。除了 CustomView 是在它自己的 .xib 文件中定义的事实之外,这会很好用,所以自然在 awakeFromNib 中所有 IBOutlet 都是 nil。这是因为界面生成器中无法将 .xib 文件链接在一起。因此,当我的 ViewController 的视图显示在屏幕上时,它会尝试实例化 CustomView,而不是加载 CustomView.xib 文件。

这里有一个详细的解决方法 http://cocoanuts.mobi/2014/03/26/reusable /,但要点是我必须在我的 CustomView 类中实现以下内容

@implementation CustomView

    - (id)awakeAfterUsingCoder:(NSCoder *)aDecoder
    {
        if (![self.subviews count])
        {
            NSBundle *mainBundle = [NSBundle mainBundle];
            NSArray *loadedViews = [mainBundle loadNibNamed:@"CustomView" owner:nil options:nil];
            return [loadedViews firstObject];
        }
        return self;
    }

@end

I was having this problem and like you the other articles didn't apply. I had a ViewController, which had its own view. In that ViewController's .xib file I put a view and gave it the class of CustomView. This would work great except for the fact that CustomView was defined in its own .xib file, so naturally in awakeFromNib all the IBOutlets were nil. This is because there is no way in interface builder to link .xib files together. So when my ViewController's view gets put on screen it tries to instantiate CustomView, rather than loading the CustomView.xib file.

There is a work around detailed here http://cocoanuts.mobi/2014/03/26/reusable/, but the gist is I had to implement the following in my CustomView class

@implementation CustomView

    - (id)awakeAfterUsingCoder:(NSCoder *)aDecoder
    {
        if (![self.subviews count])
        {
            NSBundle *mainBundle = [NSBundle mainBundle];
            NSArray *loadedViews = [mainBundle loadNibNamed:@"CustomView" owner:nil options:nil];
            return [loadedViews firstObject];
        }
        return self;
    }

@end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文