2011-01-27 12 views
15

Un po 'di background: sto passando attraverso i video iTune CS193P e sono rimasto bloccato sul compito 3 per il tempo più lungo. Fondamentalmente, il compito ti chiede di creare una vista personalizzata a livello di codice per visualizzare una forma sullo schermo. A proposito, non sto usando alcun controller di visualizzazione.Creazione di viste in modo programmatico in IOS (come funziona)?

Impossibile visualizzare la visualizzazione finché non ho finalmente trascinato un oggetto View in Interface Builder e ho modificato il nome dell'oggetto nella mia classe di visualizzazione personalizzata. Quindi la mia domanda è quando le persone dicono di creare una vista a livello di programmazione, stanno solo dicendo di creare manualmente la classe, ma quando è necessario visualizzarla usa IB? Non posso fare a meno di sentire come ho frainteso qualcosa?

modifica: vorrei essere più chiaro. La mia vista personalizzata è stata inizializzata con un frame di 0, 0, 200, 150 e drawRect è sovrascritto per disegnare un quadrato in esso. Il mio punto di vista non ha nemmeno compare se prova ad aggiungere alla finestra principale all'interno del mio controllo:

UIWindow* window = [UIApplication sharedApplication].keyWindow; 
[window addSubview:polygonView]; 

Tuttavia, se l'uso trascinare una vista in IB e cambiare la classe alla mia classe di visualizzazione, si presenta bene.

Modifica: aggiunto un po 'di codice. Questo è il metodo awakeFromNib del mio controller in cui deve essere disegnata la vista.

- (void)awakeFromNib { 
    shape = [[PolygonShape alloc] initWithNumberOfSides:numberOfSidesLable.text.integerValue minimumNumberOfSides:3 maximumNumberOfSides:12]; 
    polygonView = [[PolygonView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)]; 
    UIWindow *window = [UIApplication sharedApplication].keyWindow; 
    polygonView.backgroundColor = [UIColor blackColor]; 
    [window addSubview:polygonView]; 
    [self updateInterface]; 
} 

Parte del metodo updateInterface del mio controller:

- (void)updateInterface { 
    [polygonView setPolygon:shape]; 
    [polygonView setNeedsDisplay]; 
... 
} 

PolygonView.h

#import <UIKit/UIKit.h> 
#import "PolygonShape.h" 

@interface PolygonView : UIView { 
    IBOutlet PolygonShape *polygon; 
} 

@property (readwrite, assign) PolygonShape *polygon; 

- (void)drawRect:(CGRect)rect; 
@end 

PolygonView.m

#import "PolygonView.h" 

@implementation PolygonView 
@synthesize polygon; 

- (id)initWithFrame:(CGRect)frame { 

    self = [super initWithFrame:frame]; 
    if (self) { 
     nslog(@"initialized"); 
    } 
    return self; 
} 

- (void)drawRect:(CGRect)rect { 
     CGRect bounds = [self bounds]; 

    [[UIColor grayColor] set]; 
    UIRectFill(bounds); 

    CGRect square = CGRectMake(10, 10, 10, 100); 
    [[UIColor blackColor] set]; 
    UIRectFill(square); 

    [[UIColor redColor] set]; 
    UIRectFill(square); 
    NSLog(@"drawRect called"); 
} 
@end 

Il polygonView viene inizializzato ma il drawRect isn essere calle d.

+0

Dove viene creato il KeyWindow? Se non stai caricando un file di pennino (non è chiaro dalla tua domanda se lo sei o meno), allora dovresti creare la finestra prima di aggiungere la sottoview. – jlehr

+0

Viene creato nella classe AppDelegate. Questo significa che devo #importare la mia classe polygonView lì e crearla lì? –

+0

È interessante notare che se inserisco l'inizializzazione e aggiungo la mia vista alla finestra nel mio metodo updateInterface, funziona solo dopo aver fatto clic su un pulsante che chiama il metodo. Sembra che il codice non sia in elaborazione in awakeFromNib. Qualche idea? –

risposta

16

Per essere ancora più specifico alla tua domanda, la sintassi sarebbe

UIWindow* window = [UIApplication sharedApplication].keyWindow; 

UIView *polygonView = [[UIView alloc] initWithFrame: CGRectMake (0, 0, 200, 150)]; 
//add code to customize, e.g. polygonView.backgroundColor = [UIColor blackColor]; 

[window addSubview:polygonView]; 
[polygonView release]; 

Si tratta di un modello che userete non solo per questo ma anche per le sottoview. Inoltre, un'altra nota è con molti dei modelli, il viewController è già impostato con la propria vista. Quando si vuole fare una visualizzazione personalizzata, si crea come sopra ma invece del metodo di cui sopra si impostano le viewControllers visualizzare alla vista appena creata in questo modo:

viewController.view = polygonView; 

Buona fortuna!

+0

Allora devo fare qualcosa di sbagliato. L'ho esattamente come hai scritto e la mia vista non viene visualizzata. –

+0

Hmmm ... Cosa succede se commentate drawRect o specificatamente chiamatelo in initWithFrame con [self drawRect] ;? –

+0

