it-swarm.com.de

iOS 8 UITableView Separator-Inset funktioniert nicht

Ich habe eine App, bei der die Trennzeichen-Einfügung von UITableView auf benutzerdefinierte Werte eingestellt ist - Right 0, Left 0. Dies funktioniert einwandfrei in iOS 7.x, in iOS 8.0 sehe ich jedoch, dass der Trennzeichen-Inset auf der rechten Seite auf 15 gesetzt ist. Obwohl es in den xib-Dateien auf 0 gesetzt ist, wird es trotzdem falsch angezeigt.

Wie entferne ich die Trennzeichen für UITableViewCell separator?

643
user3570727

In iOS 8.0 wird die layoutMargins-Eigenschaft für Zellen UND Tabellensichten eingeführt.

Diese Eigenschaft ist unter iOS 7.0 nicht verfügbar. Sie müssen daher unbedingt prüfen, bevor Sie sie zuweisen.

Darüber hinaus hat Apple Ihrer Zelle ein property hinzugefügt, um zu verhindern, dass die Randeinstellungen der Tabellenansicht übernommen werden. Wenn diese Eigenschaft festgelegt ist, können Ihre Zellen ihre eigenen Ränder unabhängig von der Tabellenansicht konfigurieren. Betrachten Sie es als Überschreibung.

Diese Eigenschaft wird preservesSuperviewLayoutMargins genannt. Wenn Sie sie auf NO setzen, kann die Einstellung layoutMargin der Zelle die Einstellung von layoutMargin überschreiben, die in Ihrer TableView festgelegt ist. Dies spart Zeit (Sie müssen die Einstellungen der Tabellenansicht nicht ändern) und ist übersichtlicher. Eine detaillierte Erklärung finden Sie in der Antwort von Mike Abdullah.

HINWEIS: Was folgt, ist eine saubere Implementierung für eine Margin-Einstellung auf Zellenebene, wie in der Antwort von Mike Abdullah ausgedrückt. Wenn Sie preservesSuperviewLayoutMargins=NO Ihrer Zelle festlegen, wird sichergestellt, dass Ihre Tabellenansicht die Zelleneinstellungen nicht überschreibt. Wenn Sie möchten, dass Ihre gesamte Tabellenansicht konsistente Ränder aufweist, passen Sie Ihren Code entsprechend an.

Richten Sie Ihre Zellränder ein:

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

Durch Festlegen der preservesSuperviewLayoutMargins-Eigenschaft in Ihrer Zelle auf NO sollte sollten Sie verhindern, dass Ihre Tabellenansicht Ihre Zellränder überschreibt. In einigen Fällen scheint es nicht richtig zu funktionieren.

Wenn alles fehlschlägt, können Sie Ihre Tabellenansicht-Ränder brutal erzwingen:

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

... und los gehts! Dies sollte unter iOS 7 und 8 funktionieren.

EDIT:Mohamed Saleh hat mich auf eine mögliche Änderung in iOS 9 aufmerksam gemacht.} Möglicherweise müssen Sie die cellLayoutMarginsFollowReadableWidth der Tabellenansicht auf NO setzen, wenn Sie Einfügungen oder Ränder anpassen möchten. Ihre Laufleistung kann variieren, dies ist nicht sehr gut dokumentiert.

Diese Eigenschaft ist nur in iOS 9 vorhanden. Überprüfen Sie daher unbedingt die Einstellung.

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

Swift 4:

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

(obiger Code von iOS 8 UITableView-Trennzeichen-Einfügung 0 funktioniert nicht )

EDIT: Hier ist ein reiner Interface Builder-Ansatz:

 TableViewAttributesInspector  TableViewCellSizeInspector

HINWEIS: iOS 11 ändert und vereinfacht vieles von diesem Verhalten, ein Update wird in Kürze veröffentlicht ...

1066
cdstamper

Arg !!! Nachdem Sie entweder in Ihrer Cell-Unterklasse herumgespielt haben: 

- (UIEdgeInsets)layoutMargins
{
    return UIEdgeInsetsZero;
}

oder das Einstellen des cell.layoutMargins = UIEdgeInsetsZero; hat es für mich behoben. 

