Hinzufügen eines Abstands zwischen UITableViewCell


181

Gibt es eine Möglichkeit, den Abstand zwischen hinzuzufügen UITableViewCell?

Ich habe eine Tabelle erstellt und jede Zelle enthält nur ein Bild. Das Bild wird der Zelle wie folgt zugewiesen:

cell.imageView.image = [myImages objectAtIndex:indexPath.row];

Dadurch wird das Bild jedoch vergrößert und passt in die gesamte Zelle, und es gibt keinen Abstand zwischen den Bildern.

Oder sagen wir auf diese Weise, die Bildhöhe beträgt zB 50, und ich möchte 20 Abstände zwischen den Bildern hinzufügen. Gibt es eine Möglichkeit, dies zu erreichen?


1
Für Swift 2.2 siehe meine Antwort hier: stackoverflow.com/a/37673417/2696626
ibrahimyilmaz

Antworten:


159

Schnelle Version

Aktualisiert für Swift 3

Diese Antwort ist für zukünftige Zuschauer etwas allgemeiner als die ursprüngliche Frage. Es ist ein ergänzendes Beispiel zum grundlegenden UITableView-Beispiel für Swift .

Geben Sie hier die Bildbeschreibung ein

Überblick

Die Grundidee besteht darin, für jedes Array-Element einen neuen Abschnitt (anstelle einer neuen Zeile) zu erstellen. Die Abschnitte können dann unter Verwendung der Abschnittskopfhöhe beabstandet werden.

Wie es geht

  • Richten Sie Ihr Projekt wie im UITableView-Beispiel für Swift beschrieben ein . (Fügen Sie also a hinzu UITableViewund schließen Sie die tableViewSteckdose an den View Controller an.)

  • Ändern Sie im Interface Builder die Hintergrundfarbe der Hauptansicht in hellblau und die UITableViewHintergrundfarbe in klar.

  • Ersetzen Sie den Code ViewController.swift durch den folgenden.

ViewController.swift

import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    // These strings will be the data for the table view cells
    let animals: [String] = ["Horse", "Cow", "Camel", "Sheep", "Goat"]
    
    let cellReuseIdentifier = "cell"
    let cellSpacingHeight: CGFloat = 5
    
    @IBOutlet var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // These tasks can also be done in IB if you prefer.
        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
        tableView.delegate = self
        tableView.dataSource = self
    }
    
    // MARK: - Table View delegate methods
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return self.animals.count
    }
    
    // There is just one row in every section
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    
    // Set the spacing between sections
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return cellSpacingHeight
    }
    
    // Make the background color show through
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let headerView = UIView()
        headerView.backgroundColor = UIColor.clear
        return headerView
    }
    
    // create a cell for each table view row
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as UITableViewCell!
        
        // note that indexPath.section is used rather than indexPath.row
        cell.textLabel?.text = self.animals[indexPath.section]
        
        // add border and color
        cell.backgroundColor = UIColor.white
        cell.layer.borderColor = UIColor.black.cgColor
        cell.layer.borderWidth = 1
        cell.layer.cornerRadius = 8
        cell.clipsToBounds = true
        
        return cell
    }
    
    // method to run when table view cell is tapped
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // note that indexPath.section is used rather than indexPath.row
        print("You tapped cell number \(indexPath.section).")
    }
}

Beachten Sie, dass indexPath.sectioneher verwendet wird alsindexPath.row wird, um die richtigen Werte für die Array-Elemente und Tap-Positionen zu erhalten.

Wie haben Sie die zusätzliche Polsterung / den zusätzlichen Platz rechts und links erhalten?

Ich habe es genauso verstanden, wie Sie jeder Ansicht einen Abstand hinzufügen. Ich habe Einschränkungen für das automatische Layout verwendet. Verwenden Sie einfach das Stiftwerkzeug im Interface Builder, um Abstände für die führenden und nachfolgenden Einschränkungen hinzuzufügen.


Hallo, ich habe mich gefragt, ob dies möglich ist, ohne alle Ihre Zeilen in Abschnitte zu konvertieren. Ich habe Rahmen für jede tableViewCell, daher hilft es nicht, die Höhe zu erhöhen. Ich habe viele Anpassungen an meiner Zelle und möchte sie nicht in Abschnitte konvertieren. Vielen Dank!
Ujjwal-Nadhani

