Inset 0 separatore UITableView iOS 8 non funzionante


662

Ho un'app in cui l' UITableViewinserzione del separatore è impostata su valori personalizzati: destra 0, sinistra 0. Funziona perfettamente in iOS 7.x, tuttavia iOS 8.0vedo che l'inserzione del separatore è impostata sul valore predefinito di 15sulla destra. Anche se nei file xib è impostato su0 , viene comunque visualizzato in modo errato.

Come rimuovo i UITableViewCellmargini del separatore?


Hai provato a impostare l'inser su 0,001 anziché su 0? Ricordo di avere un problema simile in cui l'inserto del bordo non reagiva a 0 ma reagiva a 0,001 (o qualcosa di simile piccolo).
matricola

Ci ho provato e non ha funzionato neanche ..
user3570727

4
Quindi suggerirei di impostare il colore dei separatori [UIColor clearColor]e di disegnare i tuoi separatori. In questo modo sei molto più flessibile.
matricola

1
Non riesco ancora a credere che questo non sia ancora uno dei UITableViewCellSeparatorStylevalori predefiniti. Anche la risposta accettata è un trucco davvero sporco secondo me.
Enrico Susatyo,

Risposte:


1071

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

Questa proprietà non è disponibile su iOS 7.0, quindi devi assicurarti di controllare prima di assegnarla!

La soluzione semplice è sottoclassare la cella e sovrascrivere la proprietà dei margini del layout come suggerito da @ user3570727. Tuttavia, perderai qualsiasi comportamento del sistema come ereditare i margini dall'area sicura, quindi non consiglio la seguente soluzione:

(ObjectiveC)

-(UIEdgeInsets)layoutMargins { 
     return UIEdgeInsetsZero // override any margins inc. safe area
}

(rapido 4.2):

override var layoutMargins: UIEdgeInsets { get { return .zero } set { } }

Se non si desidera sovrascrivere la proprietà o è necessario impostarla in modo condizionale, continuare a leggere.


Oltre alla layoutMarginsproprietà, Apple ha aggiunto una proprietà alla tua cella che le impedirà di ereditare le impostazioni dei margini della vista tabella. Quando questa proprietà è impostata, le celle possono configurare i propri margini indipendentemente dalla vista tabella. Pensalo come una sostituzione.

Questa proprietà viene chiamata preservesSuperviewLayoutMarginse impostandola su NOconsentirà alle layoutMarginimpostazioni della cella di sovrascrivere qualsiasi cosa layoutMarginsia impostata su TableView. Entrambi risparmiano tempo ( non è necessario modificare le impostazioni della vista tabella ) ed è più conciso. Fare riferimento alla risposta di Mike Abdullah per una spiegazione dettagliata.

NOTA: ciò che segue è un'implementazione pulita per un'impostazione del margine a livello di cella , come espresso nella risposta di Mike Abdullah. L'impostazione delle celle preservesSuperviewLayoutMargins=NOgarantirà che la vista tabella non sovrascriva le impostazioni della cella. Se desideri che l'intera vista della tabella abbia margini coerenti, modifica il codice di conseguenza.

Imposta i margini delle celle:

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Remove seperator inset
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
           [cell setSeparatorInset:UIEdgeInsetsZero];
    }

    // Prevent the cell from inheriting the Table View's margin settings
    if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
        [cell setPreservesSuperviewLayoutMargins:NO];
    }

    // Explictly set your cell's layout margins
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

Swift 4:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // Remove seperator inset
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = .zero
    }
    // Prevent the cell from inheriting the Table View's margin settings
    if cell.responds(to: #selector(setter: UITableViewCell.preservesSuperviewLayoutMargins)) {
        cell.preservesSuperviewLayoutMargins = false
    }
    // Explictly set your cell's layout margins
    if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
        cell.layoutMargins = .zero
    }
}

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

Se tutto fallisce, puoi forzare i tuoi margini di visualizzazione tabella:

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    // Force your tableview margins (this may be a bad idea)
    if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [self.tableView setSeparatorInset:UIEdgeInsetsZero];
    }

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

Swift 4:

