2014-12-05 17 views
5

Ho creato una sottoclasse personalizzata di UIView insieme a un file xib e dichiarato IBOutlet e IBActions all'interno della classe personalizzata.UIView personalizzato caricato da Xib

@interface ContactUsView : UIView 

@property (nonatomic, weak) IBOutlet UIButton *displayCloseButton; 

- (IBAction)callButtonPressed:(id)sender; 
- (IBAction)emailButtonPressed:(id)sender; 
- (IBAction)displayCloseButtonPressed:(id)sender; 

@end 

Nel file xib ho trascinato un UIView per rappresentare la mia vista personalizzata. Ho impostato:

  • file proprietario = alla mia classe personalizzata
  • aver impostato il trascinato in UIView alla mia classe personalizzata.

Ho quindi aggiunto vari pulsanti che sono collegati ai 3 metodi sopra indicati.

All'interno del ContactUsView.m ho il seguente:

- (id)initWithFrame:(CGRect)frame 
{ 
    if (self = [super initWithFrame:frame]) { 
     NSArray* array = [[NSBundle mainBundle] loadNibNamed:@"ContactUsView" owner:self options:nil]; 
     for (id object in array) { 
      if ([object isKindOfClass:[ContactUsView class]]) 
       self = (ContactUsView *)object; 
     } 
    } 
    return self; 
} 

Quando vengo a creare questo punto di vista faccio la seguente:

- (void)viewWillAppear:(BOOL)animated 
{ 
    ContactUsView *contactUs = [[ContactUsView alloc] initWithFrame:CGRectZero]; 

    CGPoint origin = self.view.frame.origin; 
    CGSize size = self.view.frame.size; 
    [contactUs setFrame:CGRectMake(origin.x, 
           CGRectGetMaxY(self.view.frame) - 100, 
           size.width, 
           contactUs.frame.size.height)]; 

    [self.view addSubview:contactUs]; 
} 

Problema Quando premo su una delle i pulsanti con cui l'applicazione si arresta in modo anomalo con: Thread 1: EXC_BAD_ACCESS (codice = 2, indirizzo = 0xb0c

Qualcuno può aiutarmi con questo. Sento che sto probabilmente commettendo un errore da qualche parte riguardo alla creazione e caricamento di visualizzazioni personalizzate da xibs.

Se hai bisogno di ulteriori informazioni fammi sapere. Grazie molto.

Riferimento futuro Quando si crea una vista personalizzata utilizzando uno xib NON impostare il proprietario dei file. Invece crea tutti i tuoi IBOutlet e IBActions come faresti normalmente e quindi per agganciarli apri la scheda Utility e controlla il trascinamento da lì.

enter image description here

+0

di poter postare l'intera errore? O la linea in cui si verifica effettivamente l'errore? Abilita i punti di interruzione sulle eccezioni in XCode. – KerrM

+0

Se inserisco un punto di interruzione in uno dei metodi chiamati, non raggiunge mai il punto di interruzione. Si blocca solo con il codice sopra e nulla viene mostrato nell'output. Ho aggiunto un punto di interruzione "Tutte le eccezioni" e ancora non viene mostrato nulla nell'output. – pls

risposta

4

• proprietario Files = alla mia classe personalizzata

sbagliato. Il proprietario dei file dovrebbe essere vuoto. La vista stessa è il proprietario dei file. Significa che dovresti connettere tutte le azioni e le prese con ContactUsView nel tuo xib.

[[NSBundle mainBundle] loadNibNamed: @ "ContactUsView" il proprietario: opzioni self: nil]

...

auto = (ContactUsView *) oggetto;

Dopo aver superato self come parametro owner. Lo stai cambiando. Il che significa che in precedenza lo ContactUsView assegnato (self) verrà distrutto dal -loadNibNamed:owner:options: non conservarlo.Se si applica il mio primo consiglio si dovrebbe inviare nil come owner parametro

for ciclo qui non è necessario utilizzare solo array[0], perché questa è sempre la vostra vista se si dispone di gerarchia di vista valido nel tuo XI ter

