2015-04-13 7 views
9

Vorrei sfruttare l'altezza dinamica UITableViewCell in iOS 8. Devo inserire uno UICollectionView all'interno di uno UITableViewCell. Voglio assicurarmi che tutte le celle nella vista della raccolta siano visibili sullo schermo, quindi la cella della tabella dovrebbe aumentare di altezza per adattarsi alla vista della collezione. Ho quasi funzionato. Non sono stato in grado di ottenere che la cella della tabella abbia le dimensioni corrette: è troppo lunga o troppo corta e alcuni problemi di layout sono visibili finché non interagisco con la tabella (più su quello sotto).Aggiornare l'altezza della vista di raccolta per adattarsi a tutte le celle all'interno di una cella di visualizzazione tabella utilizzando Auto Layout

Ho impostato i vincoli di layout automatico per la vista di raccolta su contentView della cella della tabella: iniziale, finale, superiore e inferiore. Ho quindi creato un vincolo di altezza sulla vista di raccolta in modo da poter aggiornare immediatamente il suo constant dopo aver calcolato l'altezza appropriata per adattarsi a tutte le celle nella vista di raccolta (perché non penso che ci sia un modo per farlo automaticamente).

Ecco il resto del setup.

viewDidLoad { 
    self.tableView.rowHeight = UITableViewAutomaticDimension 
    self.tableView.estimatedRowHeight = 44 
} 

override func viewWillLayoutSubviews() { 
    super.viewWillLayoutSubviews() 

    let cellDimension = self.collectionView.frame.size.width/7 //always 7 columns 

    let flowLayout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout 
    flowLayout.itemSize = CGSizeMake(cellDimension, cellDimension) 

    self.collectionViewHeightConstraint.constant = cellDimension * 4 //always 4 rows 
} 

non ho implementato heightForRowAtIndexPath.

Questa configurazione comporta vincoli verticali in conflitto. Ho provato a ridurre la priorità dei vincoli e a modificare la relazione in un gruppo di combinazioni, ma nessuna ha comportato il comportamento desiderato. Se riduco la priorità del vincolo di altezza a 999, la cella di visualizzazione tabella è troppo alta all'inizio, ma dopo aver fatto scorrere verso l'alto e verso il basso la tabella visualizza gli aggiornamenti dell'altezza della cella della tabella all'altezza prevista. Con alcune altre combinazioni, il risultato è che la cella di una tabella è troppo corta ma la vista di raccolta completa è dissanguata, la cella della tabella è troppo corta e la vista di raccolta è troncata o la cella della tabella è troppo alta, in base a quale priorità e relazioni che ho applicato ai vincoli. Inoltre, le celle di visualizzazione della raccolta non vengono visualizzate con le dimensioni appropriate mentre la vista è in animazione (ma vengono corrette correttamente dopo la fine dell'animazione), oppure se ricarico la tabella le celle della vista di raccolta sono di dimensioni errate finché non scorrono la tavola.

Come posso risolvere questi problemi di aspetto per ottenere un'altezza di cella di visualizzazione tabella dinamica che contiene una vista di raccolta completamente visibile con dimensioni di cella dinamiche in base alla larghezza dello schermo?

+0

Vorrei suggerire di spostare l'impostazione rowHeight "self.tableView.rowHeight =" da ViewDidLoad a ViewWillAppear, potreste voler controllare anche questa domanda. [link] (http://stackoverflow.com/questions/29263875/uitableviewcells-initial-load-view-display-issue) –

+0

@KevinHorgan Questo non ha fatto nessuna differenza evidente. – Joey

+0

Per fare in modo che l'autolayout funzioni correttamente in UITableViewCell è necessario aggiungere i vincoli per tutti i layout in containerView senza mancare. Altrimenti, gli autolayout non funzioneranno correttamente. Controllare il seguente collegamento che fornisce alcune informazioni dettagliate sull'installazione di autolayout per tableviewcell http: // stackoverflow .com/questions/29231390/uitableview-strange-layout-behavior-changes-on-scroll/29327082 # 29327082 – Ram

risposta

0

Ecco come mi avvicinerei a questo, e penso che possa essere fatto tutto in IB.

In primo luogo, avrei impostato le dimensioni minime per le celle CV, quindi avrei impostato la priorità del CV per abbracciarne il contenuto il più strettamente possibile. Ciò dovrebbe garantire che, a parte tutte le influenze esterne, il CV cercherà di avere la dimensione più piccola possibile che renda visibili tutte le sue cellule.

In seguito, giocherei lo stesso gioco con la visualizzazione del contenuto della cella TBV e il CV, ovvero imposterei la priorità principale della visualizzazione del contenuto della cella TBV per abbracciare il CV il più strettamente possibile. Ancora una volta, questo dovrebbe far sì che, trascurate le influenze esterne, la cella TBV dovrebbe mantenere la dimensione minima che deve conservare per poter visualizzare il CV in pieno.

0

Avere uno sguardo a come forkingdog ha risolto lo stesso problema delle altezze dinamiche di cellule Tableview qui> https://github.com/forkingdog/UITableView-FDTemplateLayoutCell

Si dovrebbe essere in grado di passare l'ImageView per uicollectionview. enter image description here

Nel suo Tableview - piuttosto che utilizzare il fuori dalla scatola stimato altezza delle righe - avrete bisogno di qualcosa di simile a

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    return [tableView fd_heightForCellWithIdentifier:@"FDFeedCell" configuration:^(FDFeedCell *cell) { 
     cell.entity = self.feedEntities[indexPath.row]; 
    }]; 
} 



