Come aggiungere la spaziatura tra UITableViewCell


182

C'è un modo per aggiungere spazio tra UITableViewCell?

Ho creato una tabella e ogni cella contiene solo un'immagine. L'immagine è assegnata alla cella in questo modo:

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

ma ciò rende l'immagine ingrandita e si adatta all'intera cella e non vi sono spazi tra le immagini.

O diciamo in questo modo, l'altezza dell'immagine è ad esempio 50 e voglio aggiungere 20 spazi tra le immagini. C'è un modo per raggiungere questo obiettivo?


1
Per Swift 2.2 vedere la mia risposta qui: stackoverflow.com/a/37673417/2696626
ibrahimyilmaz

Risposte:


160

Versione rapida

Aggiornato per Swift 3

Questa risposta è in qualche modo più generale della domanda originale per il bene dei futuri spettatori. È un esempio supplementare all'esempio base di UITableView per Swift .

inserisci qui la descrizione dell'immagine

Panoramica

L'idea di base è creare una nuova sezione (anziché una nuova riga) per ciascun elemento dell'array. Le sezioni possono quindi essere distanziate utilizzando l'altezza dell'intestazione della sezione.

Come farlo

  • Imposta il tuo progetto come descritto nell'esempio di UITableView per Swift . (Cioè, aggiungere a UITableViewe collegare la tableViewpresa al View Controller).

  • In Interface Builder, cambia il colore di sfondo della vista principale in azzurro e il UITableViewcolore di sfondo in chiaro.

  • Sostituire il codice ViewController.swift con il seguente.

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

Si noti che indexPath.sectionviene utilizzato anziché indexPath.rowper ottenere i valori corretti per gli elementi dell'array e le posizioni dei tocchi.

Come hai ottenuto l'ulteriore imbottitura / spazio a destra e a sinistra?

Ho capito allo stesso modo in cui aggiungi spazio a qualsiasi vista. Ho usato i vincoli di layout automatico. Basta usare lo strumento Pin in Interface Builder per aggiungere la spaziatura per i vincoli iniziali e finali.


Ciao, mi chiedevo se questo fosse possibile senza convertire tutte le tue righe in sezioni. Ho dei bordi su ogni tableViewCell, quindi aumentare l'altezza non aiuta. Ho molte personalizzazioni con la mia cella e non voglio convertirlo in sezioni. Grazie!
Ujjwal-Nadhani,

3
@utente2901306, all'inizio ero titubante nell'utilizzare questo metodo, perché mi sembrava di poter usare le righe e aumentare un margine o qualcosa del genere. Tuttavia, non ho trovato il modo di farlo e questo metodo ha funzionato abbastanza bene. Non è necessario modificare le personalizzazioni sul tuo cellulare. Fondamentalmente devi solo aggiungere numberOfSectionsInTableViewe return 1per il numero di righe. Quindi utilizzare indexPath.sectionper ottenere l'indice di cella corrente. Provalo una volta. Penso che scoprirai che non è necessario apportare molte modifiche alla configurazione corrente. Questo è sicuramente più semplice della sottoclasse.
Suragch,

L'uso di cell.layer.xxx in cellForRow può darti un successo prestazionale. Meglio impostare questi valori nella XIB
Abhishek Bedi

@AbhishekBedi, ho sempre trovato le layermanipolazioni abbastanza veloci. Stai dicendo questo perché hai notato un hit da prestazione o come una buona pratica generale? Anche se li hai impostati in un XIB, devono comunque essere impostati quando viene creata la cella.
Suragch,

1
@FateNuller, non sono in disaccordo con te. La risposta di Husam sembra piuttosto buona.
Suragch,

150

La mia soluzione semplice con Swift :

// Inside UITableViewCell subclass

