2013-01-31 8 views
16

Questo mi sembra un problema facile, ma ho colpito un muro di mattoni di trovare una soluzione e sto sperando che qualcuno qui può aiutare ...1 pixel tra la prima e la seconda cella UITableView raggruppati

I sto facendo un UITableView con UITableViewStyleGrouped, e sto vedendo un piccolo (1 pixel) linea bianca tra la prima e la seconda fila di ogni sezione del mio vista tabella (vedi immagine)

example of gap

sembra che la ragione per questa linea è che la prima cella in ogni sezione è 1 pixel più alta delle altre. Quando imposto la cella iniziale di ciascun gruppo ad essere alta 29 pixel (gli altri sono 30) il divario scompare e tutto va bene.

Mentre questa soluzione ha esito positivo, preferirei sapere il motivo per cui ciò si verifica, così posso evitare di usare un trucco incasinato.

FYI:

  • ho fatto in modo che questo non è un problema con le immagini di sfondo che ho utilizzando - sono tutti 30px alto, e ho sostituito l'immagine in alto con un'immagine centrale con la stessa risultato.
  • Ho rimosso tutti i confini tra le cellule modificando separatorStyle = UITableViewCellSeparatorStyleNone
  • Questo effetto non avviene sulla UITableViewStylePlain

Qualsiasi aiuto è molto apprezzato.

Grazie

Codice per la configurazione da tavolo:

myTable = [[UITableView alloc] initWithFrame:CGRectMake(TABLE_SHIFT_OFFSET, 
                  DATE_SLIDER_HEIGHT - DATE_SLIDER_SHADOW_HEIGHT, 
                  326, 
                  self.view.frame.size.height - DATE_SLIDER_HEIGHT + DATE_SLIDER_SHADOW_HEIGHT) style:UITableViewStyleGrouped]; 
    myTable.backgroundColor = [UIColor clearColor]; 
    myTable.backgroundView = nil; 
    myTable.separatorStyle = UITableViewCellSeparatorStyleNone; 
    [self.view addSubview:myTable]; 
    myTable.dataSource = self; 
    myTable.delegate = self; 

Codice per la configurazione delle cellule:

- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // This is a hack to make sure that a white line doesnt appear between the 
    // first and second rows in the table, which happens for reasons I dont understand 
    if (indexPath.row == 0) { 
    return 29; 
    } 

    return 30; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{  
    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"satCell"]; 
    if (!cell) 
    { 
    cell = [[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"satCell"]; 
    } 

    cell.backgroundView = nil; 
    cell.backgroundView = [[UIView alloc] initWithFrame:CGRectZero]; 

    cell.backgroundColor = [UIColor whiteColor]; 
    int numberOfRowsInThisSection = [self tableView:tableView numberOfRowsInSection:indexPath.section]; 

    if (numberOfRowsInThisSection == 1) 
    { 
    cell.backingImage = self.singleWhite; 
    } 
    else if (indexPath.row == 0) 
    { 
    cell.backingImage = self.topWhite; 
    } 
    else if (indexPath.row % 2 == 0) 
    { 
    // Even row 
    if (indexPath.row == numberOfRowsInThisSection - 1) 
    { 
     // Last row (even) 
     cell.backingImage = self.botWhite; 
    } 
    else 
    { 
     // Normal row (even) 
     cell.backingImage = self.midWhite; 
    } 
    } 
    else if (indexPath.row % 2 == 1) 
    { 
    // Odd row 
    if (indexPath.row == numberOfRowsInThisSection - 1) 
    { 
     // Last row (even) 
     cell.backingImage = self.botDark; 
    } 
    else 
    { 
     // Normal row (odd) 
     cell.backingImage = self.midDark; 
    } 
    } 

    // Setup cell text [REMOVED FOR BREVITY] 

    return cell; 
} 

Il codice per l'impostazione della protezione immagine entro MyTableViewCell:

- (void)setBackingImage:(UIImage *)backingImage 
{ 
    if (self.backingImage != backingImage) 
    { 
    _backingImage = nil; 
    _backingImage = backingImage; 
    self.backingView.image = backingImage; 
    } 
} 

self.backingView è impostato utilizzando il seguente codice:

[[UIImageView alloc] initWithFrame:CGRectMake(7, 0, 307, 30)]; 
+0

Siamo in grado di vedere qualche codice? Hai qualcosa in corso in heightForRowAtIndexPath :? –

+0

Il codice relativo alla visualizzazione delle celle sarebbe carino. A quale vista nella cella stai aggiungendo viste, la cella stessa, il contentView o lo sfondoView? Stai aggiungendo le tue immagini che hanno un bordo? Ho fatto alcuni test e penso che lo stile separatore non funzioni con le tabelle raggruppate, disegnano sempre il separatore. –

+0

Ho aggiunto tutto il codice che posso pensare che potrebbe influire sulla struttura della tabella. Sarei felice di aggiungere qualsiasi altra cosa se necessario ... PS. L'hack in heightForRowAtIndexPath: è la mia soluzione attuale. Se l'hack viene rimosso, il gap viene visualizzato nuovamente – sleeke

risposta

3

Questo è un problema noto, si verifica solo quando si nascondono i separatori di una tabella di gruppo, la stessa cosa è accaduta in questo altro stack overflow question.