func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    // Force your tableview margins (this may be a bad idea)
    if tableView.responds(to: #selector(setter: UITableView.separatorInset)) {
        tableView.separatorInset = .zero
    }
    if tableView.responds(to: #selector(setter: UITableView.layoutMargins)) {
        tableView.layoutMargins = .zero
    }
}

... e eccoti qua! Questo dovrebbe funzionare su iOS 7 e 8.


EDIT: Mohamed Saleh ha portato alla mia attenzione un possibile cambiamento in iOS 9. Potrebbe essere necessario impostare la vista tabella cellLayoutMarginsFollowReadableWidthsuNO se si desidera personalizzare inserti o margini. Il tuo chilometraggio può variare, questo non è documentato molto bene.

Questa proprietà esiste solo in iOS 9, quindi assicurati di controllare prima di impostare.

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

Swift 4:

if myTableView.responds(to: #selector(setter: self.cellLayoutMarginsFollowReadableWidth)) {
    myTableView.cellLayoutMarginsFollowReadableWidth = false
}

(sopra il codice da iOS 8 UITableView separator inset 0 non funziona )

EDIT: ecco un puro approccio Interface Builder:

TableViewAttributesInspector TableViewCellSizeInspector

NOTA: iOS 11 modifica e semplifica gran parte di questo comportamento, sarà disponibile un aggiornamento ...


2
Per le visualizzazioni di tabella all'interno di UIPopoverController, ho dovuto eseguire entrambe queste operazioni, come mostrato sopra, anziché solo in willDisplayCell.
Zhang,

44
Ho anche scoperto che nonostante tutto il codice sopra che dovevo ancora aggiungere cell.preservesSuperviewLayoutMargins = NOil suggerimento per @ bffmike o dopo aver fatto scorrere lo schermo, le inserzioni sarebbero apparse. (wtf ??)
inorganik

E se vogliamo impostare il margine solo per un tipo di cella in una tabella raggruppata?
SAHM,

Potresti provare a impostarlo in willDisplayCell e vedere se funziona davvero (hai un handle sulla cella, quindi dovrebbe essere banale). In caso contrario, dobbiamo presentare un bug. Dovrebbero essere possibili margini di layout specifici per cella, IMO.
cdstamper,

2
Questo ha funzionato per me con l'aggiunta di cell.preservesSuperviewLayoutMarginsnel mio metodo fonte di dati:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
MTS

257

Arg !!! Dopo aver giocato in uno dei due modi nella Cellsottoclasse:

- (UIEdgeInsets)layoutMargins
{
    return UIEdgeInsetsZero;
}

o impostando il cell.layoutMargins = UIEdgeInsetsZero;riparato per me.


13
la prima soluzione in questa risposta ha funzionato per me, la seconda non ha funzionato.
Spybart,

5
Non usare solo cell.layoutMargins = UIEdgeInsetsZero; poiché andrà in crash su iOS 7.x. È meglio verificare se il selettore esiste prima di usarlo. Vedi la mia soluzione di seguito.
Ricky,

3
Non sta impostando cell.layoutMargins ... Questa soluzione funziona benissimo quando hai già celle personalizzate.
Sjoerd Perfors,

11
Funzionerà perfettamente in iOS 7, poiché il metodo non verrà chiamato! Tuttavia, devi anche impostare i layout layout della vista tabella, altrimenti non funzionerà.
cdstamper,

2
scavalcando l'accessorio ha funzionato per me. ma tutte le altre soluzioni no. anche la configurazione di separatorInsetin IB non ha funzionato. c'è anche un problema con i colori di sfondo della vista tabella. questa è roba davvero malata.
glasz,

178

Prendiamoci un momento per capire il problema prima di caricare ciecamente per tentare di risolverlo.

Una rapida occhiata nel debugger ti dirà che le linee di separazione sono subview UITableViewCell. Sembra che la cella stessa si assuma una buona dose di responsabilità per il layout di queste linee.

iOS 8 introduce il concetto di margini di layout . Per impostazione predefinita, i margini del layout di una vista sono 8ptsu tutti i lati e sono ereditati dalle viste degli antenati.

