Separatore di iOS 8 UITableView 0 non funzionante


Answers

Arg !!! Dopo averlo giocato, esegui questa operazione nella sottoclasse Cell :

- (UIEdgeInsets)layoutMargins
{
    return UIEdgeInsetsZero;
}

o impostando il file cell.layoutMargins = UIEdgeInsetsZero; risolto per me.

Question

Ho un'app in cui il separatore di UITableView è impostato su valori personalizzati - Destra 0 , Sinistra 0 . Funziona perfettamente su iOS 7.x , tuttavia in iOS 8.0 vedo che il separatore è impostato sul valore predefinito di 15 sulla destra. Anche se nei file xib è impostato su 0 , viene comunque visualizzato in modo errato.

Come rimuovere i margini del separatore di UITableViewCell ?




In un modo più compatto rispetto alla risposta più votata ...

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

    if ([cell respondsToSelector:@selector(setSeparatorInset:)] && [cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)] && [cell respondsToSelector:@selector(setLayoutMargins:)]) {
         [cell setSeparatorInset:UIEdgeInsetsZero];
         [cell setPreservesSuperviewLayoutMargins:NO];
         [cell setLayoutMargins:UIEdgeInsetsZero];
    }

}




Per iOS 9 è necessario aggiungere:

if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
    myTableView.cellLayoutMarginsFollowReadableWidth = NO;
} 

Per maggiori dettagli si prega di fare riferimento alla question .




Per me la linea semplice ha fatto il lavoro

cell.layoutMargins = UIEdgeInsetsZero



Questo ha funzionato perfettamente per me su iOS 8 e iOS 9.

Per OBJ-C

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  { 
        if ([tableView respondsToSelector:@selector(setSeparatorInset:)])
        {
            [tableView setSeparatorInset:UIEdgeInsetsZero];
        }

        if ([tableView respondsToSelector:@selector(setLayoutMargins:)])
        {
            [tableView setLayoutMargins:UIEdgeInsetsZero];
        }

        if ([cell respondsToSelector:@selector(setLayoutMargins:)])
        {
            [cell setLayoutMargins:UIEdgeInsetsZero];
        }
         return cell;
    }



Lukasz risponde in Swift:

    // iOS 7:
    UITableView.appearance().separatorStyle = .SingleLine
    UITableView.appearance().separatorInset = UIEdgeInsetsZero
    UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

    // iOS 8:
    if UITableView.instancesRespondToSelector("setLayoutMargins:") {
        UITableView.appearance().layoutMargins = UIEdgeInsetsZero
        UITableViewCell.appearance().layoutMargins = UIEdgeInsetsZero
        UITableViewCell.appearance().preservesSuperviewLayoutMargins = false
    }



Credo che questa sia la stessa domanda che ho posto qui: Rimuovi SeparatorInset su iOS 8 UITableView per XCode 6 iPhone Simulator

In iOS 8 , c'è una nuova proprietà per tutti gli oggetti ereditati da UIView . Pertanto, la soluzione per impostare SeparatorInset in iOS 7.x non sarà in grado di rimuovere lo spazio bianco visualizzato su UITableView in iOS 8.

La nuova proprietà si chiama " layoutMargins ".

@property(nonatomic) UIEdgeInsets layoutMargins
Description   The default spacing to use when laying out content in the view.
Availability  iOS (8.0 and later)
Declared In   UIView.h
Reference UIView Class Reference

La soluzione:-

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

    if ([tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [tableView setSeparatorInset:UIEdgeInsetsZero];
    }

    if ([tableView respondsToSelector:@selector(setLayoutMargins:)]) {
        [tableView setLayoutMargins:UIEdgeInsetsZero];
    }

   if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
   }
}

Se imposti cell.layoutMargins = UIEdgeInsetsZero; senza verificare se esiste il layoutMargins , l'app si bloccherà su iOS 7.x. Quindi, il modo migliore sarebbe controllare se il layoutMargins esiste prima di setLayoutMargins:UIEdgeInsetsZero .




Swift:

override func viewDidLoad() {
    super.viewDidLoad()

    if self.tableView.respondsToSelector("setSeparatorInset:") {
        self.tableView.separatorInset = UIEdgeInsetsZero
    }
    if self.tableView.respondsToSelector("setLayoutMargins:") {
        self.tableView.layoutMargins = UIEdgeInsetsZero
    }

    self.tableView.layoutIfNeeded()            // <--- this do the magic
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
     ...

    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset = UIEdgeInsetsZero
    }
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins = UIEdgeInsetsZero
    }

    return cell
}



Questa è la mia soluzione. Questo vale per la sottoclasse di celle personalizzate, basta aggiungerle entrambe alla sottoclasse.

  1. - (UIEdgeInsets)layoutMargins {    
        return UIEdgeInsetsMake(0, 10, 0, 10);
    }
    

2.

self.separatorInset = UIEdgeInsetsMake(0, 10, 0, 10);

Ed è conveniente che tu possa personalizzare la posizione del separatore senza chiedere al tuo disegnatore di disegnarne uno per te ..........




Ecco un modo semplice per rimuovere globalmente l'inserto.

In UITableViewCell+Extensions.swift :

import UIKit

extension UITableViewCell {

  override public var layoutMargins: UIEdgeInsets {
    get { return UIEdgeInsetsZero }
    set { }
  }

}

Nell'applicazione AppDelegate application:didFinishLaunchingWithOptions: ::

  UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