3
@ user2901306, ich zögerte zunächst auch, diese Methode zu verwenden, da ich das Gefühl hatte, nur Zeilen verwenden und einen Rand oder etwas vergrößern zu können. Ich habe jedoch keinen Weg gefunden, dies zu tun, und diese Methode hat recht gut funktioniert. Sie müssen die Anpassungen in Ihrer Zelle nicht ändern. Sie müssen grundsätzlich nur numberOfSectionsInTableViewund return 1für die Anzahl der Zeilen hinzufügen . Verwenden Sie dann indexPath.section, um den aktuellen Zellenindex abzurufen. Versuchen Sie es einmal. Ich denke, Sie werden feststellen, dass Sie nicht sehr viele Änderungen an Ihrem aktuellen Setup vornehmen müssen. Dies ist definitiv einfacher als Unterklassen.
Suragch

Die Verwendung von cell.layer.xxx in cellForRow kann zu einem Leistungseinbruch führen. Besser diese Werte in der XIB
Abhishek Bedi

@AbhishekBedi, ich habe immer festgestellt, dass layerManipulationen ziemlich schnell sind. Sagen Sie das, weil Sie einen Leistungseinbruch bemerkt haben oder als allgemeine bewährte Methode? Selbst wenn Sie sie in einer XIB festlegen, müssen sie beim Erstellen der Zelle festgelegt werden.
Suragch

1
@FateNuller, ich bin nicht anderer Meinung als du. Husams Antwort sieht ziemlich gut aus.
Suragch

149

Meine einfache Lösung mit Swift :

// Inside UITableViewCell subclass

override func layoutSubviews() {
    super.layoutSubviews()

    contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
}

Ergebnis Geben Sie hier die Bildbeschreibung ein


11
Schöne Lösung. Falls jemand Probleme hat, musste ich super.layoutSubviews()zuerst anrufen, um sicherzustellen, dass die gesamte Ansicht richtig angelegt war, bevor der Rahmen festgelegt wurde.
Ruttopia

@Husam Deine Lösung hat bei mir funktioniert. Aber ich habe ein Problem bei der ausgewählten Zelle. Ich habe den Rand für contentView festgelegt und jedes Mal, wenn ich eine Zelle ausgewählt habe, wird der Rand kleiner. Wie kann ich es reparieren?
Bad_Developer

@SonHoang Möglicherweise müssen Sie didSetfür selectedVariable überschreiben und layoutSubviews()innen aufrufen !
Husam

1
Hey, Husam. Danke für die tolle Lösung. Sagen Sie mir nicht, wie ich die Farbe des hinzugefügten Inhalts zwischen den Zellen ändern soll?
A.Kant

1
Dies ist eine viel bessere Lösung als die akzeptierte Antwort. Die akzeptierte Antwort hat fast 100 Codezeilen und dies ist nur eine. Unglaublich.
YungGun

135

Die Art und Weise, wie ich einen Abstand zwischen Zellen hinzufüge, besteht darin, numberOfSections = "Your array count" zu machen und dafür zu sorgen, dass jeder Abschnitt nur eine Zeile enthält. Und dann definieren Sie headerView und seine Höhe.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return yourArry.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return cellSpacingHeight;
}

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UIView *v = [UIView new];
    [v setBackgroundColor:[UIColor clearColor]];
    return v;
}

22
Das funktioniert super. Ich musste den cellForRowAtIndexPath ein wenig ändern, nicht das normale Array [indexPath.row], sondern das Array [indexPath.section]. Andernfalls wird das erste Element des Arrays in allen Abschnitten angezeigt.
Tom Spee

@TomSpee - Wie haben Sie dieses Problem in cellForRowAtIndexPath gelöst?

5
@TKutal - Genau wie der normale Code in cellForRowAtIndexPath, aber ändern Sie die indexPath.row in indexPath.section
Tom Spee

Obwohl dies das erreicht, was der Fragesteller wünscht, glaube ich nicht, dass Apple diesen Ansatz empfehlen würde. Korrigieren Sie mich, wenn ich falsch liege, aber ich glaube, dass "Abschnitte" dazu gedacht sind, "Abschnitte" von Daten, die Sie in Ihrer Tabelle darstellen, logisch zu trennen. Sie sollten keine "Abschnitte" verwenden, um die Leerzeichen zwischen den einzelnen Datenzellen zu formatieren, die ansonsten alle in einem einzigen Abschnitt angezeigt werden sollten. Ich denke, der bessere Ansatz, wenn auch schwieriger, wäre es, UITableViewCell in eine Unterklasse zu unterteilen und das Trennzeichen für die Tabellenansicht zu simulieren, indem eine Ansicht am unteren Rand der Zelle hinzugefügt wird.
FateNuller