override func layoutSubviews() {
    super.layoutSubviews()

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

Risultato inserisci qui la descrizione dell'immagine


11
Bella soluzione. Nel caso in cui qualcuno abbia dei problemi, ho dovuto chiamare super.layoutSubviews()prima per assicurarmi che l'intera vista fosse correttamente disposta prima di impostare il suo frame.
Ruttopia,

@Husam La tua soluzione ha funzionato per me. Ma ho un problema con la cella selezionata. Ho impostato il bordo per contentView e ogni volta che ho selezionato la cella il bordo sarà più piccolo. Come posso ripararlo?
Bad_Developer

@SonHoang Potrebbe essere necessario eseguire l'override didSetper selectedvariabile e chiamata layoutSubviews()dentro!
Husam,

1
Ehi, Husam. Grazie per l'ottima soluzione. Non dirmi come cambiare il colore del contenuto aggiunto tra le celle?
A.Kant,

1
Questa è una soluzione molto migliore della risposta accettata. La risposta accettata ha quasi 100 righe di codice e questa è solo una. Incredibile.
YungGun

135

Il modo in cui ottengo l'aggiunta della spaziatura tra le celle è rendere numberOfSections = "Il tuo conteggio di array" e rendere ogni sezione contiene solo una riga. E quindi definire headerView e la sua altezza.

- (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
Funziona benissimo. Ho dovuto cambiare un po 'cellForRowAtIndexPath, non l'array normale [indexPath.row] ma l'array [indexPath.section]. Altrimenti mostrerà il primo elemento dell'array in tutte le sezioni.
Tom Spee,

@TomSpee - Come hai risolto il problema in cellForRowAtIndexPath?

5
@TKutal - Proprio come il normale codice in cellForRowAtIndexPath ma cambia indexPath.row in indexPath.section
Tom Spee

Sebbene ciò soddisfi ciò che desidera chi chiede, non credo che Apple consiglierebbe questo approccio. Correggimi se sbaglio, ma credo che le "sezioni" siano pensate per separare logicamente le "sezioni" di dati che stai rappresentando nella tua tabella. Non dovresti usare "sezioni" per definire gli spazi tra ogni cella di dati che altrimenti dovrebbero essere visualizzati in una singola sezione. Penso che l'approccio migliore, sebbene più difficile, sarebbe quello di sottoclassare UITableViewCell e simulare il separatore della vista tabella aggiungendo una vista nella parte inferiore della cella.
FateNuller,

2
Quindi Apple dovrebbe piuttosto non lamentarsi, ma creare un metodo conveniente per variare lo spazio tra le righe.
Arnie Schwarzvogel,

44

Avevo bisogno di fare lo stesso concetto di avere UITableCells con uno "spazio" tra di loro. Poiché non è possibile aggiungere letteralmente spazio tra le celle, è possibile falsificarlo modificando l'altezza della cella di UITableView e quindi aggiungendo una UIView al contentView della cella. Ecco una schermata di un prototipo che ho fatto in un altro progetto di test mentre simulavo questo:

Spaziatura tra UITableViewCells

Ecco un po 'di codice (Nota: ci sono molti valori codificati a scopo dimostrativo)

Innanzitutto, dovevo impostare l' heightForRowAtIndexPathopzione per consentire altezze diverse su UITableViewCell.

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

Successivamente, voglio manipolare l'aspetto di UITableViewCells, quindi lo faccio nel willDisplayCell:(NewsUITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPathmetodo.

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

    }
}

Nota che ho creato la mia altezza di WhiteRoundedCornerView 70.0 e questo è ciò che provoca lo spazio simulato perché l'altezza della cella è in realtà 80.0 ma il mio contentView è 70.0 che gli dà l'aspetto.

Potrebbero esserci altri modi per farlo ancora meglio, ma è proprio come ho scoperto come farlo. Spero che possa aiutare qualcun altro.


Solo un FYI, per un numero molto elevato di celle, si desidera impostare la visualizzazione del contenuto all'interno della sottoclasse di celle anziché willDisplayCell. La performance inizia a
subire

@ BBH1023 Il livello ombra si moltiplica ogni volta che appare la vista durante la navigazione avanti e indietro per visualizzare rapidamente. Come suggeriresti di cancellarlo se è già stato applicato una volta
soulshined