Come meglio possiamo dire, quando si delinea la sua linea di separazione, UITableViewCellsceglie di rispettare il margine del layout di sinistra, usandolo per vincolare l'inserzione di sinistra.

Mettendo tutto insieme, per ottenere l'inserzione desiderata di veramente zero, dobbiamo:

  • Impostare il margine di layout sinistro su 0
  • Ferma i margini ereditati che lo sovrascrivono

Detto così, è un compito abbastanza semplice da raggiungere:

cell.layoutMargins = UIEdgeInsetsZero;
cell.preservesSuperviewLayoutMargins = NO;

Cose da notare:

  • Questo codice deve essere eseguito una sola volta per cella (dopotutto stai solo configurando le proprietà della cella) e non c'è nulla di speciale quando scegli di eseguirlo. Fai quello che ti sembra più pulito.
  • Purtroppo nessuna delle proprietà è disponibile per la configurazione in Interface Builder, ma preservesSuperviewLayoutMarginsse lo si desidera è possibile specificare un attributo di runtime definito dall'utente .
  • Chiaramente, se la tua app ha come target anche versioni precedenti del sistema operativo, dovrai evitare di eseguire il codice precedente fino a quando non viene eseguito su iOS 8 e versioni successive.
  • Invece di impostare preservesSuperviewLayoutMargins, è possibile configurare anche le viste degli antenati (come la tabella) in modo che abbiano 0margine sinistro, ma ciò sembra intrinsecamente più soggetto a errori poiché non si controlla l'intera gerarchia.
  • Probabilmente sarebbe leggermente più pulito impostare solo il margine sinistro 0e lasciare gli altri.
  • Se vuoi avere un inserto 0 sui separatori "extra" che UITableViewdisegna nella parte inferiore delle tabelle di stile semplice, immagino che richiederà di specificare le stesse impostazioni anche a livello di tabella (non ho provato questo!)

3
Grazie! Questa è davvero la risposta più concisa. Molto meglio che ignorare due metodi e costringerlo bruto.
LunaCodeGirl

