30

此处链接的示例代码效果很好,并允许 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 完全相同。它的 File's Owner 的类设置为 PagingScrollView,它的 scrollView 出口设置为子 UIScrollView。

在 ScrollViewPagingExampleViewController 中,我简单地声明:

IBOutlet PagingScrollView   *pagingScrollView;

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

在 awakeFromNib 中,scrollView 属性为 nil。我认为由于 scrollView 在同一个 nib 中连接到 IB 中,因此此时可以使用它。

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

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

4

4 回答 4

12

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

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

于 2011-08-03T13:59:04.913 回答
7

对于任何在 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)
}
于 2017-11-29T17:55:32.460 回答
4

我遇到了这个问题,和你一样,其他文章不适用。我有一个 ViewController,它有自己的视图。在那个 ViewController 的 .xib 文件中,我放置了一个视图并给它一个 CustomView 类。这会很好用,除了 CustomView 是在它自己的 .xib 文件中定义的,所以在 awakeFromNib 中自然所有 IBOutlets 都是 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
于 2015-06-21T20:55:30.817 回答
3

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

class PointsTableViewCell: UITableViewCell {

    @IBOutlet weak var pointsTitleLabel: UILabel! {
        didSet {
            self.pointsTitleLabel.text = "Points"
        }
    }
}
于 2018-03-21T14:22:30.910 回答