Non succede nulla di diverso se non sovrascrivo drawRect. Se chiamo drawRect dal metodo initWithFrame ottengo un errore di eccezione: "reason:" - [PolyRepView drawRect]: selettore non riconosciuto inviato all'istanza 0x4b58c70 "" –

2

È necessario avere una vista (o una finestra) per aggiungere una vista secondaria a. La sintassi normale è come questo:

UIView *newView = [[UIView alloc] initWithFrame:mainView.bounds]; 
[mainView addSubview:newView]; 
[newView release]; 

Naturalmente, se si dispone di un oggetto personalizzato che eredita da UIView, si usa che invece di UIView. Quando si avvia un nuovo progetto, creare una "applicazione basata sulla visualizzazione", che inizierà con un controller di visualizzazione con una vista associata (a cui è possibile accedere con "CustomViewController.view", che sostituirà "mainView" nello snippet di codice sopra).

Se si desidera creare la vista a livello di codice all'avvio dell'app, inserire il codice nel metodo "- (void) viewDidLoad" del proprio controller di visualizzazione.

+0

So che un controller Vista sarebbe la strada da percorrere, ma in questo particolare incarico c'è solo una classe modello, una classe controller e la classe vista personalizzata. Stai dicendo che dovrei aggiungere il mio oggetto vista alla finestra principale? Come e dove lo farei? –

0

Da qualche parte nella classe del controller attivo, è possibile aggiungere una vista personalizzata alla vista corrente di primo livello.

[ myCurrentTopView addSubview: myNewCustomView ]; 

Aiuta ad allocare e inizializzare prima questa vista personalizzata.

Poi, si può innescare qualche disegno in drawRect di questa visualizzazione personalizzata facendo un:

[ myNewCustomView setNeedsDisplay ]; 
+0

La mia attuale vista superiore è la finestra principale. La finestra principale non è un oggetto nella mia classe controller, quindi come impostare la mia vista come sottoview ([window addSubView: ...] non funziona). –

0

Hai impostato il colore di sfondo della vista su qualcosa di distinguibile?

Sei sicuro che la tua vista non venga visualizzata o è solo che non puoi vederla? Inserisci un NSLog nel drawRect: metodo della tua vista (se usi una classe di visualizzazione personalizzata).

+0

Sì, ho provato a impostare il colore di sfondo iniziale su nero solo per vedere se posso vedere una vista bianca o grigia, che non ha funzionato. Ho anche inserito un messaggio NSLog in drawRect e iniWithFrame che non è stato mostrato nella console. Non credo che la mia vista venga inizializzata anche se ho polygonView = [polygonView initWithFrame: CGRectMake (0, 10, 320, 480)]; nel metodo awakeFromNib del mio controller. –

+0

Riporto indietro la vista non inizializzando. Lo è e viene visualizzato il messaggio NSLog in iniWithFrame. È solo il messaggio NSLog in drawRect che non viene visualizzato. Vedo che i miei dati nel mio modello vengono trasmessi correttamente alla mia vista. Non riesco proprio a capire perché la finestra non visualizzerà la mia vista. –

+0

Forse un po 'più di codice ci aiuterebbe ad analizzare la situazione. – fzwo

4

Questa è una vecchia questione, ma non sono sicuro che ha ottenuto la risposta che si aspettava - suona come egli ha incontrato lo stesso problema che ho fatto, dove ho creato una sottoclasse UIViewController, colpì un UIViewController in un pennino costruttore di interfaccia, ma quindi non riuscivo a capire come far lavorare i due l'uno con l'altro.

Se il pennino è stato fatto separatamente (quindi non è stato creato per te accanto alla tua classe), devi ricordarti di fare clic su UIViewController che hai inserito nel generatore di interfacce, quindi dal pannello delle proprietà fai clic sul terzo pulsante della scheda ("Classe personalizzata"). Il Class sarà la classe base predefinita UIViewController ecc. - apri questo elenco a discesa e vedrai un elenco di tutte le sottoclassi personalizzate, selezionalo e volla: hai collegato il tuo elemento personalizzato all'interfaccia.

La speranza che salva qualcuno nei giorni che ho impiegato per capire, ho trovato alcuni modi stupidamente meravigliosi di aggirarlo fino a quando non ho realizzato la soluzione semplice.

0

Ho avuto un problema molto simile di recente ed ecco cosa ha funzionato per me: Sembra che quando si inizia con una 'applicazione vuota' in Xcode 4.3.2 si deve impostare la vista come la vista principale della finestra principale utilizzando il metodo setRootViewController invece di addSubview. Quindi:

// Initialize myView and then 
[window setRootViewController:myView]; 
// instead of [window addSubview:myView]; 
// the rest as normal... 
[window makeKeyAndVisible]; 

Dopo di che è possibile utilizzare il metodo addSubview per aggiungere ulteriori visualizzazioni.

2

hi basta aggiungere questo codice,

[window bringSubviewToFront:polygonView]; 

right after, 
[window addSubview:polygonView]; 
+1

È una cattiva pratica .... – Resty

0

chiamata

[super drawRect]; 

prima del tuo codice personalizzato in drawRect: corpo.

Problemi correlati