2
Dann sollte sich Apple lieber nicht beschweren, sondern eine bequeme Methode zum Variieren des Abstands zwischen Zeilen erstellen.
Arnie Schwarzvogel

44

Ich musste das gleiche Konzept machen, dass UITableCells einen "Raum" zwischen sich haben. Da Sie nicht buchstäblich Leerzeichen zwischen Zellen hinzufügen können, können Sie diese fälschen, indem Sie die Zellenhöhe von UITableView ändern und dann der contentView Ihrer Zelle eine UIView hinzufügen. Hier ist ein Screenshot eines Prototyps, den ich in einem anderen Testprojekt gemacht habe, als ich dies simuliert habe:

Abstand zwischen UITableViewCells

Hier ist ein Code (Hinweis: Zu Demonstrationszwecken gibt es viele fest codierte Werte)

Zuerst musste ich das einstellen heightForRowAtIndexPath, um unterschiedliche Höhen in der UITableViewCell zuzulassen.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{

    NSString *text = [self.newsArray  objectAtIndex:[indexPath row]];
    if ([text isEqual:@"December 2012"])
    {
        return 25.0;
    }

    return 80.0;
}

Als nächstes möchte ich das Erscheinungsbild der UITableViewCells ändern, damit ich dies in der willDisplayCell:(NewsUITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPathMethode mache .

- (void)tableView:(UITableView *)tableView willDisplayCell:(NewsUITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (cell.IsMonth)
    {
        UIImageView *av = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 20, 20)];
        av.backgroundColor = [UIColor clearColor];
        av.opaque = NO;
        av.image = [UIImage imageNamed:@"month-bar-bkgd.png"];
        UILabel *monthTextLabel = [[UILabel alloc] init];
        CGFloat font = 11.0f;
        monthTextLabel.font = [BVFont HelveticaNeue:&font];

        cell.backgroundView = av;
        cell.textLabel.font = [BVFont HelveticaNeue:&font];
        cell.textLabel.textColor = [BVFont WebGrey];
    }


    if (indexPath.row != 0)
    {
        cell.contentView.backgroundColor = [UIColor clearColor];
        UIView *whiteRoundedCornerView = [[UIView alloc] initWithFrame:CGRectMake(10,10,300,70)];
        whiteRoundedCornerView.backgroundColor = [UIColor whiteColor];
        whiteRoundedCornerView.layer.masksToBounds = NO;
        whiteRoundedCornerView.layer.cornerRadius = 3.0;
        whiteRoundedCornerView.layer.shadowOffset = CGSizeMake(-1, 1);
        whiteRoundedCornerView.layer.shadowOpacity = 0.5;
        [cell.contentView addSubview:whiteRoundedCornerView];
        [cell.contentView sendSubviewToBack:whiteRoundedCornerView];

    }
}

Beachten Sie, dass ich meine whiteRoundedCornerView-Höhe 70.0 festgelegt habe und dies den simulierten Speicherplatz verursacht, da die Höhe der Zelle tatsächlich 80.0 beträgt, meine contentView jedoch 70.0, wodurch sie angezeigt wird.

Es gibt vielleicht andere Möglichkeiten, dies noch besser zu erreichen, aber so habe ich es gefunden. Ich hoffe es kann jemand anderem helfen.


Nur zu Ihrer Information, für eine sehr große Anzahl von Zellen möchten Sie die Inhaltsansicht innerhalb der Zellenunterklasse anstelle von willDisplayCell festlegen. Die Leistung beginnt einen großen Erfolg zu haben, je mehr Zellen Sie der Warteschlange hinzufügen
BBH1023

@ BBH1023 Die Schattenebene vervielfacht sich jedes Mal, wenn die Ansicht beim Hin- und Herbewegen angezeigt wird, um sie schnell anzuzeigen. Wie würden Sie vorschlagen, das aufzuheben, wenn es bereits einmal angewendet wurde
soulshined