per privare per aggiungere più ombra fai questo: tag NSInteger = 120; if (indexPath.row! = 0) {if (cell.tag! = 120) {cell.contentView.backgroundColor = [UIColor clearColor]; ... [cell.contentView sendSubviewToBack: whiteRoundedCornerView]; cell.tag = tag; }}
user3001228

24

Dovrai impostare la cornice per la tua immagine. Il codice non testato è

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

2
Ho appena testato con backgroundView e questa è la soluzione di lavoro più semplice
Sam,

2
Assicurati di chiamare questo codice layoutSubviewsse stai effettuando la sottoclasseUITableViewCell
Mazyod

30
@ NicoHämäläinen Bene, ho sviluppato oltre 20 app negli ultimi tre anni e ho SEMPRE subclassato UITableViewCellper ottenere il risultato di cui ho bisogno :) ... La sottoclasse UITableViewCellè molto comune.
Mazyod,

1
@ NicoHämäläinen non c'è niente di sbagliato nella sottoclasse UITableViewCell. Quando si crea una creazione personalizzata, UITableViewCellsè necessario eseguire la sottoclasse UITableViewCell.
Popeye,

1
@ NicoHämäläinen, allora dovresti aggiornare il tuo commento. Le persone tendono ad acquisire informazioni e non leggono più. Dato che questo sito è una grande risorsa e gli sviluppatori tendono a fidarsi dei fatti che vedono qui, potrebbero indurli a indurre a pensare cose terribili ... solo le mie due monete. Forse ho isteria
chrs

11

Ero nella stessa barca. All'inizio ho provato a passare alle sezioni, ma nel mio caso è finito per essere più un mal di testa di quanto pensassi inizialmente, quindi ho cercato un'alternativa. Per continuare a utilizzare le righe (e non scherzare con il modo in cui accedi ai dati del tuo modello), ecco cosa ha funzionato per me semplicemente usando una maschera :

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
}

Tutto quello che ti resta da fare è aumentare l'altezza della cella dello stesso valore del tuo desiderato verticalPadding, quindi modificare il layout interno in modo che qualsiasi vista che abbia spaziato ai bordi della cella abbia lo stesso spazio aumentato di verticalPadding/2. Unico inconveniente: si ottiene verticalPadding/2un'imbottitura sia nella parte superiore che in quella inferiore di TableView, ma è possibile risolverlo rapidamente impostando tableView.contentInset.bottom = -verticalPadding/2e tableView.contentInset.top = -verticalPadding/2. Spero che questo aiuti qualcuno!


1
Funziona anche in Swift 5.
Londra

1
Migliore risposta!! Grazie. Se si utilizza una cella personalizzata, questo funziona in "override func awakeFromNib ()"
trees_are_great

10

Penso che la soluzione più semplice se stai solo cercando un po 'di spazio e probabilmente meno costoso sarebbe semplicemente impostare il colore del bordo della cella sul colore di sfondo delle tue tabelle, quindi impostare la larghezza del bordo per ottenere il risultato desiderato!

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

1
Non è una buona idea per lo sfondo trasparente. Altrimenti, potrebbe funzionare.
ergunkocak,

1
Questo è vero. Non è una soluzione per tutti i casi, ma funzionerà per alcuni! @ergunkocak
Craig

8

Se non si utilizzano già le intestazioni di sezione (o piè di pagina), è possibile utilizzarle per aggiungere spaziature arbitrarie alle celle della tabella. Invece di avere una sezione con n righe, crea una tabella con n sezioni con una riga ciascuna.

Implementa il tableView:heightForHeaderInSection:metodo per controllare la spaziatura.

Potresti anche voler implementare tableView:viewForHeaderInSection:per controllare l'aspetto della spaziatura.


8

L'ho risolto in questo modo in Swift 4.

Creo un'estensione di UITableViewCell e includo questo codice:

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
}

Spero che ti aiuti.


il testo nella cella viene ritagliato.
Mehdico,

l'override di CGRect sta funzionando e non ho aggiunto awakeFromNib one.
Eric Tan,

5

Esempio in rapido 3 ..

