2011-08-02 8 views
21

El código de ejemplo ligada aquí funciona muy bien y permite una UIScrollView para mostrar imágenes con la paginación y la vista previa de las imágenes antes y después de la imagen actual:IBOutlet no está conectado en awakeFromNib

Estoy tratando de encapsular el ejemplo en un solo control que se puede reutilizar. Así que creé una PagingScrollView:

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

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

@end 

con tierra sencilla aplicación

- (void) awakeFromNib 
{ 
    [super awakeFromNib]; 

    NSLog(@"awake from nib"); 
} 

En PagingScrollView.xib, puse una vista que contiene una UIScrollView y una ARScrollViewEnhancer exactamente como en el xib ScrollViewPagingExampleViewController originales. La clase Owner de su archivo está configurada en PagingScrollView, y su salida scrollView está configurada en el niño UIScrollView.

En ScrollViewPagingExampleViewController, simplemente declaran:

IBOutlet PagingScrollView *pagingScrollView; 

Y en IB, me arrastre un ver, establecer su clase con el PagingScrollView, y conectar su salida pagingScrollView a la PagingScrollView.

En awakeFromNib, la propiedad scrollView es nula. Creo que dado que el scrollView está conectado en IB en la misma punta, estaría disponible en este punto.

Confusamente, en ScrollViewPagingExampleViewController.xib, hay una salida vacía llamada scrollView. Esto podría indicar que hay una instancia diferente de PagingScrollView que la definida en PagingScrollView.xib.

Como resultado, no puedo completar el UIScrollView con las vistas secundarias reales. ¿Qué estoy haciendo mal aquí?

+0

Esto no está relacionado con su pregunta, pero me implementó el proyecto github que nos ha facilitado de una manera diferente camino. Creo que podrías estar interesado. Se carga en (https://github.com/aakash272/pagingScroll) – tipycalFlow

Respuesta

11

Hay una muy buena respuesta a esta pregunta aquí: Accessing View in awakeFromNib?

Larga historia corta, la visión puede ser cargado en awakeFromNib, pero su contenido se cargó con pereza, por lo que se debe utilizar viewDidLoad en lugar de awakeFromNib de lo que estás tratando de lograr

+22

Un UIView no tiene viewDidLoad, este es un método en UIViewController. En mi código de ejemplo anterior, PagingScrollView es un UIView. Tal vez la pregunta se deba a cómo incorporar un control personalizado que use IBOutlet dentro de un control personalizado que también tenga IBOutlet. –

+1

Nunca había visto este comportamiento en ningún proyecto ... hasta que comencé a usar Storyboards. Parece frustrar el propósito del método awakeFromNib? Muy raro. – Adam

+0

Hola Adam, encontré exactamente el mismo problema ahora. Objetos que contienen IBOutlet que están nulos en awakeFromNib cuando se usa el objeto en un guión gráfico, mientras que con plumines normales funcionó bien. –

2

Estaba teniendo este problema y, como usted, los otros artículos no se aplican. Tenía un ViewController, que tenía su propia vista. En el archivo .xib de ese ViewController puse una vista y le di la clase de CustomView. Esto funcionaría muy bien, excepto por el hecho de que CustomView se definió en su propio archivo .xib, por lo que, naturalmente, en awakeFromNib todos los IBOutlets eran nulos. Esto se debe a que no hay forma en que el constructor de interfaces pueda vincular archivos .xib. Entonces, cuando la vista de mi ViewController aparece en la pantalla, intenta crear una instancia de CustomView, en lugar de cargar el archivo CustomView.xib.

No es un trabajo alrededor detallado aquí http://cocoanuts.mobi/2014/03/26/reusable/, pero la esencia es que tenía que poner en práctica lo siguiente en mi clase 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 
1

Para cualquier persona encontrar este buscando la respuesta apropiada en Swift 4, aquí tienes .

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

Aunque, he encontrado el verdadero secreto de ser que no subclase la vista principal de un archivo .xib. En lugar de hacer el propietario del archivo la clase que usted quiere que sea y añadir la plumilla al igual que en el interior de las clases 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) 
    } 
Cuestiones relacionadas