2015-05-01 15 views
5

Sto caricando un file XIB di UIView personalizzato come vista di intestazione di una vista uitable in un controller di visualizzazione.Problema di caricamento automatico della vista Tableheader

Il proprietario del file per il file xib è il viewcontroller. Dispongo sia di & del viewcontroller che l'interfaccia di uiview è stata dichiarata all'interno di uiviewcontroller.

ViewController.h

 @class ZeroStateView; 

     @interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> 

     @property (nonatomic, weak) IBOutlet CustomUITableView *tableView; 
     @property (nonatomic,strong) NSMutableArray *dataArray; 
     @property (weak, nonatomic) IBOutlet ZeroStateView *zeroStateView; 


     @end 


    @interface ZeroStateView : UIView 
    @property (weak, nonatomic) IBOutlet AutoLayoutLabel *titleLabel; 
    @property (weak, nonatomic) IBOutlet UIImageView *titleIcon; 

    - (void)updateView; 

    @end 

ViewController.m

- (void)prepareHeaderViewForZeroState{ 
      ZeroStateView *sizingView = [ZeroStateView new]; 
      [[[NSBundle mainBundle] loadNibNamed:@"ZeroStateView" owner:self options:nil] objectAtIndex:0]; 
      sizingView = self.zeroStateView; 
      [sizingView updateView]; 

      self.tableView.tableHeaderView = sizingView; 

      UIView *headerView = self.tableView.tableHeaderView; 



      CGFloat height = [headerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height; 

     CGRect headerFrame = headerView.frame; 
     headerFrame.size.height = height; 
     headerView.frame = headerFrame; 


     self.tableView.tableHeaderView = headerView; 
    } 

    @end 

    @implementation ZeroStateView 

    -(void)updateView{ 
     self.titleIcon.alpha = 0.5; 

     UIFontDescriptor *titleFontDescriptor = [UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleSubheadline]; 

     self.titleLabel.text = @"This is a long text message and its really long. This is a long text message and its really long. This is a long text message and its really long. This is a long text message and its really long. This is a long text message and its really long. This is a long text message and its really long. This is a long text message and its really long. This is a long text message and its really long. "; 

    } 

La classe AutolayoutLabel il seguente metodo sovrascritto:

- (void)setBounds:(CGRect)bounds { 
     [super setBounds:bounds]; 

     // For multiline label, preferredMaxLayoutWidth always matches the frame width 
     if (self.numberOfLines == 0 && bounds.size.width != self.preferredMaxLayoutWidth) { 
      self.preferredMaxLayoutWidth = self.bounds.size.width; 
      [self setNeedsUpdateConstraints]; 
     } 
    } 

L'altezza calcolata dal systemLayoutSizeFittingSize: UILayoutFittingCompressedSize restituisce 0. Di conseguenza ottengo il seguente vista come la vista intestazione della tabella: Header view with height 0

Quando ho aggiunto l'altezza reale come sotto, i overflow UILabel. Mi aspetto che la visualizzazione dei dati cresca man mano che l'altezza dell'etichetta aumenta.

headerFrame.size.height = self.sizingView.frame.size.height; 

TableHeaderView not being resized properly

Ecco la cattura dello schermo di che i vincoli di UIViews:

ZeroState view XIB file with constraints

Che cosa mi manca qui? Qualcuno può segnalarmi?

Aggiornamento ho creato un campione project per voi ragazzi per controllare che cosa è esattamente questione è.

+0

Per quello che vale, aiuta sempre a indicare la tua domanda nella prima frase. –

+0

Non si dovrebbe chiamare questo 'ZeroStateView * sizingView = [ZeroStateView new];' se si assegna qualcos'altro ad esso 2 righe dopo. – pteofil

+0

Quando si chiama 'prepareHeaderViewForZeroState'? – pteofil

risposta

2

Ho reimplementato quello che avevi finora in un modo diverso. Per iniziare, ho rimosso lo UIView in ZeroStateView.xib in cui sono stati incorporati e UILabel. La base dello xib è già un UIView, quindi non è necessario aggiungere un altro UIView ad esso.

Avanti Ho cambiato i vincoli intorno.Non ricordo esattamente che cosa ho cambiato vincoli, quindi mi limiterò a elencarli qui:

  1. vincoli per UIImageView
    • Allinea al centro X per Superview
    • Width = 60
    • Altezza = 56
    • Spazio Top a Superview = 37
    • fondo Spazio per UILabel = 31
  2. vincoli per UILabel
    • Sinistra Spazio per Superview = 15
    • giusto spazio per Superview = 15
    • spazio inferiore a Superview = 45
    • Top Spazio per UIImageView = 31

Sul codice. Nel ViewController.h, il IBOutlet non stava facendo nulla per quanto ho potuto dire, così ho cambiato la proprietà leggere @property (strong, nonatomic) ZeroStateView *zeroStateView;

Ora i cambiamenti importanti: ViewController.m. Esistono due metodi UITableViewDelegate che sostituiranno prepareHeaderViewForZeroState. In viewDidLoad, inizializzare lo zeroStateView e impostare il delegato della vista tabella su self.

- (void)viewDidLoad 
{ 
    //... 

    // Load the view 
    self.zeroStateView = [[[NSBundle mainBundle] loadNibNamed:@"ZeroStateView" owner:self options:nil] firstObject]; 
    [self.zeroStateView updateView]; 
    self.zeroStateView.backgroundColor = [UIColor darkGrayColor]; 

    // Set self for table view delegate for -heightForHeaderInSection: and viewForHeaderInSection: 
    self.dataTable.delegate = self; 
} 

Ora che siamo delegato della visualizzazione della tabella, otteniamo due chiamate di metodo che ci permetteranno di personalizzare la visualizzazione di intestazione e impostiamo la sua altezza in modo appropriato.

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
{ 
    // This will set the header view to the zero state view we made in viewDidLoad 
    return self.zeroStateView; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
{ 
    // sizeToFit describes the size that the label can fit itself into. 
    // So we are saying that the label can use the width of the view and infinite height. 
    CGSize sizeToFit = CGSizeMake(self.view.frame.size.width, MAXFLOAT); 

    // Then we ask the label to tell us how it can fit in that size. 
    // The label will respond with the width of the view and however much height it needs 
    // to display its text. This is the magic of how it grows vertically. 
    CGSize size = [self.zeroStateView.titleLabel sizeThatFits:sizeToFit]; 

    // Add the height the label needs to the overall zero state view. This should be changed 
    // to the height of the UIImage + the height we just got + the whitespace above and below 
    // each of these views. You can handle that part. 
    return self.zeroStateView.frame.size.height + size.height; 
} 

Ho caricato le mie modifiche su Dropbox here.

0

Non sono sicuro, ma è possibile controllare se si dispone dei vincoli iniziali, finali, superiori e inferiori sia per UIImage che per l'etichetta con riferimento alla superview.

Edit: aggiungere il vincolo di larghezza prima di ottenere lo systemLayoutSize

NSLayoutConstraint *tempWidthConstraint = 
[NSLayoutConstraint constraintWithItem:self.contentView 
          attribute:NSLayoutAttributeWidth 
          relatedBy:NSLayoutRelationEqual 
           toItem:nil 
          attribute:NSLayoutAttributeNotAnAttribute 
          multiplier:1.0 
           constant:CGRectGetWidth(window.frame)]; 

widthConstraint.constant = tempWidthConstraint.constant; 
[self.contentView addConstraint:tempWidthConstraint]; 

CGSize fittingSize = [self.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; 
CGFloat height = fittingSize.height +1; 
[self.contentView removeConstraint:tempWidthConstraint]; 
+0

Aggiungere anche i vincoli iniziali, finali e superiori per la vista dell'immagine Icona di avviso. –

+0

vorrei che l'immagine fosse centrata. Se imposto uno spazio finale, l'icona imageview scompare dalla vista –

+0

sì ok, hai provato ad aggiungere un vincolo di larghezza per la vista prima di ottenere systemLayoutSize, quindi rimuovi il vincolo di larghezza –

1

Basta cambiare le dimensioni del telaio del tableHeaderView, non cambia la sua dimensione. Devi reimpostarlo su tableView per forzare una ricarica.

È necessario chiamare di nuovo self.tableView.tableHeaderView = headerView; dopo aver impostato la nuova dimensione del frame.

+0

ma systemLayoutSizeFittingSize restituisce zero –

+0

Qualunque altro problema hai , tu _must_ set self.tableView.tableHeaderView = headerView; di nuovo o le modifiche di altezza nella vista dell'intestazione non avranno alcun effetto sulla vista tabella. Consideralo un bug in iOS (lo faccio), ma devi farlo. – gnasher729

1

Come si chiama il metodo prepareHeaderViewForZeroState da viewwillappear. A quel punto il layout non è calcolato. quindi imponi il layout da calcolare prima di chiamare il metodo systemLayoutSizeFittingSize per calcolare l'altezza della cella. Ecco il codice che devi scrivere prima di chiamare systemLayoutSizeFittingSize.

UIView *header = self.tableView.tableHeaderView; 

    [header setNeedsLayout]; 
    [header layoutIfNeeded]; 

Edit:

hai appena lasciato 1 vincoli ZeroStateView.xib. ovvero Bottom Space to : Superview. gentilmente riferimento screenshot.

enter image description here

uscita:

enter image description here

Qui avete Updated code

Spero che questo aiuto.

+0

Ho aggiornato il mio codice per aggiungere quello che hai suggerito ma non ha fatto molto. Ho aggiornato il progetto di esempio.puoi giocarci quando puoi. –

0

Ci sono alcune cose qui che mi confondono che potrebbero complicare le cose.

  1. Perché si sottoclassa l'etichetta?
  2. I vincoli non hanno davvero senso.
    • Perché l'etichetta ha due limiti di altezza, una costante e un ≥ vincolo? Rimuovili entrambi, non ne hai nemmeno bisogno.
    • Inoltre, lo spazio verticale sul fondo del contenitore è ≥ pure. Perché? Così com'è, la tua vista personalizzata non ha un'altezza definita, il che potrebbe essere il motivo per cui la misura adatta restituisce un'altezza pari a zero.

Una volta a risolvere questi problemi, fatemi sapere se avete più fortuna.

+0

Ciao grazie per aver segnalato gli errori. Ho aggiornato il mio codice e questo non ha fatto molto. Ho aggiornato il progetto di esempio. puoi giocarci quando puoi. –

Problemi correlati