255
user3570727

Nehmen wir uns einen Moment Zeit, um das Problem zu verstehen, bevor Sie blind versuchen, es zu beheben.

Ein kurzes Umschalten im Debugger zeigt an, dass die Trennlinien Unteransichten von UITableViewCell sind. Es scheint, dass die Zelle selbst ziemlich viel Verantwortung für das Layout dieser Linien übernimmt.

iOS 8 führt das Konzept von Layoutränder ein. Standardmäßig sind die Layoutränder einer Ansicht auf allen Seiten 8pt und aus Vorfahrenansichten geerbt.

Wie man am besten erkennen kann, wählt UITableViewCell beim Layout der Trennlinie den linken Layoutrand und verwendet diesen, um den linken Einschub einzuschränken.

Um dies zu erreichen, müssen wir:

  • Setzen Sie den linken Layoutrand auf 0.
  • Verhindern Sie, dass alle vererbten Ränder das überschreiben

So gesehen ist es eine ziemlich einfache Aufgabe:

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

Dinge zu beachten:

  • Dieser Code muss nur benötigt einmal pro Zelle ausgeführt werden (Sie konfigurieren nur die Eigenschaften der Zelle), und es gibt nichts Besonderes, wenn Sie sie ausführen. Tun Sie, was Ihnen am saubersten erscheint.
  • Leider ist keine der Eigenschaften für die Konfiguration im Interface Builder verfügbar, Sie können jedoch bei Bedarf ein benutzerdefiniertes Laufzeitattribut für preservesSuperviewLayoutMargins angeben.
  • Wenn Ihre App auch auf ältere Betriebssystemversionen abzielt, müssen Sie die Ausführung des obigen Codes erst unter iOS 8 und höher vermeiden.
  • Anstatt preservesSuperviewLayoutMargins einzustellen, konfigurieren Sie can Vorfahrenansichten (z. B. die Tabelle) so, dass auch 0 linker Rand vorhanden ist. Dies scheint jedoch inhärent fehleranfälliger zu sein, da Sie nicht die gesamte Hierarchie steuern.
  • Es wäre wahrscheinlich etwas sauberer, nur den linken Rand auf 0 zu setzen und die anderen zu belassen.
  • Wenn Sie eine 0-Einfügung für die "zusätzlichen" Trennzeichen haben möchten, die UITableView unten in einfachen Stiltabellen zeichnet, ist es wahrscheinlich, dass Sie dieselben Einstellungen auch auf Tabellenebene angeben müssen (haben Sie diese nicht probiert!)
178
Mike Abdullah

Ich glaube, das ist die gleiche Frage, die ich hier gestellt habe: Entfernen Sie SeparatorInset unter iOS 8 UITableView für XCode 6 iPhone Simulator

In iOS 8 gibt es eine neue Eigenschaft für alle von UIView geerbten Objekte. Die Lösung zum Festlegen von SeparatorInset in iOS 7.x kann also den in UITableView unter iOS 8 angezeigten Leerraum nicht entfernen. 

Die neue Eigenschaft heißt "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

Die Lösung:-

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

Wenn Sie cell.layoutMargins = UIEdgeInsetsZero; einstellen, ohne zu prüfen, ob layoutMargins vorhanden ist, stürzt die App unter iOS 7.x ab. Der beste Weg wäre also zu prüfen, ob layoutMargins zuerst vor setLayoutMargins:UIEdgeInsetsZero existiert.

58
Ricky

Sie können UIAppearance einmalig beim Start der Anwendung (vor dem Laden der Benutzeroberfläche) verwenden, um sie als globale Standardeinstellungen festzulegen:

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

}

Auf diese Weise halten Sie den Code Ihres UIViewControllers sauber und können ihn jederzeit überschreiben, wenn Sie möchten.

46
Lukasz

iOS führt die layoutMargins-Eigenschaft für Zellen UND Tabellenansichten ein.

Diese Eigenschaft ist in iOS 7.0 nicht verfügbar. Sie müssen daher unbedingt prüfen, bevor Sie sie zuweisen.