+0

Grazie mille Silmaril. Questo ha risolto il mio problema. Per riferimento futuro durante la creazione di una vista personalizzata è necessario aprire il tag Utilities e controllare il trascinamento da lì. – pls

0

È possibile utilizzare delegato per questo questo è come si può fare questo

 @protocol CustomViewDelegate <NSObject> 
- (void)callButtonPressed:(id)sender; 
- (void)emailButtonPressed:(id)sender; 
- (void)displayCloseButtonPressed:(id)sender; 

@end 

@interface ContactUsView : UIView 

@property (nonatomic, weak) IBOutlet UIButton *displayCloseButton; 

@property (nonatomic, weak) id<CustomViewDelegate> ButtonDelegate; 

- (IBAction)callButtonPressed:(id)sender; 

- (IBAction)emailButtonPressed:(id)sender; 
- (IBAction)displayCloseButtonPressed:(id)sender; 


@end 

e in.m file di

- (IBAction)callButtonPressed:(id)sender 
{ 
[self.ButtonDelegate callButtonPressed:sender]; 
} 

- (IBAction)emailButtonPressed:(id)sender{ 
[self.ButtonDelegate emailButtonPressed:sender]; 
} 

- (IBAction)displayCloseButtonPressed:(id)sender{ 
[self.ButtonDelegate displayCloseButtonPressed:sender]; 
} 

Dopo di che è sufficiente impostare il delegato con viewcontroller refrence e utilizzare quelli delegato qui

- (void)viewWillAppear:(BOOL)animated 

{

ContactUsView *contactUs = [[ContactUsView alloc] initWithFrame:CGRectZero]; 
contactUs.ButtonDelegate = self; 

CGPoint origin = self.view.frame.origin; 
CGSize size = self.view.frame.size; 
[contactUs setFrame:CGRectMake(origin.x, 
          CGRectGetMaxY(self.view.frame) - 100, 
          size.width, 
          contactUs.frame.size.height)]; 

[self.view addSubview:contactUs]; 

}

- (void)callButtonPressed:(id)sender 

{}

- (void)emailButtonPressed:(id)sender 

{}

- (void)displayCloseButtonPressed:(id)sender 

{}

ho fatto e funziona totlly benissimo

+0

Grazie per la risposta. Stai caricando lo xib nello stesso modo in cui lo faccio io? La mia app si arresta in modo anomalo quando faccio clic su un pulsante collegato a IBAction. Tuttavia si blocca immediatamente, il che significa che non accade nulla nel metodo. Se mi sembra che abbia qualcosa a che fare con la memoria quando viene caricata la vista. – pls

+0

sì io faccio lo stesso. –

2

Se si sta caricando un UIView per un xib allora si dovrebbe creare un metodo di classe a carica la vista.

Nella tua customview.h

+(id)customView; 

& nel vostro customview.m

+ (id)customView 
{ 
    CustomView *customView = [[[NSBundle mainBundle] loadNibNamed:@"CustomView" owner:nil options:nil] lastObject]; 
    if ([customView isKindOfClass:[CustomView class]]) 
     return customView; 
    else 
     return nil; 
} 

È possibile inizializzare ovunque utilizzando:

CustomView *myView = [CustomView customView]; 

EDIT: Assicurati di hai cambiato la tua classe di customview in identità inspecter & assicurati anche che la tua connessione di IBActions sia con i metodi di quella classe. enter image description here

enter image description here

+0

Ciao Ajay. Sì, probabilmente lo implementerò come metodo di classe. Tuttavia il codice all'interno del tuo metodo è lo stesso del mio codice e causa ancora lo stesso crash. – pls

+0

Controlla la mia risposta aggiornata – Ajay

+0

La risposta di Silmaril mi ha fatto capire cosa stavo facendo male. Ho già accettato la sua risposta prima di vedere la tua risposta modificata che ha la stessa soluzione. Ho votato anche la tua risposta. Grazie molto. – pls

Problemi correlati