Um mehr Schatten hinzuzufügen, gehen Sie folgendermaßen vor: NSInteger tag = 120; if (indexPath.row! = 0) {if (cell.tag! = 120) {cell.contentView.backgroundColor = [UIColor clearColor]; ... [cell.contentView sendSubviewToBack: whiteRoundedCornerView]; cell.tag = tag; }}
user3001228

24

Sie müssen den Rahmen für Ihr Bild festlegen. Ungetesteter Code ist

cell.imageView.frame = CGRectOffset(cell.frame, 10, 10);

2
Gerade mit backgroundView getestet und dies ist die einfachste funktionierende Lösung
Sam

2
layoutSubviewsUITableViewCell
Stellen

30
@ NicoHämäläinen Nun, ich habe in den letzten drei Jahren über 20 Apps entwickelt und IMMER Unterklassen erstellt UITableViewCell, um das gewünschte Ergebnis zu erzielen :) ... Unterklassen UITableViewCellsind sehr verbreitet.
Mazyod

1
@ NicoHämäläinen an Unterklassen ist nichts auszusetzen UITableViewCell. Wenn Sie benutzerdefinierte erstellen UITableViewCells, sollten Sie Unterklassen sein UITableViewCell.
Popeye

1
@ NicoHämäläinen du solltest dann deinen Kommentar aktualisieren. Menschen neigen dazu, Informationen zu greifen und nicht weiter zu lesen. Da diese Seite eine großartige Ressource ist und Entwickler dazu neigen, Fakten zu vertrauen, die sie hier sehen, könnte dies sie dazu verleiten, schreckliche Dinge zu denken. Nur meine zwei Münzen. Vielleicht habe ich Hysterie
chrs

11

Ich war im selben Boot. Zuerst habe ich versucht, zu Abschnitten zu wechseln, aber in meinem Fall waren es eher Kopfschmerzen als ursprünglich gedacht, also habe ich nach einer Alternative gesucht. Um weiterhin Zeilen zu verwenden (und nicht mit dem Zugriff auf Ihre Modelldaten herumzuspielen), hat Folgendes für mich funktioniert, indem ich nur eine Maske verwendet habe :

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
    let verticalPadding: CGFloat = 8

    let maskLayer = CALayer()
    maskLayer.cornerRadius = 10    //if you want round edges
    maskLayer.backgroundColor = UIColor.black.cgColor
    maskLayer.frame = CGRect(x: cell.bounds.origin.x, y: cell.bounds.origin.y, width: cell.bounds.width, height: cell.bounds.height).insetBy(dx: 0, dy: verticalPadding/2)
    cell.layer.mask = maskLayer
}

Alles, was Sie noch tun müssen, ist , die Höhe der Zelle um den gleichen Wert wie gewünscht zu vergrößernverticalPadding und dann Ihr inneres Layout so zu ändern, dass alle Ansichten, die einen Abstand zu den Rändern der Zelle hatten, denselben Abstand um erhöhen verticalPadding/2. verticalPadding/2Kleiner Nachteil: Sie erhalten sowohl oben als auch unten in der Tabellenansicht eine Auffüllung, die Sie jedoch schnell beheben können, indem Sie tableView.contentInset.bottom = -verticalPadding/2und einstellen tableView.contentInset.top = -verticalPadding/2. Hoffe das hilft jemandem!


1
Funktioniert auch in Swift 5.
LondonGuy

1
Beste Antwort!! Danke dir. Wenn Sie eine benutzerdefinierte Zelle verwenden, funktioniert dies in der "override func awakeFromNib ()"
tree_are_great

10

Ich denke, die einfachste Lösung, wenn Sie nur ein wenig Platz suchen und wahrscheinlich am billigsten sind, besteht darin, einfach die Farbe des Zellenrahmens auf die Hintergrundfarbe Ihrer Tabelle einzustellen und dann die Rahmenbreite festzulegen, um das gewünschte Ergebnis zu erzielen!

    cell.layer.borderColor = blueColor.CGColor
    cell.layer.borderWidth = 3

Keine gute Idee für transparenten Hintergrund. Andernfalls kann es funktionieren.
Ergunkocak

Das ist wahr. Nicht für alle Fälle eine Lösung, aber für einige wird es funktionieren! @ergunkocak
Craig

8