#import "UITableView+FDTemplateLayoutCell.h" 
#import <objc/runtime.h> 

@implementation UITableView (FDTemplateLayoutCell) 

- (id)fd_templateCellForReuseIdentifier:(NSString *)identifier; 
{ 
    NSAssert(identifier.length > 0, @"Expects a valid identifier - %@", identifier); 

    NSMutableDictionary *templateCellsByIdentifiers = objc_getAssociatedObject(self, _cmd); 
    if (!templateCellsByIdentifiers) { 
     templateCellsByIdentifiers = @{}.mutableCopy; 
     objc_setAssociatedObject(self, _cmd, templateCellsByIdentifiers, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
    } 

    UITableViewCell *templateCell = templateCellsByIdentifiers[identifier]; 
    if (!templateCell) { 
     templateCell = [self dequeueReusableCellWithIdentifier:identifier]; 
     templateCellsByIdentifiers[identifier] = templateCell; 
    } 

    return templateCell; 
} 

- (CGFloat)fd_heightForCellWithIdentifier:(NSString *)identifier configuration:(void (^)(id))configuration 
{ 
    // Fetch a cached template cell for `identifier`. 
    UITableViewCell *cell = [self fd_templateCellForReuseIdentifier:identifier]; 

    // Reset to initial height as first created, otherwise the cell's height wouldn't retract if it 
    // had larger height before it gets reused. 
    cell.contentView.bounds = CGRectMake(0, 0, CGRectGetWidth(self.frame), self.rowHeight); 

    // Manually calls to ensure consistent behavior with actual cells (that are displayed on screen). 
    [cell prepareForReuse]; 

    // Customize and provide content for our template cell. 
    if (configuration) { 
     configuration(cell); 
    } 

    // Add a hard width constraint to make dynamic content views (like labels) expand vertically instead 
    // of growing horizontally, in a flow-layout manner. 
    NSLayoutConstraint *tempWidthConstraint = 
    [NSLayoutConstraint constraintWithItem:cell.contentView 
           attribute:NSLayoutAttributeWidth 
           relatedBy:NSLayoutRelationEqual 
            toItem:nil 
           attribute:NSLayoutAttributeNotAnAttribute 
           multiplier:1.0 
            constant:CGRectGetWidth(self.frame)]; 
    [cell.contentView addConstraint:tempWidthConstraint]; 

    // Auto layout does its math 
    CGSize fittingSize = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; 

    [cell.contentView removeConstraint:tempWidthConstraint]; 

    // Add 1px extra space for separator line if needed, simulating default UITableViewCell. 
    if (self.separatorStyle != UITableViewCellSeparatorStyleNone) { 
     fittingSize.height += 1.0/[UIScreen mainScreen].scale; 
    } 

    return fittingSize.height; 
} 

@end 
1

Da quello che posso capire da voi il codice nella creazione di cellule CollectionView e dimensione, mi sembra che tu voglia avere celle di raccolta quadrate e avere 4 righe di 7 celle e tutte completamente visibili.

Se si aggiungono vincoli alla collectionView che si trova nella cella a tutti i 4 margini (in alto, in basso, a sinistra ea destra) e quindi si aggiunge un vincolo di proporzioni di 7: 4 a collectionView, il tableview dovrebbe essere in grado di calcola automaticamente l'altezza della cella per te alla giusta dimensione.

+0

Ciò comporta vincoli in conflitto. Ho anche bisogno che gli elementi si adattino per riempire tutto lo spazio disponibile - non dovrebbe esserci alcuna spaziatura tra ogni cella. – Joey

+0

È necessario impostare l'altezza della cella TableView di conseguenza per eliminare i vincoli in conflitto. Quando lo esegui, tableView ridimensiona la cella a destra, ma in IB devi farlo. Non dovrebbe essere così difficile da calcolare usando il rapporto 7: 4. Per fare in modo che gli elementi riempiano tutto lo spazio disponibile è necessario impostare itemSize per la collectionView. Ma attenzione, hai una collezioneView in ogni cella, quindi devi impostarla in una delle funzioni del datasource tableView. – pteofil

+0

Questo mi ha fatto pensare, però, che quello che stai cercando di ottenere con collectionViews incorporato nelle celle tableview, può essere molto più semplice con un solo CollectionView e quello che stavi per inserire in ogni cella TableView che hai messo in sezioni in CollectionView. – pteofil

Problemi correlati