16
In iOS 8, per me, questo non funzionerebbe senza[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
davetw12

1
Hai il mio voto, grazie per la chiara spiegazione. Devo solo menzionare che TableView stesso ha anche layoutMargins che potrebbe essere necessario impostare in aggiunta al separatorInset, in alcuni casi.
cdstamper,

@ davetw12 e @cdstamper Potete fornire prove di ciò? Tutte le mie esplorazioni finora dicono che l'impostazione sia layoutMarginse preservesSuperviewLayoutMarginssulla cellula è tutto ciò che è richiesto. Qualcos'altro sembra confidare nel voodoo.
Mike Abdullah,

3
No, non è una forma di voodoo @MikeAbdullah. Per evitare il valore predefinito separatorInsetdi a UITableViewCellin iOS 8, devi impostare il set UIEdgeInsetssu zero su entrambi UITableViewe su UITableViewCell. Se non fai entrambe le cose, avrai comunque un riquadro sinistro maggiore di zero. L'ho confermato più volte.
davetw12,

58

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 , esiste una nuova proprietà per tutti gli oggetti ereditati UIView. Quindi, la soluzione per impostare SeparatorInsetin iOS 7.x non sarà in grado di rimuovere lo spazio bianco che vedi 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

iOS 8 UITableView setSeparatorInset: UIEdgeInsetsZero setLayoutMargins: UIEdgeInsetsZero

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 layoutMarginsesiste, l'app andrà in crash su iOS 7.x. Quindi, il modo migliore sarebbe verificare se layoutMarginsesiste prima setLayoutMargins:UIEdgeInsetsZero.


Come può essere utilizzato questo approccio se la destinazione di distribuzione è impostata su iOS 7?
Petar,

Ho inserito il codice per tableView in viewDidLoad e funzionano perfettamente. Penso che non sia necessario chiamarli ogni volta in willDisplayCell ().
Abdullah Umer,

46

Puoi utilizzare UIAppearance una volta, all'avvio dell'applicazione (prima che l'interfaccia utente venga caricata), per impostarlo come impostazioni globali predefinite:

// iOS 7:
[[UITableView appearance] setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[[UITableView appearance] setSeparatorInset:UIEdgeInsetsZero];

[[UITableViewCell appearance] setSeparatorInset:UIEdgeInsetsZero];

// iOS 8:
if ([UITableView instancesRespondToSelector:@selector(setLayoutMargins:)]) {

    [[UITableView appearance] setLayoutMargins:UIEdgeInsetsZero];
    [[UITableViewCell appearance] setLayoutMargins:UIEdgeInsetsZero];
    [[UITableViewCell appearance] setPreservesSuperviewLayoutMargins:NO];

}

In questo modo, mantieni pulito il codice di UIViewController e puoi sempre sovrascriverlo se lo desideri.


41

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

Questa proprietà non è disponibile in iOS 7.0, quindi devi assicurarti di controllare prima di assegnarla!

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

Questa proprietà si chiama preservesSuperviewLayoutMargins e l'impostazione su NO può consentire di sovrascrivere le impostazioni layoutMargin della vista tabella con l'impostazione layoutMargin della propria cella. Entrambi risparmiano tempo ( non è necessario modificare le impostazioni della vista tabella ) ed è più conciso. Fare riferimento alla risposta di Mike Abdullah per una spiegazione dettagliata.

NOTA: questa è l'implementazione corretta, meno disordinata, come espresso nella risposta di Mike Abdullah; l'impostazione preservesSuperviewLayoutMargins della cella = NO garantirà che la vista tabella non sovrascriva le impostazioni della cella.

Primo passo: imposta i margini delle celle:

/*
    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 cella su NO dovrebbe impedire alla vista tabella di ignorare i margini della cella. In alcuni casi, sembra non funzionare correttamente.

Secondo passo - Solo se tutto fallisce, puoi forzare i 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 eccoti qua! Questo dovrebbe funzionare su iOS 8 e iOS 7.

Nota: testato con iOS 8.1 e 7.1, nel mio caso avevo solo bisogno di usare il primo passo di questa spiegazione.

Il secondo passaggio è necessario solo se hai una cella non popolata sotto le celle renderizzate, ad es. se la tabella è maggiore del numero di righe nel modello di tabella. Non eseguire il secondo passaggio comporterebbe diversi offset del separatore.


1
Non è necessario controllare i selettori nel willDisplayCellmetodo poiché il metodo stesso è già iOS 8+ e non verrà mai chiamato dalle versioni precedenti.
Rivera,

38

In Swift è leggermente più fastidioso perché layoutMarginsè una proprietà, quindi devi scavalcare getter e setter.

override var layoutMargins: UIEdgeInsets {
  get { return UIEdgeInsetsZero }
  set(newVal) {}
}

Questo effettivamente funzionerà di layoutMarginssola lettura, il che nel mio caso va bene.


Solo questa soluzione ha funzionato per me. E non ho avuto bisogno di aggiungere ulteriore codice di linee nei metodi. Ho usato celle personalizzate.
Ramis

2
Per le celle statiche, ad eccezione di LayoutMargins di sostituzione, è comunque necessario modificare lo stile del separatore della cella in "Inserti personalizzati" e impostare il valore sinistro su "0" nello storyboard.
hufeng03,

22

Per iOS 9 devi aggiungere:

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

Per maggiori dettagli si prega di fare riferimento alla domanda .


12
è divertente aggiungere del codice per ogni versione in modo che l'aspetto iniziale rimanga lo stesso ...
Christian

20

Estensione Swift 2.0

Volevo solo condividere un'estensione che ho fatto per rimuovere i margini dai separatori di celle di vista tabella.

extension UITableViewCell {
    func removeMargins() {

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

        if self.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
            self.preservesSuperviewLayoutMargins = false
        }

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

Usato nel contesto:

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell

    cell.removeMargins()
    return cell

15

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
}

11

L'ho fatto funzionare facendo questo:

tableView.separatorInset = UIEdgeInsetsZero;
tableView.layoutMargins = UIEdgeInsetsZero;
cell.layoutMargins = UIEdgeInsetsZero;

9

Per quanto riguarda ciò che cdstamper ha suggerito invece della vista tabella, l'aggiunta delle righe di seguito nel layout della cella Il metodo Subview funziona per me.

- (void)layoutSubviews 
{
    [super layoutSubviews];

    if ([self respondsToSelector:@selector(setSeparatorInset:)])
                [self setSeparatorInset:UIEdgeInsetsZero];

        if ([self respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)])
        {
            [self setPreservesSuperviewLayoutMargins:NO];;
        }

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

9

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
    }
}

9

Dopo molte indagini ...

Ecco l'unico modo per controllare completamente queste cose (che ho potuto trovare)

Per controllare completamente sia gli inserti di separazione che i margini di layout su ciascuna cella. Fallo nel willDisplayCellmetodo sul tuo UITableviewDelegate.

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.layoutMargins = UIEdgeInsetsZero
    cell.contentView.layoutMargins = UIEdgeInsetsMake(0, 10, 0, 10)
    cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0)
}

L'oggetto cella controlla il separatore e contentViewcontrolla tutto il resto. Se gli spazi degli inserti del separatore vengono visualizzati con un colore imprevisto, ciò dovrebbe risolverlo:

cell.backgroundColor = cell.contentView.backgroundColor

8

Soluzione semplice in Swift per iOS 8 con una personalizzazioneUITableViewCell

override func awakeFromNib() {
    super.awakeFromNib()

    self.layoutMargins = UIEdgeInsetsZero
    self.separatorInset = UIEdgeInsetsZero
}

In questo modo stai impostando layoutMargine separatorInsetsolo una volta invece di farlo per ciascunowillDisplayCell come suggerisce la maggior parte delle risposte di cui sopra.

Se stai usando un'abitudine, UITableViewCellquesto è il posto giusto per farlo. Altrimenti dovresti farlotableView:cellForRowAtIndexPath .

Solo un altro suggerimento: non è necessario impostare preservesSuperviewLayoutMargins = falseperché il valore predefinito è già NO!


8

Per me la linea semplice ha fatto il lavoro

cell.layoutMargins = UIEdgeInsetsZero

chiamato questo nel metodo delegato cellForRowAtIndexPath. Buona risposta :)
saintjab

7

Basta aggiungere il codice qui sotto per risolvere questo programma.

Buona fortuna a te!

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

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

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

}

5

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
    }

5

Questo è il codice che funziona per me, in Swift:

override func viewDidLoad() 
{
    super.viewDidLoad()
    ...
    if tableView.respondsToSelector("setSeparatorInset:") {
        tableView.separatorInset = UIEdgeInsetsZero
    }
}

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath)
{
    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset.left = CGFloat(0.0)
    }
    if tableView.respondsToSelector("setLayoutMargins:") {
        tableView.layoutMargins = UIEdgeInsetsZero
    }
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins.left = CGFloat(0.0)
    }
}

Questo mi sembra il più pulito (per ora), poiché tutte le regolazioni del bordo / margine della cella / tabella di visualizzazione vengono eseguite nel tableView:willDisplayCell:forRowAtIndexPath:metodo, senza inserire codice inutile in tableView:cellForRowAtIndexPath:.

A proposito, sto solo impostando il separatore sinistro della cellaInset / layoutMargins, perché in questo caso non voglio rovinare i miei vincoli che ho impostato nella mia cella.

Codice aggiornato a Swift 2.2:

 override func viewDidLoad() {
   super.viewDidLoad()       

    if tableView.respondsToSelector(Selector("setSeparatorInset:")) {
      tableView.separatorInset = UIEdgeInsetsZero
        }
    }

 override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath) {
        if cell.respondsToSelector(Selector("setSeparatorInset:")) {
            cell.separatorInset.left = CGFloat(0.0)
        }
        if tableView.respondsToSelector(Selector("setLayoutMargins:")) {
            tableView.layoutMargins = UIEdgeInsetsZero
        }
        if cell.respondsToSelector(Selector("setLayoutMargins:")) {
            cell.layoutMargins.left = CGFloat(0.0)
        }
    }

Cosa non funziona esattamente per te? Ho appena testato questo codice sul simulatore di iPhone 5, con l'SDK di iOS 8.1 installato, e tutto è come quando ho pubblicato questa risposta. Il codice è stato compilato ed eseguito con Xcode 6.1.1.
Ivan

4

La maggior parte delle risposte mostrano inserti di separazione e margini di layout di essere impostati su una varietà di metodi (cioè viewDidLayoutSubviews, willDisplayCell, ecc) per celle e tableviews, ma ho trovato che solo mettendo questi in cellForRowAtIndexPathgrandi opere. 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];

4

Utilizzare lo snippet di codice seguente per evitare problemi di imbottitura 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];
    }
}

4

Invece di aggiornare preservesSuperviewLayoutMarginse layoutMarginsogni volta che la cella scorre (usando willDisplayCell), suggerirei di farlo una volta in cellForRowAtIndexPath::

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

    let cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)

    cell.preservesSuperviewLayoutMargins = false
    cell.layoutMargins = UIEdgeInsetsZero

    return cell

}

4

Ecco un modo semplice per rimuovere l'inserzione a livello globale.

In UITableViewCell+Extensions.swift:

import UIKit

extension UITableViewCell {

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

}

In AppDelegate application:didFinishLaunchingWithOptions::

  UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

Si potrebbe pensare a a) anche semplicemente sostituire separatorInsetl'estensione, oppure b) impostare invece il proxy aspetto layoutMargins. Né funzionerà. Anche se separatorInsetè indicata come una proprietà, il tentativo di sovrascriverla come proprietà (o metodo) genera errori del compilatore. E l'impostazione del proxy dell'aspetto per UITableViewCell' layoutMargins(o, del resto, anche l'impostazione dei proxy dell'aspetto per UITableView' layoutMarginse separatorInset) non ha alcun effetto.


3

In iOS8:

Aggiungendo questo alla mia sottoclasse UITableViewCell:

- (UIEdgeInsets)layoutMargins {
    return UIEdgeInsetsZero;
}

e questo a "tableView: cellForRowAtIndexPath" o "tableView: willDisplayCell":

[editCell setSeparatorInset:UIEdgeInsetsZero];

Ha funzionato per me.


2
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        // ... Get the cell
        cell.separatorInset = UIEdgeInsetsMake(0.f, 20.f, 0.f, [UIScreen mainScreen].bounds.size.width - 20);
        // others
        return cell;
}

Per ogni cella specifica che si desidera nascondere il separatore.


2

Dopo aver visto le risposte al terzo piano, ho cercato di capire quale fosse la relazione tra la configurazione del separatore tra TableView e TableViewCell e ho fatto alcuni test. Ecco le mie conclusioni:

  1. possiamo considerare che l'impostazione del separatore della cella su zero deve spostare il separatore in due fasi: il primo passo è impostare il separatore della cella su zero. il secondo passo è impostare il marginlayout della cella su zero.

  2. impostare il separatorinset di TableView e marginlayout può influire sul separatorinset della cella . Tuttavia, dal test, trovo che l'insieme di separatori di TableView sembra essere inutile, il marginlayout di TableView può effettivamente influenzare il marginlayout della cella .

  3. imposta Cell's PreservesSuperviewLayoutMargins = false, può tagliare l' effetto marginlayout di TableView su Cells.

  4. una delle soluzioni:

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell = UITableViewCell()
    
        cell.preservesSuperviewLayoutMargins = false
        cell.separatorInset = UIEdgeInsetsZero
        cell.layoutMargins = UIEdgeInsetsZero
    
        return cell
    }

2

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 puoi personalizzare la posizione del separatore senza chiedere al tuo designer di disegnarne uno per te ..........


1

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];
    }

}


1

Aggiungendo questo frammento, semplice ed elegante in Swift funziona per me in iOS8 :)

    // tableview single line
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.preservesSuperviewLayoutMargins = false
    cell.layoutMargins = UIEdgeInsetsZero
}

1

Questo ha funzionato perfettamente per me in 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;
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.