Wenn Sie noch keine Abschnittsüberschriften (oder -fußzeilen) verwenden, können Sie damit Tabellenzellen einen beliebigen Abstand hinzufügen. Anstatt einen Abschnitt mit n Zeilen zu haben, erstellen Sie eine Tabelle mit n Abschnitten mit jeweils einer Zeile.

Implementieren Sie die tableView:heightForHeaderInSection:Methode zur Steuerung des Abstands.

Möglicherweise möchten Sie auch implementieren, um tableView:viewForHeaderInSection:zu steuern, wie der Abstand aussieht.


8

Ich habe es so in Swift 4 gelöst.

Ich erstelle eine Erweiterung von UITableViewCell und füge diesen Code hinzu:

override open var frame: CGRect {
    get {
        return super.frame
    }
    set (newFrame) {
        var frame =  newFrame
        frame.origin.y += 10
        frame.origin.x += 10
        frame.size.height -= 15
        frame.size.width -= 2 * 10
        super.frame = frame
    }
}

override open func awakeFromNib() {
    super.awakeFromNib()
    layer.cornerRadius = 15
    layer.masksToBounds = false
}

Ich hoffe es hilft dir.


Text in der Zelle wird beschnitten.
Mehdico

Die CGRect-Überschreibung funktioniert, und ich habe keine awakeFromNib hinzugefügt.
Eric Tan

5

Beispiel in Swift 3 ..

Geben Sie hier die Bildbeschreibung ein

  1. Falten Sie eine Einzelansicht-Anwendung
  2. Tabellenansicht im View Controller hinzufügen
  3. Fügen Sie eine benutzerdefinierte Zelle für die Tablview-Zelle hinzu
  4. Der Controller-Code ist wie folgt

       class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
    
       @IBOutlet weak var tableView: UITableView!
    
    
        var arraytable = [[String:Any]]()
         override func viewDidLoad() {
         super.viewDidLoad()
    
         arraytable = [
         ["title":"About Us","detail":"RA-InfoTech Ltd -A Joint Venture IT Company formed by Bank Asia Ltd"],
         ["title":"Contact","detail":"Bengal Center (4th & 6th Floor), 28, Topkhana Road, Dhaka - 1000, Bangladesh"]
    ]
    
    
    
    
    
    
       tableView.delegate = self
       tableView.dataSource = self
    
       //For Auto Resize Table View Cell;
      tableView.estimatedRowHeight = 44
       tableView.rowHeight = UITableViewAutomaticDimension
    
       //Detault Background clear
       tableView.backgroundColor = UIColor.clear
    }

    func numberOfSections (in tableView: UITableView) -> Int {return arraytable.count}

       func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     return 1
     }
    
    // Set the spacing between sections
     func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 10
    }
    
    // Make the background color show through
      func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerView = UIView()
    headerView.backgroundColor = UIColor.clear
    
    return headerView
    }
    
         func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
         let cell = tableView.dequeueReusableCell(withIdentifier: "cell")! as! CustomCell
    
         cell.tv_title.text = arraytable[indexPath.section]["title"] as! String?
        cell.tv_details.text = arraytable[indexPath.section]["detail"] as! String?
    
       //label height dynamically increase
       cell.tv_details.numberOfLines = 0
    
    
    
    
       //For bottom border to tv_title;
       let frame =  cell.tv_title.frame
        let bottomLayer = CALayer()
       bottomLayer.frame = CGRect(x: 0, y: frame.height - 1, width: frame.width, height: 1)
        bottomLayer.backgroundColor = UIColor.black.cgColor
       cell.tv_title.layer.addSublayer(bottomLayer)
    
      //borderColor,borderWidth, cornerRadius
      cell.backgroundColor = UIColor.lightGray
      cell.layer.borderColor = UIColor.red.cgColor
      cell.layer.borderWidth = 1
      cell.layer.cornerRadius = 8
      cell.clipsToBounds = true
    
      return cell
      }
    
       }
  5. Laden Sie die vollständige Quelle auf Github herunter: Link

    https://github.com/enamul95/CustomSectionTable


Es wurde eine weitere Antwort dupliziert, die @Suragch bereits für eine schnelle Version beantwortet hat. Bitte vermeiden Sie Duplikate
Amr Angry