inserisci qui la descrizione dell'immagine

  1. Creare un'applicazione a vista singola
  2. aggiungi tableview nel controller di visualizzazione
  3. aggiungi una cella personalizzata per la cella tablview
  4. visualizzare il codice del controller è come qui sotto

       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. Scarica la fonte completa su Github: link

    https://github.com/enamul95/CustomSectionTable


ha duplicato un'altra risposta alla quale @Suragch ha già ricevuto una risposta per la versione rapida, per favore evita di fare duplicazioni
Amr Angry

1
questa non è una buona soluzione. Se hai bisogno di una sezione di intestazione con un titolo, questo non funzionerà
kuzdu,

4

Tre approcci a cui riesco a pensare:

  1. Crea una cella di tabella personalizzata che delinea la vista dell'intera cella nel modo desiderato

  2. Invece di aggiungere l'immagine alla vista immagine, cancella le viste secondarie della vista immagine, crea una vista personalizzata che aggiunge un UIImageView per l'immagine e un'altra vista, forse una semplice UIView che fornisce la spaziatura desiderata e aggiungila come sottoview di la vista dell'immagine.

  3. Voglio suggerire di manipolare direttamente UIImageView per impostare una dimensione / imbottitura fissa, ma non sono vicino a Xcode, quindi non posso confermare se / come funzionerebbe.

Ha senso?


4

Sì, puoi aumentare o diminuire la spaziatura (riempimento) tra due celle creando una vista di base sulla vista del contenuto nella cella. Imposta il colore chiaro per lo sfondo della vista del contenuto e puoi regolare l'altezza della vista di base per creare spazio tra le celle.


4

Basato sulla risposta di Husam: l'uso del livello della cella anziché della visualizzazione del contenuto consente di aggiungere un bordo attorno all'intera cella e all'accessorio, se necessario. Questo metodo richiede un'attenta regolazione dei vincoli inferiori della cella e di quegli inserti, altrimenti la vista non sarà corretta.

@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

Modificare il numero di righe nella sezione su 1 È stato modificato il numero di sezioni anziché il numero di righe

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

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

Qui inserisci la spaziatura tra le righe

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

2

Penso che questa sia la soluzione più pulita:

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

1
Non ho potuto vedere alcun cambiamento visivo dopo l'applicazione in layoutMarginsquesto modo. Forse perché sto usando il layout automatico.
Cœur il

I margini non "spezzerebbero" un'altezza esplicita per la cella, quindi è necessario disporre di un'altezza automatica affinché le celle funzionino
Aviel Gross

1
Ho un'altezza automatica.
Cœur il

2

Questo articolo ha aiutato, è praticamente quello che hanno detto le altre risposte, ma riassumendo e conciso

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

In esso, li applica solo ai lati sinistro e destro, ma l' UIEdgeInsetsMakeinit consente di aggiungere imbottitura a tutti e quattro i punti.

func UIEdgeInsetsMake (_ top: CGFloat, _ left: CGFloat, _ bottom: CGFloat, _ right: CGFloat) -> UIEdgeInsets

Descrizione
Crea un bordo per un pulsante o una vista. Un inserto è un margine attorno a un rettangolo. I valori positivi rappresentano i margini più vicini al centro del rettangolo, mentre i valori negativi rappresentano i margini più lontani dal centro.

Parametri
top: l'inserto nella parte superiore di un oggetto.
left: l'inserto a sinistra di un oggetto in
basso: l'inserto in fondo a un oggetto.
right: l'inserto a destra di un oggetto.

Restituisce
Un inserto per un pulsante o una vista

Si noti che UIEdgeInsets può essere utilizzato anche per ottenere lo stesso.

Xcode 9.3 / Swift 4


Questa risposta indica erroneamente che il codice è compatibile con Swift 4, ma UIEdgeInsetsMake è stato deprecato. In alternativa, utilizzare UIEdgeInsets.
José,

developer.apple.com/documentation/uikit/… esattamente dove dice che è stato deprecato? Lo uso nei miei progetti e sto lavorando con l'ultimo Xcode, quindi Swift 9.3 @ José
Mauricio Chirino