Allerdings hat Apple Ihrer Zelle eine property mit dem Namen preservesSuperviewLayoutMargins hinzugefügt, um zu verhindern, dass die Randeinstellungen der Table View übernommen werden. Auf diese Weise können Ihre Zellen unabhängig von der Tabellenansicht ihre eigenen Ränder konfigurieren. Betrachten Sie es als Überschreibung.

Diese Eigenschaft heißt preservesSuperviewLayoutMargins. Wenn Sie die Einstellung auf NO setzen, können Sie die layoutMargin-Einstellungen Ihrer Table View mit der layoutMargin-Einstellung Ihrer eigenen Zelle überschreiben. Dies spart Zeit ( Sie müssen die Einstellungen der Tabellenansicht nicht ändern ) und ist übersichtlicher. Eine detaillierte Erklärung finden Sie in der Antwort von Mike Abdullah.

HINWEIS: Dies ist die korrekte, weniger chaotische Implementierung, wie sie in der Antwort von Mike Abdullah zum Ausdruck kommt. Durch das Setzen von preservesSuperviewLayoutMargins = NO in Ihrer Zelle wird sichergestellt, dass die Tabellenansicht die Zelleneinstellungen nicht überschreibt.

Erster Schritt - Richten Sie Ihre Zellränder ein:

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

Durch Festlegen der Eigenschaft preservesSuperviewLayoutMargins in Ihrer Zelle auf NO sollte verhindern, dass Ihre Tabellenansicht die Zellränder überschreibt. In einigen Fällen scheint es nicht richtig zu funktionieren.

Zweiter Schritt - Nur wenn alle fehlschlagen, können Sie Ihre Tabellenansichtsränder brutal erzwingen:

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

... und los gehts! Dies sollte unter iOS 8 und iOS 7 funktionieren.

Hinweis: Mit iOS 8.1 und 7.1 getestet, in meinem Fall musste ich nur den ersten Schritt dieser Erklärung verwenden.

Der zweite Schritt ist nur erforderlich, wenn sich unter den gerenderten Zellen eine unbesetzte Zelle befindet, z. wenn die Tabelle größer als die Anzahl der Zeilen im Tabellenmodell ist. Wenn Sie den zweiten Schritt nicht ausführen, führt dies zu unterschiedlichen Separator-Offsets.

41
King-Wizard

In Swift ist es etwas ärgerlicher, da layoutMargins eine Eigenschaft ist. Sie müssen also die getter und setter überschreiben.

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

Dies macht layoutMargins praktisch zum Readonly, was in meinem Fall in Ordnung ist.

37
swilliams

Für iOS 9 müssen Sie Folgendes hinzufügen:

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

Weitere Einzelheiten finden Sie unter Frage .

22
Julian Król

Swift 2.0 Erweiterung

Ich wollte nur eine Erweiterung teilen, die ich gemacht habe, um die Ränder von den Tabellentrennzeichen zu entfernen.

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

Im Kontext verwendet:

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

    cell.removeMargins()
    return cell
19
Dan Beaulieu

Schnell:

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

Ich habe es so gemacht, dass es funktioniert:

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

Swift 3.0 Beispiel:

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
mkz

Nach langer Untersuchung ...

Dies ist der einzige Weg, um dieses Zeug vollständig zu kontrollieren (was ich finden konnte)

So können Sie sowohl die Trennzeichen-Einsätze als auch die Layout-Ränder in jeder Zelle vollständig steuern. Tun Sie dies in der willDisplayCell-Methode auf Ihrer 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)
}

Das Zellobjekt steuert das Trennzeichen und die Variable contentView alles andere. Wenn Ihre Trennzeichen in einer unerwarteten Farbe angezeigt werden, sollte dies behoben sein:

cell.backgroundColor = cell.contentView.backgroundColor
9
Matjan

Was cdstamper anstelle der Tabellensicht vorschlug, funktioniert das Hinzufügen von Zeilen unterhalb der layoutSubview-Methode der Zelle für mich.