1
Das ist keine gute Lösung. Wenn Sie einen Header-Bereich mit einem Titel benötigen, funktioniert dies nicht
Kuzdu

4

Drei Ansätze, die ich mir vorstellen kann:

  1. Erstellen Sie eine benutzerdefinierte Tabellenzelle, in der die Ansicht der gesamten Zelle in der von Ihnen gewünschten Weise dargestellt wird

  2. Anstatt das Bild zur Bildansicht hinzuzufügen, löschen Sie die Unteransichten der Bildansicht, erstellen Sie eine benutzerdefinierte Ansicht, die eine UIImageView für das Bild und eine andere Ansicht hinzufügt, möglicherweise eine einfache UIView, die den gewünschten Abstand bereitstellt, und fügen Sie sie als Unteransicht von hinzu die Bildansicht.

  3. Ich möchte vorschlagen, dass Sie UIImageView direkt bearbeiten, um eine feste Größe / Auffüllung festzulegen, aber ich bin nicht in der Nähe von Xcode, sodass ich nicht bestätigen kann, ob / wie dies funktionieren würde.

Ist das sinnvoll?


4

Ja, Sie können den Abstand (Auffüllen) zwischen zwei Zellen vergrößern oder verkleinern, indem Sie eine Basisansicht für die Inhaltsansicht in der Zelle erstellen. Stellen Sie eine klare Farbe für den Hintergrund der Inhaltsansicht ein und passen Sie die Höhe der Basisansicht an, um Platz zwischen den Zellen zu schaffen.


4

Basierend auf Husams Antwort: Wenn Sie die Zellebene anstelle der Inhaltsansicht verwenden, können Sie bei Bedarf einen Rahmen um die gesamte Zelle und das Zubehör hinzufügen. Diese Methode erfordert eine sorgfältige Anpassung der unteren Einschränkungen der Zelle sowie der Einfügungen, da sonst die Ansicht nicht richtig ist.

@implementation TableViewCell

- (void)awakeFromNib { 
    ... 
}

- (void) layoutSubviews {
    [super layoutSubviews];

    CGRect newFrame = UIEdgeInsetsInsetRect(self.layer.frame, UIEdgeInsetsMake(4, 0, 4, 0));
    self.layer.frame = newFrame;
}

@end

3

Ändern Sie die Anzahl der Zeilen im Abschnitt auf 1. Sie haben die Anzahl der Abschnitte anstelle der Anzahl der Zeilen geändert

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        1
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

Hier setzen Sie den Abstand zwischen den Zeilen

 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 50
    }

2

Ich denke, das ist die sauberste Lösung:

class MyTableViewCell: UITableViewCell {
    override func awakeFromNib() {
        super.awakeFromNib()
        layoutMargins = UIEdgeInsetsMake(8, 0, 8, 0)
    }
}

1
Nach layoutMarginsdieser Anwendung konnte ich keine visuelle Veränderung feststellen . Vielleicht, weil ich Autolayout verwende.
Cœur

Die Ränder würden eine explizite Höhe für die Zelle nicht "brechen", daher benötigen Sie eine automatische Höhe für die Zellen, damit dies funktioniert
Aviel Gross,

1
Ich habe automatische Höhe.
Cœur

2

Dieser Artikel hat geholfen, es ist ziemlich genau das, was die anderen Antworten sagten, aber zusammengefasst und prägnant

https://medium.com/@andersongusmao/left-and-right-margins-on-uitableviewcell-595f0ba5f5e6

Darin wendet er sie nur auf die linke und rechte Seite an, aber der UIEdgeInsetsMakeInit erlaubt das Hinzufügen von Polstern zu allen vier Punkten.

func UIEdgeInsetsMake (_ oben: CGFloat, _ links: CGFloat, _ unten: CGFloat, _ rechts: CGFloat) -> UIEdgeInsets

Beschreibung
Erstellt einen Kanteneinsatz für eine Schaltfläche oder Ansicht. Ein Einschub ist ein Rand um ein Rechteck. Positive Werte repräsentieren Ränder, die näher an der Mitte des Rechtecks ​​liegen, während negative Werte Ränder darstellen, die weiter von der Mitte entfernt sind.

Parameter
oben: Der Einschub oben auf einem Objekt.
links: Der Einschub links von einem Objekt
unten: Der Einschub unten von einem Objekt.
rechts: Der Einschub rechts von einem Objekt.