Hai ragione, scusa, mia cattiva. UIEdgeInsets è preferito, ma ciò non significa che l'altro sia deprecato. SwiftLint si lamenterà comunque del costruttore legacy quando usa UIEdgeInsetsMake.
José

1
Ok capito. Per favore, rimuovi il voto negativo se eri quello che ha lanciato per favore, non ho mai detto che la mia risposta fosse l'unica possibile.
Mauricio Chirino,

Dice che non posso cambiare il mio voto se non cambi la tua risposta. Puoi forse modificare un po 'le parole?
José

2

Non è necessario utilizzare un sacco di sezioni diverse. Le altre risposte usano inserti di frame e CGRect e layer e ... BLAH. Non bene; usa il layout automatico e un UITableViewCell personalizzato. In quel UITableViewCell, invece di visualizzare il contenuto all'interno di contentView, crea un nuovo containerView (una vista UIV), visualizza la vista contenitore all'interno della vista contenuto, quindi visualizza tutte le viste all'interno della vista contenitore.

Per rendere la spaziatura ora, modifica semplicemente i margini del layout della vista contenitore, in questo modo:

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

Prova a esaminare - (UIEdgeInsets) layoutMargins; sul cellulare


1

La mia situazione era che ho usato UIView personalizzato per viewForHeader nella sezione anche heightForHeader nella sezione return height costante diciamo 40, il problema è stato quando non ci sono dati che hanno toccato tutte le viste dell'intestazione. quindi volevo spaziare tra la sezione in assenza di dati, quindi ho risolto semplicemente cambiando il piano "stile tabella" in "Gruppo". E ha funzionato per me.


1

Scopri la mia soluzione su GitHub con la sottoclasse UITableViewe l'utilizzo delle funzionalità di runtime di Objective-C.
Utilizza fondamentalmente la struttura di dati privati ​​di Apple UITableViewRowDatache ho cercato nella intestazione di runtime privata di UITableView:

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

ed ecco la classe privata desiderata che contiene tutto il necessario per disporre le spaziature delle celle come desiderato senza impostarle nelle classi delle celle:

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


1

Ho avuto problemi a farlo funzionare a fianco dei colori di sfondo e delle viste degli accessori nella cella. Alla fine ho dovuto:

1) Impostare la proprietà della vista di sfondo delle celle con un UIView impostato con un colore di sfondo.

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

2) Riposizionare questa vista in layoutSubviews per aggiungere l'idea di spaziatura

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

1

Usare le intestazioni come spaziatura funzionerebbe bene, immagino che se non vuoi usare nessuna intestazione. Altrimenti, probabilmente non è la migliore idea. Quello che sto pensando è creare una vista cellulare personalizzata.

Esempi:

Nella cella personalizzata, crea una vista di sfondo con vincoli in modo che non riempia l'intera cella, dagli un po 'di riempimento.

Quindi, rendere invisibile lo sfondo della vista tabella e rimuovere i separatori:

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

// Remove the separators
tableview.separatorStyle = .none

1

Se non desideri modificare la sezione e il numero di riga della vista della tabella (come ho fatto io), ecco cosa fai:

1) Aggiungi un ImageView nella parte inferiore della vista della cella della tabella.

2) Rendi lo stesso colore del colore di sfondo della vista tabella.

L'ho fatto nella mia applicazione e funziona perfettamente. Saluti! : D


0

inserisci qui la descrizione dell'immagineSWift-5, Spaziatura tra 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

Puoi semplicemente usare il vincolo nel codice in questo modo:

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

    }
}

è importante aggiungere subview (contenitore) e inserire altri elementi al suo interno.


-2

aggiungi una vista interna alla cella quindi aggiungi le tue viste ad essa.


-2

Soluzione Swift 5.0

Sottoclasse UITableViewCell

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

-4

Utilizzare UITableViewDelegate heightForRowAtIndexPathe restituire l'altezza della riga.

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

La domanda è come aggiungere la spaziatura tra le celle piuttosto che l'altezza della cella
shippo7
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.