- (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
Vijay V S

Einfache Lösung in Swift für iOS 8 mit einer benutzerdefinierten UITableViewCell

override func awakeFromNib() {
    super.awakeFromNib()

    self.layoutMargins = UIEdgeInsetsZero
    self.separatorInset = UIEdgeInsetsZero
}

Auf diese Weise stellen Sie layoutMargin und separatorInset nur einmal ein, anstatt es für jede willDisplayCell zu tun, wie die meisten der obigen Antworten nahelegen. 

Wenn Sie eine benutzerdefinierte UITableViewCell verwenden, ist dies der richtige Ort dafür. .__ Ansonsten sollten Sie es in tableView:cellForRowAtIndexPath tun.

Noch ein Hinweis: Sie müssen preservesSuperviewLayoutMargins = false nicht festlegen, da der Standardwert bereits NO ist!

8

Für mich hat die einfache Linie den Job gemacht

cell.layoutMargins = UIEdgeInsetsZero
8
apinho

Fügen Sie einfach folgenden Code hinzu, um dieses Programm zu lösen. 

Viel Glück!

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

}
7
JimmyChang

Dies ist der Code, der für mich in Swift funktioniert:

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

Dies erscheint mir (vorerst) am saubersten, da alle Anpassungen von Zelle/tableView-Rand/Rand in der tableView:willDisplayCell:forRowAtIndexPath:-Methode vorgenommen werden, ohne unnötigen Code in tableView:cellForRowAtIndexPath: einzuengen.

Übrigens, ich setze nur die linken separatorInset/layoutMargins der Zelle, da ich in diesem Fall meine Einschränkungen, die ich in meiner Zelle eingerichtet habe, nicht vermasseln möchte.

Code auf Swift 2.2 aktualisiert:

 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)
        }
    }
5
Ivan

Bei den meisten Antworten werden Trennzeichen-Insets und Layout-Ränder für eine Vielzahl von Methoden (z. B. viewDidLayoutSubviews, willDisplayCell usw.) für Zellen und Tabellenansichten festgelegt. Ich habe jedoch festgestellt, dass es einfach gut ist, diese in cellForRowAtIndexPath zu setzen. Scheint wie der sauberste Weg.

// 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
inorganik

Lukasz antwortet 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
    }
4
Naka

Anstatt preservesSuperviewLayoutMargins und layoutMargins jedes Mal zu aktualisieren, wenn die Zelle hineinrollt (mithilfe von willDisplayCell), würde ich vorschlagen, dies einmal in cellForRowAtIndexPath: durchzuführen:

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

Verwenden Sie den folgenden Code-Ausschnitt, um UITableView in IOS 8 & 7 zu vermeiden.

-(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
Anooj VM

Hier ist eine einfache Möglichkeit, den Einschub global zu entfernen.

Im UITableViewCell+Extensions.Swift:

import UIKit

extension UITableViewCell {

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

}

In AppDelegateapplication:didFinishLaunchingWithOptions::

  UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

Sie könnten denken, dass Sie a) auch nur separatorInset in der Erweiterung überschreiben oder b) stattdessen den Darstellungs-Proxy für layoutMargins festlegen. Beides wird nicht funktionieren. Obwohl angegeben wird, dass separatorInset eine Eigenschaft ist, führt der Versuch, diese als Eigenschaft (oder Methode) zu überschreiben, zu Compilerfehlern. Festlegen des Darstellungs-Proxys für UITableViewCell 's layoutMargins (oder auch Festlegen der Darstellungs-Proxys für UITableView' s layoutMargins und separatorInset) ) hat keine Auswirkung.

3
Scott Gardner

In iOS8:

Hinzufügen zu meiner UITableViewCell-Unterklasse: 

- (UIEdgeInsets)layoutMargins {
    return UIEdgeInsetsZero;
}

und dies zu "tableView: cellForRowAtIndexPath" oder "tableView: willDisplayCell":

[editCell setSeparatorInset:UIEdgeInsetsZero];

Für mich gearbeitet.

3
CoderSaru
-(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;
}

Für eine bestimmte Zelle, in der Sie das Trennzeichen ausblenden möchten.

2
xmurobi

Das ist meine Lösung. Dies gilt für die benutzerdefinierte Unterklasse der Zellen. Fügen Sie beide zur Unterklasse hinzu.

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

