iOS 8 UITableView Separator Inset 0 funktioniert nicht




objective-c swift (20)

Swift 2.0 Erweiterung

Ich wollte nur eine Erweiterung teilen, die ich gemacht habe, um die Ränder von den tableview Zelltrennzeichen 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

Ich habe eine App, bei der der UITableView des UITableView auf benutzerdefinierte Werte gesetzt ist - Right 0 , Left 0 . Dies funktioniert perfekt in iOS 7.x , aber in iOS 8.0 sehe ich, dass der Separatoreinsatz auf der rechten Seite auf den Standardwert 15 . Obwohl es in den xib-Dateien auf 0 , wird es immer noch falsch angezeigt.

Wie entferne ich die UITableViewCell Trennzeichen Ränder?


Nach viel Nachforschungen ...

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

Um beide Trenneinfügungen und Layout-Ränder für jede Zelle vollständig zu steuern. Tun Sie dies in der Methode willDisplayCell auf Ihrem 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 contentView steuert das Trennzeichen und das contentView steuert alles andere. Wenn die eingefügten Trennbereiche in einer unerwarteten Farbe angezeigt werden, sollte das Problem gelöst werden:

cell.backgroundColor = cell.contentView.backgroundColor

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

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

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

    cell.preservesSuperviewLayoutMargins = false
    cell.layoutMargins = UIEdgeInsetsZero

    return cell

}

Arg !!! Nachdem du das in deiner Cell Unterklasse gemacht hast:

- (UIEdgeInsets)layoutMargins
{
    return UIEdgeInsetsZero;
}

oder cell.layoutMargins = UIEdgeInsetsZero; reparierte es für mich.


Die meisten Antworten zeigen Separator-Einfügungen und Layout-Ränder, die über eine Vielzahl von Methoden ( viewDidLayoutSubviews , willDisplayCell , etc.) für Zellen und Tabellenansichten gesetzt werden, aber ich habe festgestellt, dass es einfach ist, diese in cellForRowAtIndexPath . 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];

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 scheint für mich am saubersten zu sein, da alle cell / tableView Edge / Margin Anpassungen in der tableView:willDisplayCell:forRowAtIndexPath: Methode vorgenommen werden, ohne überflüssigen Code in tableView:cellForRowAtIndexPath:

Übrigens, ich setze nur das linke Trennzeichen der Zelle in set / layoutMargins, weil 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)
        }
    }

Fügen Sie einfach unten 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];
       }

}

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

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

Für weitere Details lesen Sie bitte die question .


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

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

Sie könnten denken, a) überschreiben Sie auch separatorInset in der Erweiterung oder b) legen layoutMargins stattdessen den Darstellungsproxy für layoutMargins . Keine wird funktionieren. Auch wenn " separatorInset als Eigenschaft angegeben ist, generiert der Versuch, es als Eigenschaft (oder Methode) zu überschreiben, Compilerfehler. Und das Einstellen des Darstellungs - Proxys für die UITableViewCell layoutMargins (oder auch das Festlegen der Darstellungs - Proxies für die layoutMargins und das separatorInset layoutMargins ) hat keine Auswirkungen.


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

In iOS 8 gibt es eine neue Eigenschaft für alle Objekte, die von UIView erben. Die Lösung, mit der das SeparatorInset in iOS 7.x eingerichtet wird, kann den in UITableView in 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

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; ohne zu prüfen, ob die layoutMargins existieren, layoutMargins die App auf iOS 7.x ab. Der beste Weg wäre also zu überprüfen, ob das layoutMargins zuerst vor setLayoutMargins:UIEdgeInsetsZero .


In Swift ist es etwas ärgerlicher, da es sich bei layoutMargins um eine Eigenschaft handelt, also müssen Getter und Setter überschrieben werden.

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

Dies wird layoutMargins effektiv layoutMargins machen, was in meinem Fall in Ordnung ist.


In einer kompakteren Weise als die am meisten gewählte 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];
    }

}


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
    }

Nachdem ich die Antworten in der 3. Etage gesehen hatte, versuchte ich herauszufinden, wie die Beziehung zwischen TableView und TableViewCell aussehen sollte, und testete sie. Hier sind meine Schlussfolgerungen:

  1. Wir können davon ausgehen, dass das Trennzeichen der Zelle auf Null gesetzt werden muss, um das Trennzeichen in zwei Schritten zu verschieben: Im ersten Schritt wird das Trennzeichen der Zelle auf null gesetzt. Der zweite Schritt besteht darin, das marginlayout der Zelle auf Null zu setzen.

  2. Legen Sie fest, dass das Separatorinset und das marginlayout des TableView das Separatorinset der Zelle beeinflussen können. Bei dem Test finde ich jedoch, dass das Trennzeichen des TableViews nutzlos erscheint, TableViews Marginlayout kann das Marginlayout der Zelle beeinflussen .

  3. Setzen Sie Cell's PreservesSuperviewLayoutMargins = false, um den Marginlayout- Effekt von TableView auf Zellen zu unterbinden .

  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
    }
    

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
}

Sie können UIAppearance einmal beim Start der Anwendung (vor dem Laden der Benutzeroberfläche) verwenden, um es 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 behalten Sie den Code Ihres UIViewControllers sauber und können ihn jederzeit überschreiben.


Was cdstamper anstelle der Tabellenansicht vorgeschlagen hat, funktioniert das Hinzufügen von Zeilen in 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];
        }
}

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

Dies funktionierte perfekt für mich in iOS 8 und iOS 9.

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

Hinzufügen dieses Schnipsel, 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
}




ios8