Rückgabe
Ein Einschub für eine Schaltfläche oder Ansicht

Beachten Sie, dass UIEdgeInsets auch verwendet werden können, um dasselbe zu erreichen.

Xcode 9.3 / Swift 4


Diese Antwort besagt fälschlicherweise, dass der Code Swift 4-kompatibel ist, UIEdgeInsetsMake jedoch veraltet ist. Stattdessen sollte UIEdgeInsets verwendet werden.
José

developer.apple.com/documentation/uikit/… genau wo steht, dass es veraltet ist? Ich benutze dies in meinen Projekten und arbeite mit dem neuesten Xcode, daher Swift 9.3 @ José
Mauricio Chirino

Du hast recht, sorry, mein schlechtes. UIEdgeInsets wird bevorzugt, aber das bedeutet nicht, dass das andere veraltet ist. SwiftLint wird sich jedoch über den Legacy-Konstruktor beschweren, wenn UIEdgeInsetsMake verwendet wird.
José

1
OK habe es. Bitte entfernen Sie die Ablehnung, wenn Sie derjenige waren, der bitte gecastet hat. Ich habe nie gesagt, dass meine Antwort die einzig mögliche ist.
Mauricio Chirino

Es heißt, dass ich meine Stimme nur ändern kann, wenn Sie Ihre Antwort ändern. Können Sie vielleicht den Wortlaut ein wenig ändern?
José

2

Die Verwendung einer Reihe verschiedener Abschnitte ist nicht erforderlich. Die anderen Antworten verwenden Frame-Insets und CGRect und Layer und ... BLAH. Nicht gut; Verwenden Sie das automatische Layout und eine benutzerdefinierte UITableViewCell. Erstellen Sie in dieser UITableViewCell anstelle einer Unteransicht Ihres Inhalts in der Inhaltsansicht eine neue Containeransicht (eine UIView), zeigen Sie die Containeransicht in der Inhaltsansicht an und zeigen Sie dann alle Ihre Ansichten in der Containeransicht an.

Um den Abstand jetzt festzulegen, bearbeiten Sie einfach die Layoutränder der Containeransicht wie folgt:

class CustomTableViewCell: UITableViewCell {
    let containerView = UIView()
    let imageView = UIImageView()

    required init?(coder aDecoder: NSCoder) {super.init(coder: aDecoder)}

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        containerView.translatesAutoResizingMaskIntoConstraints = false
        imageView.translatesAutoResizingMaskIntoConstraints = false
        contentView.addSubview(containerView)
        containerView.addSubview(imageView)

        contentView.layoutMargins = UIEdgeInsets(top: 15, left: 3, bottom: 15, right: 3)
        containerView.layoutMargins = UIEdgeInsets(top: 15, left: 17, bottom: 15, right: 17) // It isn't really necessary unless you've got an extremely complex table view cell. Otherwise, you could just write e.g. containerView.topAnchor

        let cg = contentView.layoutMarginsGuide
        let lg = containerView.layoutMarginsGuide
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: cg.topAnchor),
            containerView.leadingAnchor.constraint(equalTo: cg.leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: cg.trailingAnchor),
            containerView.bottomAnchor.constraint(equalTo: cg.bottomAnchor),
            imageView.topAnchor.constraint(equalTo: lg.topAnchor),
            imageView.leadingAnchor.constraint(equalTo: lg.leadingAnchor),
            imageView.trailingAnchor.constraint(equalTo: lg.trailingAnchor),
            imageView.bottomAnchor.constraint(equalTo: lg.bottomAnchor)
        ])
    }
}


1

Meine Situation war, dass ich benutzerdefinierte UIView verwendet habe, um ForFeaHeader im Abschnitt auch heightForHeader im Abschnitt anzuzeigen. Konstante Höhe zurückgeben, z. B. 40, Problem war, wenn keine Daten vorhanden sind, wurden alle Header-Ansichten berührt. Also wollte ich zwischen den Abschnitten Platz machen, wenn keine Daten vorhanden sind. Also habe ich das Problem behoben, indem ich einfach die Ebene "Tabellenansicht" in "Gruppe" geändert habe. Und es hat bei mir funktioniert.


1