2.

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

Es ist praktisch, dass Sie die Position des Trennzeichens anpassen können, ohne dass Ihr Designer Sie dazu auffordert, einen für Sie zu zeichnen.

2
Guoyu

Nachdem ich die Antworten auf Ebene 3 gesehen hatte, versuchte ich herauszufinden, in welcher Beziehung das Trennzeichen zwischen TableView und TableViewCell steht, und habe einige Tests durchgeführt. Hier sind meine Schlussfolgerungen:

  1. wenn Sie das Trennzeichen der Zelle auf Null setzen, muss das Trennzeichen in zwei Schritten verschoben werden: Zuerst setzen Sie separatorinset der Zelle auf Null. Im zweiten Schritt setzen Sie marginlayout der Zelle auf Null.

  2. setzen Sie das TableView-separatorinset und marginlayout, um das separatorinset der Zelle zu beeinflussen. Im Test finde ich jedoch, dass das separatorinset von TableView unbrauchbar zu sein scheint. Das marginlayout von TableView kann sich jedoch auf marginlayout der Zelle auswirken.

  3. wenn Sie PreservesSuperviewLayoutMargins von Cell festlegen, wird der Effekt marginlayout von TableView auf Cells abgeschnitten.

  4. eine der Lösungen: 

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

Auf kompaktere Weise als die meistbeachtete Antwort ...

- (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
subharb

Das hat für mich in iOS 8 und iOS 9 perfekt funktioniert.

Für 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;
    }
1
jithin

Das Hinzufügen dieses Snippets, einfach elegant in Swift, funktioniert für mich in iOS8 :)

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

Meine Lösung fügt eine UIView als Container für die Zellunteransichten hinzu. Setzen Sie dann diese UIView-Einschränkungen (oben, unten, nachgestellt, führend) auf 0 Punkte. Und alle unnötigen Massen verschwinden. das Bild zeigt die Logik

0
memetcircus

Mit keiner der oben genannten Lösungen hatte ich wirklich Glück. Ich verwende NIB-Dateien für meine Tabellenzellen. Ich habe dieses Problem durch Hinzufügen eines Etiketts mit der Höhe "1" behoben. Ich habe den Hintergrund des Etiketts in Schwarz geändert, das Etikett am unteren Rand der Spitze befestigt und dann den unteren Teil des Inhalts mit dem hinzugefügten Etikett verbunden . Jetzt habe ich einen schwarzen Rand entlang meiner Zellen.

Für mich fühlt sich das eher wie ein Hack an, aber es funktioniert.

Meine einzige andere Wahl war, die Grenze vollständig zu beseitigen. Ich entscheide immer noch, ob ich das einfach so mache.

0
Scott

lass es als meinen Code tun:

-(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 ([tableView respondsToSelector:@selector(setLayoutMargins:)]) {
        cell.preservesSuperviewLayoutMargins = NO;
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]){
        [cell setSeparatorInset:UIEdgeInsetsZero];
    }
}
0
Bkillnest

 enter image description here

verwenden Sie das Storyboard, um die Trennzeichen-Einfügung zu ändern 

0
Phani Sai

Überschreiben Sie einfach "cellForRowAtIndexPath" und setzen Sie "cell.preservesSuperviewLayoutMargins = false" und "cell.separatorInset = UIEdgeInsets.zero" und "cell.layoutMargins = UIEdgeInsets.zero"

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell: LayoutTableViewCell! = tableView.dequeueReusableCell(withIdentifier: "LayoutCell") as? LayoutTableViewCell



    let currentLayout = OrderLayouts()[indexPath.row]

    cell.NameLabel?.text = currentLayout.name
    cell.DescrLabel?.text = currentLayout.descr

    if(GlobalVariables.debug){

        cell.DescrLabel?.text = "\(currentLayout.id) \n \(currentLayout.descr)"

    }

    cell.preservesSuperviewLayoutMargins = false
    cell.separatorInset = UIEdgeInsets.zero
    cell.layoutMargins = UIEdgeInsets.zero


    return cell

}
0
MDalprato

Für mich hat bis auf diesen Workaround keiner funktioniert ( Swift 3.0 ):