Si potrebbe pensare a a) anche solo sovrascrivere separatorInset nell'estensione, oppure b) impostare invece il proxy dell'aspetto per layoutMargins . Né funzionerà. Anche se separatorInset è indicato come proprietà, il tentativo di sovrascriverlo come una proprietà (o metodo) genera errori del compilatore. Inoltre, l'impostazione del proxy dell'aspetto per layoutMargins UITableView (o anche per l'impostazione dei proxy di aspetto per layoutMargins e separatorInset UITableView ) non ha alcun effetto.




La maggior parte delle risposte mostra i separatori ei margini di layout impostati su una varietà di metodi (ad esempio, viewDidLayoutSubviews , willDisplayCell , ecc.) Per le celle e le visualizzazioni di tabelle, ma ho scoperto che il semplice inserimento di questi in cellForRowAtIndexPath funziona alla grande. Sembra il modo più pulito.

// kill insets for iOS 8
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) {
    cell.preservesSuperviewLayoutMargins = NO;
    [cell setLayoutMargins:UIEdgeInsetsZero];
}
// iOS 7 and later
if ([cell respondsToSelector:@selector(setSeparatorInset:)])
    [cell setSeparatorInset:UIEdgeInsetsZero];



Versione rapida

iOS introduce la proprietà layoutMargins su celle E viste tabella.

Questa proprietà non è disponibile in iOS 7.0, quindi è necessario assicurarsi di controllare prima di assegnarlo!

Tuttavia, Apple ha aggiunto una proprietà chiamata preservesSuperviewLayoutMargins alla tua cella che impedirà di ereditare le impostazioni dei margini della tua Vista tabella. In questo modo, le tue celle possono configurare i propri margini indipendentemente dalla vista tabella. Pensalo come un override.

Questa proprietà si chiama preservesSuperviewLayoutMargins e impostandola su NO può consentire di ignorare le impostazioni di layoutMargin della Vista tabella con l'impostazione di layout del mouse della propria cella. Risparmia tempo ( non è necessario modificare le impostazioni della Vista tabella ) ed è più conciso. Si prega di fare riferimento alla risposta di Mike Abdullah per una spiegazione dettagliata.

NOTA: questa è l'implementazione corretta e meno disordinata, come espresso nella risposta di Mike Abdullah; impostazione delle conserve della cellaSuperviewLayoutMargins = NO garantisce che la vista tabella non sostituisca le impostazioni della cella.

Primo passo: imposta i margini della tua cella:

/*
    Tells the delegate that the table view is about to draw a cell for a particular row.
*/
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,
    forRowAtIndexPath indexPath: NSIndexPath)
{
    // Remove separator inset
    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset = UIEdgeInsetsZero
    }

    // Prevent the cell from inheriting the Table View's margin settings
    if cell.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
        cell.preservesSuperviewLayoutMargins = false
    }

    // Explictly set your cell's layout margins
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins = UIEdgeInsetsZero
    }
}

L'impostazione della proprietà preservesSuperviewLayoutMargins sulla tua cella su NO dovrebbe impedire alla vista tabella di ignorare i margini della cella. In alcuni casi, sembra non funzionare correttamente.

Secondo passaggio: solo se tutto fallisce, puoi forzare la forza bruta sui margini della vista tabella:

/*
    Called to notify the view controller that its view has just laid out its subviews.
*/
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    // Force your tableview margins (this may be a bad idea)
    if self.tableView.respondsToSelector("setSeparatorInset:") {
        self.tableView.separatorInset = UIEdgeInsetsZero
    }

    if self.tableView.respondsToSelector("setLayoutMargins:") {
        self.tableView.layoutMargins = UIEdgeInsetsZero
    }
}

... e ci sei! Questo dovrebbe funzionare su iOS 8 e iOS 7.

Nota: testato usando iOS 8.1 e 7.1, nel mio caso ho solo dovuto usare il primo passo di questa spiegazione.

Il Secondo Passo è richiesto solo se hai una cella non popolata sotto le celle renderizzate, es. se la tabella è più grande del numero di righe nel modello di tabella. Se non si esegue la seconda fase, si otterrebbero offset di separatori diversi.




Esempio di Swift 3.0:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // removing seperator inset
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = .zero
    }
    // prevent the cell from inheriting the tableView's margin settings
    if cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins)) {
        cell.preservesSuperviewLayoutMargins = false
    }
    // explicitly setting cell's layout margins
    if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
        cell.layoutMargins = .zero
    }
}



Utilizzare lo snippet di codice seguente per evitare problemi di padding indesiderati per UITableView in IOS 8 e 7.

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

    if ([tableView respondsToSelector:@selector(setSeparatorInset:)])
    {
        [tableView setSeparatorInset:UIEdgeInsetsZero];
    }

    if ([tableView respondsToSelector:@selector(setLayoutMargins:)])
    {
        [tableView setLayoutMargins:UIEdgeInsetsZero];
    }

    if ([cell respondsToSelector:@selector(setLayoutMargins:)])
    {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}



Soluzione semplice in Swift per iOS 8 con UITableViewCell personalizzato

override func awakeFromNib() {
    super.awakeFromNib()

    self.layoutMargins = UIEdgeInsetsZero
    self.separatorInset = UIEdgeInsetsZero
}

In questo modo stai impostando layoutMargin e separatorInset solo una volta invece di farlo per ogni willDisplayCell come willDisplayCell maggior parte delle risposte precedenti.

Se stai usando un UITableViewCell personalizzato, questo è il posto giusto per farlo. Altrimenti dovresti farlo in tableView:cellForRowAtIndexPath .

Un altro suggerimento: non è necessario impostare preservesSuperviewLayoutMargins = false perché il valore predefinito è già NO !




Related