Schauen Sie sich meine Lösung auf GitHub mit Unterklassen UITableViewund Verwendung der Laufzeitfunktionen von Objective-C an.
Grundsätzlich wird die private Datenstruktur von Apple verwendet UITableViewRowData, für die ich einen privaten Laufzeitheader durchsucht habe UITableView:

https://github.com/JaviSoto/iOS10-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UITableView.h ,

und hier ist die gewünschte private Klasse, die alles enthält, was Sie benötigen, um die Abstände Ihrer Zellen so zu gestalten, wie Sie möchten, ohne sie in den Klassen der Zellen festzulegen:

https://github.com/JaviSoto/iOS10-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UITableViewRowData.h


1

Ich hatte Probleme, dies neben Hintergrundfarben und Zubehöransichten in der Zelle zum Laufen zu bringen. Am Ende musste ich:

1) Legen Sie die Eigenschaft für die Hintergrundansicht der Zellen mit einem UIView-Satz mit einer Hintergrundfarbe fest.

let view = UIView()
view.backgroundColor = UIColor.white
self.backgroundView = view

2) Positionieren Sie diese Ansicht in layoutSubviews neu, um die Idee des Abstands hinzuzufügen

override func layoutSubviews() {
    super.layoutSubviews()
    backgroundView?.frame = backgroundView?.frame.inset(by: UIEdgeInsets(top: 2, left: 0, bottom: 0, right: 0)) ?? CGRect.zero
}

1

Die Verwendung der Überschriften als Abstand würde gut funktionieren, wenn Sie keine Überschriften verwenden möchten. Ansonsten wahrscheinlich nicht die beste Idee. Ich denke, ich erstelle eine benutzerdefinierte Zellenansicht.

Beispiele:

Erstellen Sie in der benutzerdefinierten Zelle eine Hintergrundansicht mit Einschränkungen, damit nicht die gesamte Zelle ausgefüllt wird, und füllen Sie sie auf.

Machen Sie dann den Hintergrund der Tabellenansicht unsichtbar und entfernen Sie die Trennzeichen:

// Make the background invisible
tableView.backgroundView = UIView()
tableView.backgroundColor = .clear

// Remove the separators
tableview.separatorStyle = .none

1

Wenn Sie den Abschnitt und die Zeilennummer Ihrer Tabellenansicht nicht ändern möchten (wie ich), gehen Sie wie folgt vor:

1) Fügen Sie eine ImageView am unteren Rand Ihrer Tabellenzellenansicht hinzu.

2) Stellen Sie die gleiche Farbe wie die Hintergrundfarbe der Tabellenansicht ein.

Ich habe dies in meiner Anwendung getan und es funktioniert perfekt. Prost! : D.


0

Geben Sie hier die Bildbeschreibung einSWift-5, Abstand zwischen UITableViewCell

    1. use sections instead of rows
    2. each section should return one row
    3. assign your cell data like this e.g [indexPath.section], instead of row
    4. use UITableView Method "heightForHeader" and return your desired spacing
    5. Do rest things as you were doing it

    Thanks!

0

Sie können die Einschränkung einfach wie folgt in Code verwenden:

class viewCell : UITableViewCell 
{

@IBOutlet weak var container: UIView!



func setShape() {
    self.container.backgroundColor = .blue
    self.container.layer.cornerRadius = 20
    container.translatesAutoresizingMaskIntoConstraints = false
    self.container.widthAnchor.constraint(equalTo:contentView.widthAnchor , constant: -40).isActive = true
           self.container.heightAnchor.constraint(equalTo: contentView.heightAnchor,constant: -20).isActive = true
           self.container.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
           self.container.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true

    }
}

Es ist wichtig, eine Unteransicht (Container) hinzuzufügen und andere Elemente darin zu platzieren.


-1

Swift 5.0 Lösung

Innerhalb der UITableViewCell-Unterklasse

override func layoutSubviews() {
    super.layoutSubviews()
    let padding = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
    bounds = UIEdgeInsetsInsetRect(bounds, padding)
}

-2

Fügen Sie der Zelle eine innere Ansicht hinzu, und fügen Sie dann Ihre eigenen Ansichten hinzu.


-4

Verwenden Sie UITableViewDelegate heightForRowAtIndexPathund geben Sie die Zeilenhöhe zurück.

 (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
 return 100.0f ;
}

Die Frage ist, wie man den Abstand zwischen den Zellen und nicht die Höhe der Zelle
hinzufügt
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.