In poche parole, la parte superiore e le cellule inferiori utilizzano uno in più punto, ma il separatore nasconde, quindi la soluzione è:

  1. Sottrarre la spaziatura aggiuntiva (come già fatto)
  2. Marchio lo sfondo di un motivo ripetuto o un'immagine estensibile (Non tentare di promuovere me stesso, ma the answer I gave sul thread precedente collegato spiega anche come eseguire immagini estensibili).
  3. Non nascondere il separatore, ma corrisponde al colore con lo sfondo delle celle in modo che sembri nascosto.

L'opzione 2 sembra essere la più "pulita" e aggiunge il vantaggio di supportare le altezze variabili delle celle tableView.

E perché ha un ulteriore punto? Solo Apple lo sa.

+0

Tre buone soluzioni, di cui # 1 corrisponde meglio alle mie esigenze. Preferirei avere tutte le file alla stessa altezza, piuttosto che allungare i miei sfondi per adattarli a quel punto in più. Vale anche la pena notare che non ho visto la riga in basso esibire lo stesso comportamento - quella fila sembra sempre essere 30 punti, proprio come il resto. È un peccato dover ricorrere a un metodo così sporco, ma come dici tu - Apple sa solo perché è fatto così ... – sleeke

0

Questo è l'intestazione di sezione urlata per me. Stai sovrascrivendo il metodo viewForHeaderInSection? La mia ipotesi migliore è che i limiti per la prima cella in ogni sezione siano in qualche modo eliminando i limiti dell'intestazione di quella sezione.

Prova sovrascrivendo questi metodi:

– tableView:viewForHeaderInSection: 
– tableView:viewForFooterInSection: 
– tableView:heightForHeaderInSection: 
– tableView:heightForFooterInSection: 
– tableView:willDisplayHeaderView:forSection: 
– tableView:willDisplayFooterView:forSection: 

e giocare con quello che ritornano. Soprattutto heightForHeaderInSection/viewForHeaderInSection/willDisplayHeaderView: ForSection:

+0

Ho provato a sovrascrivere questi metodi, ma ciò non sembra avere alcun effetto. Dalle risposte di Can e Geoff di cui sopra, sembra che questo sia un problema noto e non dovuto ai ritorni di questo metodo delegato ... – sleeke

1

Nella mia esperienza, le visualizzazioni di tabelle raggruppate aggiungono 1 punto (non pixel!) All'altezza della prima e dell'ultima riga in ogni sezione. Dovresti essere in grado di vederlo aggiungendo il codice di debug per sovrascrivere layoutSubviews sulla classe della tua cella di tabella, chiamala super e poi stampa bounds.size.height.

Suppongo che questo fornisca spazio per il disegno del bordo e, come te, ho appena regolato il valore che restituisco per l'altezza della prima e dell'ultima cella per annullare l'effetto. Questo potrebbe cambiare in iOS 7 poiché l'aspetto visivo è cambiato.

[Modifica] Questo è un bel po 'di codice di debug per ispezionare le gerarchie di visualizzazione. (Non è possibile chiamare direttamente recursiveDescription perché è privata e il codice non viene compilato con le impostazioni predefinite di Xcode.)

NSLog(@"%@", [self.view performSelector:@selector(recursiveDescription)]);

+0

Si prega di chiarire la differenza che citi tra un punto e un pixel? Vuoi dire che un punto è la rappresentazione universale e mostra 2 pixel su un display retina? – sleeke

+0

Sì, è esattamente quello che intendo. Stavi misurando i pixel guardando il display della retina. Per regolare la spaziatura aggiuntiva è necessario utilizzare tableView: heightForRowAtIndexPath: ma fornire la regolazione come punti, non pixel. –

1

Se la seguente sarà risolvere il problema: sbarazzarsi del 'backingImage' (backingView). Utilizzare invece la proprietà backgroundView della cella, assegnando semplicemente lo UIImageView. Ora, quando si crea il UIImageView per lo sfondo assicuratevi di fare il UIImage estensibile in questo modo:

UIImage *bg = [UIImage imageName:@"filename.png"]; 
bg = [bg resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)]; 

NOTA: sto assumendo la tua immagine ha un'altezza di 30 punti. Guardare l'immagine che stai usando può essere allungato verticalmente, cosa sto facendo in questo esempio. Per risparmiare più memoria puoi anche allungarla orizzontalmente, ma la risorsa che hai potrebbe non prestarsi per quello.

Spero che questo aiuti!

+0

Questa è una buona risposta, ma sfortunatamente non è quello che sto cercando. Mentre questo coprirà il divario, mi rimane ancora con la fila superiore di 1 punto più grande rispetto alle altre righe ... – sleeke

0

Su iOS 8 senza separatori su una vista tabella raggruppata ho avuto anche il problema. C'era una differenza di 0,5 punti tra le mie sezioni. Poiché lo sfondo dietro la mia tableview non era dello stesso colore, era molto evidente. La soluzione è riempire con un headerview vuoto di 1 px in altezza, quindi riversare fuori di esso di 1 px con un'altra vista. Funziona come un fascino.

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 1)]; 
    view.backgroundColor = [UIColor whiteColor]; 
    view.opaque = YES; 
    view.clipsToBounds = NO; 

    //Spill a view out by one pixel. 
    UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 2)]; 
    subView.backgroundColor = [UIColor whiteColor]; 
    subView.opaque = YES; 
    [view addSubview:subView]; 
    return view; 
} 

- (CGFloat)tableView:(UITableView *)tableView 
heightForHeaderInSection:(NSInteger)section { 
    return 1; 
} 
Problemi correlati