extension UIColor {
    static func colorWith(hex:String, alpha: CGFloat) -> UIColor {
        var cString = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()

        if cString.hasPrefix("#") {
            cString.remove(at: cString.startIndex)
        }

        if cString.characters.count != 6 {
            return UIColor.gray
        }

        var rgbValue:UInt32 = 0
        Scanner(string: cString).scanHexInt32(&rgbValue)

        return UIColor(red:   CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
                       green: CGFloat((rgbValue & 0x00FF00) >> 8)  / 255.0,
                       blue:  CGFloat( rgbValue & 0x0000FF)        / 255.0,
                       alpha: alpha)
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdendifier, for: indexPath)

    cell.backgroundColor = UIColor.colorWith(hex: "c8c7cc", alpha: 1) // same color of line separator

    return cell
}
0
Daniele Ceglia

nach der Antwort von @cdstamper ist layoutSubviews von UITableViewCell in Ihrer Zellendatei (ich kann einen Abstand von 1% festlegen, Sie können auf Null setzen), ein besserer Platz.

 -(void)layoutSubviews
    {
        [super layoutSubviews];
        if ([self respondsToSelector:@selector(setSeparatorInset:)]) {
            [self setSeparatorInset:UIEdgeInsetsMake(0,self.bounds.size.width*0.01,0,self.bounds.size.width*0.01)];
        }
        if ([self respondsToSelector:@selector(setLayoutMargins:)]) {
            [self setLayoutMargins:UIEdgeInsetsMake(0,self.bounds.size.width*0.01,0,self.bounds.size.width*0.01)];
        }
    }
0
BollMose

In Swift kannst du dies verwenden

    cell.selectionStyle = UITableViewCellSelectionStyle.None
    cell.preservesSuperviewLayoutMargins = false
    cell.separatorInset = UIEdgeInsetsZero
    cell.layoutMargins = UIEdgeInsetsZero
0
Anny

Ich habe all diese wunderbaren Antworten durchgesehen und festgestellt, dass die meisten von ihnen nicht mit iOS 8 funktionieren oder funktionieren, aber das Trennzeichen ändert die Größe während der Animation und verursacht unerwünschtes Flashing. Das habe ich letztendlich in meinem App-Delegierten gemacht, bevor ich das Fenster erstellt habe:

[[UITableView appearance] setSeparatorInset:UIEdgeInsetsZero];
[[UITableViewCell appearance] setSeparatorInset:UIEdgeInsetsZero];

if ([UITableView instancesRespondToSelector:@selector(setLayoutMargins:)]) {
    [[UITableView appearance] setLayoutMargins:UIEdgeInsetsZero];
    [[UITableViewCell appearance] setLayoutMargins:UIEdgeInsetsZero];
    [[UITableViewCell appearance] setPreservesSuperviewLayoutMargins:NO];
}

Und das habe ich meinem UITableViewController hinzugefügt:

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

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

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

Ich musste nichts anderes hinzufügen. Vielen Dank an alle, die die entscheidenden Teile geliefert haben.

0
spstanley

fügen Sie diese beiden Zeilen einfach in die cellForRowAtIndexPath-Methode ein

  • wenn Sie möchten, dass alle Trennzeilen von Null beginnen [cell setSeparatorInset: UIEdgeInsetsZero]; [cell setLayoutMargins: UIEdgeInsetsZero];

wenn Sie möchten, dass Spezifische Trennlinie von Null aus beginnt, nehmen Sie an, dass die letzte Zeile von Null beginnt 

if (indexPath.row == array.count-1) 
{
   [cell setSeparatorInset:UIEdgeInsetsZero];
   [cell setLayoutMargins:UIEdgeInsetsZero];
}
else
   tblView.separatorInset=UIEdgeInsetsMake(0, 10, 0, 0);
0
Shabnam

iOS 8 und höher. Swift 2.0 und höher:

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.separatorInset = UIEdgeInsetsZero
    if #available(iOS 8.0, *) {
        cell.layoutMargins = UIEdgeInsetsZero
    } else {
        // Fallback on earlier versions
    }
}
0
Zia