【问题标题】:IBOutlets in subview are nil子视图中的 IBOutlets 为零
【发布时间】:2014-05-14 14:54:32
【问题描述】:

我有一个UIViewController,它与自定义类MAViewControllerMenu 相关联,并在启动画面之后立即加载。在那个UIViewController中,我有一个UIScrollView,它属于另一个类MASlideShowView,其中定义了UIScrollView的IBOutlet并与之相连。

UIViewController 的类包括字段:

@property MASlideShowView* slideShow;

作为在其中保存 UIScrollView 的类的私有属性。

同样在UIViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
//TODO    [_slideShow initializeImages];
    _slideShow = [[MASlideShowView alloc] initWithModel];
    _slideShow.delegate = imageViewController;

}

- (void)viewDidAppear{
    [super viewDidAppear:(YES)];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

     // Set up the content size of the scroll view
     //HERE, self.slideShow is allocated, but all the fields it has, including the IBOutlet to the UIScrollView is still nil
    CGSize pagesScrollViewSize = self.slideShow.frame.size;
    _slideShow.contentSize = CGSizeMake(pagesScrollViewSize.width * self.pageViews.count, pagesScrollViewSize.height);

    //Delegate
    _slideShow.scrollView.delegate = self;

    // Load the initial set of pages that are on screen
    [_slideShow loadVisiblePages:YES page_index:0 image:_last_image_taken];

}

注意我在上面类的 cmets 中看到的错误

MASlideShowView 文件如下所示:

h:

@class MASlideShowView;
@protocol slideShowDelegate <NSObject>

-(void)imageViewSelected:(MASlideShowView*)slideShow image:(UIImage*)image;

@end

@interface MASlideShowView : UIScrollView

@property (nonatomic,weak) id<slideShowDelegate> delegate;//delegate to next controller to notify upon picture centered
@property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
@property (nonatomic, strong) IBOutlet UIPageControl *pageControl;
@property (weak, nonatomic) IBOutlet UIButton *rotateImageButton;
@property UIImageView* centered_image_view;
- (IBAction)PageThroughPageControl;
- (IBAction)rotateImageButtonClicked;

- (id)initWithModel;
- (void)pageThroughPageControl;
- (void)addImageToSlideshow:(UIImage*)toAdd;
- (void)loadVisiblePages:(BOOL)use_page_number page_index:(NSInteger)page image:(UIImage*)image;
@end

米:

- (id)initWithModel{    
    [self initializeImages];    
    return self;
}

-(void)initializeImages{

    // Set up the image you want to scroll & zoom and add it to the scroll view
    self.pageViews = [NSMutableArray arrayWithObjects:nil];
    NSInteger pageCount = 0;
    _imageViewCount = 0;

    // Set up the page control
    self.pageControl.currentPage = 0;
    self.pageControl.numberOfPages = pageCount;

    // Set up the array to hold the views for each page
    self.pageViews = [[NSMutableArray alloc] init];
    for (NSInteger i = 0; i < pageCount; ++i) {
        [self.pageViews addObject:[NSNull null]];
    }
}

我的问题很简单:

如何使UIScrollView 初始化? 我知道没有viewDidAppear,因为它继承自UIScrollView

谢谢

【问题讨论】:

  • _slideShow = [[MASlideShowView alloc] initWithModel];我认为你不需要初始化一个 MASlideshowView,因为当你的 parentView 是 MAViewControllerMenu 加载 Xib 时,也会加载 xib 文件中的其他子视图。因此,您的幻灯片仍然存在,不需要分配或初始化。如果要初始化 UIScrollView。在你的 MASlideShowView 中实现一个 awakeFromNib 方法。
  • @HoanNguyen - 已解决!事实证明,我在 MASlideShowView 中的 IBOutlet scrollView 确实被初始化了。但是,我在将 MASlideShowView 的 RIGHT 实例(保存 scrollView 的初始化值的实例)连接到我的主 UIViewController 的类 MAViewControllerMenu 中的 _slideShow 属性时遇到了问题。你完全正确。谢谢!

标签: ios objective-c uiviewcontroller xcode5


【解决方案1】:

有几种方法可以解决这个问题。

一种方法是 @HoanNguyen 提到使用 awakeFromNib。我个人不使用它,但它是设置的有效生命周期事件。

另一个选项是覆盖 initWithCoder: 这是标准的初始化故事板使用

- (id)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self initializeImages];
    }
    return self;
}

然后您可以删除您的 initWithModel 调用,情节提要应处理所有事情。

【讨论】:

  • 我尝试使用该函数,但它不能编译超级调用。我的“MASlideShowView”继承自 UIScrollView,似乎没有“initWithCoder”
  • 嗯,好吧,那么您可能应该使用 awakeFromNib,或者您可以尝试覆盖 UIView 的标准初始化程序,即 initWithFrame
【解决方案2】:

当您使用 Interface Builder 时,我建议您在 awakeFromNib 内调用 initializeImages

一条 awakeFromNib 消息被发送到从 存档,但前提是它可以响应消息,并且毕竟 存档中的对象已加载并初始化。当一个 对象收到一个 awakeFromNib 消息,它保证拥有所有 它的出口实例变量集。

更多详情here.

其他观察:

至于您的代码,您在输入 viewDidLoad 时已由 Interface Builder 正确设置了 slideShow,但您通过分配 _slideShow = [[MASlideShowView alloc] initWithModel] 来替换该实例,这会导致完全不同的对象。

此外,您的initWithModel 看起来一点也不像正确的init 方法,因为它没有调用任何superinit 方法。您应该从 Apple 的 sn-p 开始,在空行中写入 init,然后按转义键:

同样,答案的第一段应该足以解决您的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-14
    • 2016-10-30
    • 2011-04-29
    • 1970-01-01
    • 2022-01-13
    • 2023-03-12
    • 2019-11-15
    相关资源
    最近更新 更多