Comment ajouter un espacement entre UITableViewCell

182

Existe-t-il un moyen d'ajouter un espacement entre les deux UITableViewCell?

J'ai créé un tableau et chaque cellule ne contient qu'une image. L'image est affectée à la cellule comme ceci:

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

mais cela rend l'image agrandie et rentre dans la cellule entière, et il n'y a pas d'espacement entre les images.

Ou disons de cette manière, la hauteur de l'image est par exemple de 50, et je veux ajouter 20 espacement entre les images. Y a-t-il un moyen d'accomplir cela?

Saili
la source
1
Pour Swift 2.2, voir ma réponse ici: stackoverflow.com/a/37673417/2696626
ibrahimyilmaz

Réponses:

160

Version Swift

Mis à jour pour Swift 3

Cette réponse est un peu plus générale que la question initiale pour le bien des futurs téléspectateurs. Il s'agit d'un exemple supplémentaire à l'exemple de base UITableView pour Swift .

entrez la description de l'image ici

Aperçu

L'idée de base est de créer une nouvelle section (plutôt qu'une nouvelle ligne) pour chaque élément du tableau. Les sections peuvent ensuite être espacées en utilisant la hauteur de l'en-tête de section.

Comment faire

  • Configurez votre projet comme décrit dans l' exemple UITableView pour Swift . (Autrement dit, ajoutez un UITableViewet connectez la tableViewprise au contrôleur de vue).

  • Dans le générateur d'interface, modifiez la couleur d'arrière-plan de la vue principale en bleu clair et la UITableViewcouleur d'arrière - plan en clair.

  • Remplacez le code ViewController.swift par ce qui suit.

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

Notez que cela indexPath.sectionest utilisé plutôt que indexPath.rowpour obtenir les valeurs appropriées pour les éléments du tableau et les positions de prise.

Comment avez-vous obtenu le rembourrage / l'espace supplémentaire à droite et à gauche?

Je l'ai obtenu de la même manière que vous ajoutez un espacement à n'importe quelle vue. J'ai utilisé des contraintes de mise en page automatique. Utilisez simplement l' outil d'épingle dans Interface Builder pour ajouter un espacement pour les contraintes de début et de fin.

Suragch
la source
Salut, je me demandais si cela était possible sans convertir toutes vos lignes en sections. J'ai des bordures sur chaque tableViewCell, donc augmenter la hauteur n'aidera pas. J'ai beaucoup de personnalisations avec ma cellule et je ne souhaite pas la convertir en sections. Merci!
Ujjwal-Nadhani
3
@ user2901306, j'hésitais également à utiliser cette méthode au début, car j'avais l'impression que je devrais pouvoir utiliser simplement des lignes et augmenter une marge ou quelque chose du genre. Cependant, je n'ai pas trouvé de moyen de le faire et cette méthode a très bien fonctionné. Vous n'êtes pas obligé de modifier les personnalisations de votre cellule. En gros, il vous suffit d'ajouter numberOfSectionsInTableViewet return 1pour le nombre de lignes. Utilisez ensuite indexPath.sectionpour obtenir l'index de cellule actuel. Essayez-le une fois. Je pense que vous découvrirez que vous n'avez pas besoin de faire beaucoup de changements à votre configuration actuelle. C'est certainement plus facile que de sous-classer.
Suragch
L'utilisation de cell.layer.xxx dans cellForRow peut vous donner un impact sur les performances. Mieux vaut définir ces valeurs dans le XIB
Abhishek Bedi
@AbhishekBedi, j'ai toujours trouvé que les layermanipulations étaient assez rapides. Êtes-vous en train de dire cela parce que vous avez remarqué une mauvaise performance ou comme une bonne pratique générale? Même si vous les définissez dans un XIB, ils doivent toujours être définis lorsque la cellule est créée.
Suragch
1
@FateNuller, je ne suis pas en désaccord avec vous. La réponse de Husam semble plutôt bonne.
Suragch
150

Ma solution simple avec Swift :

// Inside UITableViewCell subclass

override func layoutSubviews() {
    super.layoutSubviews()

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

Résultat entrez la description de l'image ici

Husam
la source
11
Belle solution. Au cas où quelqu'un aurait des problèmes, je devais appeler d' super.layoutSubviews()abord pour m'assurer que la vue entière était correctement présentée avant de définir son cadre.
ruttopia
@Husam Votre solution a fonctionné pour moi. Mais j'ai un problème lors de la sélection de la cellule. J'ai défini la bordure pour contentView et chaque fois que j'ai sélectionné la cellule, la bordure sera plus petite. Comment puis-je y remédier?
Bad_Developer
@SonHoang Vous devrez peut - être remplacer didSetpour selectedvariable et appel à l' layoutSubviews()intérieur!
Husam
1
Hé, Husam. Merci pour la bonne solution. Ne me dites pas comment changer la couleur du contenu ajouté entre les cellules?
A.Kant
1
C'est une bien meilleure solution que la réponse acceptée. La réponse acceptée a sacrément près de 100 lignes de code et ce n'est qu'une. Incroyable.
YungGun
135

La façon dont j'arrive à ajouter un espacement entre les cellules est de faire numberOfSections = "Your array count" et de faire en sorte que chaque section ne contienne qu'une seule ligne. Et puis définissez headerView et sa hauteur.

- (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;
}
JonatWang
la source
22
Cela fonctionne très bien. J'ai dû changer un peu le cellForRowAtIndexPath, pas le tableau normal [indexPath.row] mais le tableau [indexPath.section]. Sinon, il affichera le premier élément du tableau dans toutes les sections.
Tom Spee
@TomSpee - Comment avez-vous résolu ce problème dans cellForRowAtIndexPath?
5
@TKutal - Tout comme le code normal dans cellForRowAtIndexPath mais changez le indexPath.row en indexPath.section
Tom Spee
Bien que cela accomplisse ce que le demandeur désire, je ne pense pas qu'Apple recommande cette approche. Corrigez-moi si je me trompe, mais je crois que les "sections" sont destinées à séparer logiquement les "sections" de données que vous représentez dans votre tableau. Vous ne devez pas utiliser de "sections" pour styliser les espaces entre chaque cellule de données qui, sinon, devraient toutes être affichées dans une seule section. Je pense que la meilleure approche, bien que plus difficile, serait de sous-classer UITableViewCell et de simuler le séparateur de vue de tableau en ajoutant une vue au bas de la cellule.
FateNuller du
2
Ensuite, Apple devrait plutôt ne pas se plaindre, mais créer une méthode pratique pour faire varier l'espace entre les lignes.
Arnie Schwarzvogel
44

J'avais besoin de faire le même concept que les UITableCells aient un "espace" entre elles. Puisque vous ne pouvez pas littéralement ajouter d'espace entre les cellules, vous pouvez le simuler en manipulant la hauteur de cellule de UITableView, puis en ajoutant un UIView au contentView de votre cellule. Voici une capture d'écran d'un prototype que j'ai fait dans un autre projet de test lorsque je simulais ceci:

Espacement entre UITableViewCells

Voici un peu de code (Remarque: il y a beaucoup de valeurs codées en dur à des fins de démonstration)

Tout d'abord, je devais régler le heightForRowAtIndexPathpour permettre différentes hauteurs sur l'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;
}

Ensuite, je veux manipuler l'aspect et la convivialité des UITableViewCells, donc je le fais dans la willDisplayCell:(NewsUITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPathméthode.

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

    }
}

Notez que j'ai fait ma hauteur whiteRoundedCornerView 70,0 et c'est ce qui cause l'espace simulé car la hauteur de la cellule est en fait 80,0 mais mon contentView est 70,0 ce qui lui donne l'apparence.

Il y a peut-être d'autres façons d'accomplir cela encore mieux, mais c'est juste comment j'ai trouvé comment le faire. J'espère que cela peut aider quelqu'un d'autre.

Puce
la source
Juste un FYI, pour un très grand nombre de cellules, vous voudrez définir la vue du contenu dans la sous-classe de cellules au lieu de willDisplayCell. La performance commence à prendre un énorme succès en le faisant de cette façon, plus vous ajoutez de cellules à la file d'attente
BBH1023
@ BBH1023 Le calque d'ombre se multiplie à chaque fois que la vue apparaît lors d'un va-et-vient pour afficher rapidement. Comment suggéreriez-vous d'annuler cela s'il a déjà été appliqué une fois
soulshined
à privent pour ajouter plus d'ombre, procédez comme suit: NSInteger tag = 120; if (indexPath.row! = 0) {if (cell.tag! = 120) {cell.contentView.backgroundColor = [UIColor clearColor]; ... [cell.contentView sendSubviewToBack: whiteRoundedCornerView]; cell.tag = balise; }}
user3001228
24

Vous devrez définir le cadre de votre image. Le code non testé est

cell.imageView.frame = CGRectOffset(cell.frame, 10, 10);
Chanok
la source
2
Je viens de tester avec backgroundView et c'est la solution de travail la plus simple
Sam
2
Assurez-vous simplement d'appeler ce code layoutSubviewssi vous faites une sousUITableViewCell
classification
30
@ NicoHämäläinen Eh bien, j'ai développé plus de 20 applications au cours des trois dernières années, et j'ai TOUJOURS sous-classées UITableViewCellafin d'obtenir le résultat dont j'ai besoin :) ... Le sous UITableViewCell- classement est très courant.
Mazyod
1
@ NicoHämäläinen il n'y a rien de mal à sous-classer UITableViewCell. Lorsque vous créez une personnalisation, UITableViewCellsvous devez effectuer des sous-classes UITableViewCell.
Popeye
1
@ NicoHämäläinen, vous devriez alors mettre à jour votre commentaire. Les gens ont tendance à saisir des informations et à ne pas lire plus loin. Puisque ce site est une excellente ressource et que les développeurs ont tendance à faire confiance aux faits qu'ils voient ici, cela pourrait les induire en erreur en pensant à des choses terribles ... juste mes deux pièces. Peut-être que j'ai l'hystérie
chrs
11

J'étais dans le même bateau. Au début, j'ai essayé de passer aux sections, mais dans mon cas, cela a fini par être plus un casse-tête que je ne le pensais au départ, alors j'ai cherché une alternative. À continuer à utiliser des lignes (et ne pas gâcher la façon dont vous accédez à vos données de modèle), voici ce qui a fonctionné pour moi simplement en utilisant un masque :

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
}

Tout ce que vous avez à faire est d'agrandir la hauteur de la cellule de la même valeur que celle souhaitée verticalPadding, puis de modifier votre disposition intérieure de sorte que toutes les vues qui avaient un espacement vers les bords de la cellule aient ce même espacement augmenté de verticalPadding/2. Inconvénient mineur: vous obtenez un verticalPadding/2rembourrage en haut et en bas de la tableView, mais vous pouvez rapidement résoudre ce problème en définissant tableView.contentInset.bottom = -verticalPadding/2et tableView.contentInset.top = -verticalPadding/2. J'espère que cela aide quelqu'un!

Merricat
la source
1
Fonctionne également dans Swift 5.
LondonGuy
1
Meilleure réponse!! Je vous remercie. Si vous utilisez une cellule personnalisée, cela fonctionne dans la fonction "override func awakeFromNib ()"
arbres_are_great
10

Je pense que la solution la plus simple si vous recherchez simplement un peu d'espace et probablement la moins chère serait de simplement définir la couleur de la bordure de la cellule sur la couleur d'arrière-plan de votre tableau, puis de définir la largeur de la bordure pour obtenir le résultat souhaité!

    cell.layer.borderColor = blueColor.CGColor
    cell.layer.borderWidth = 3
Craig
la source
1
Ce n'est pas une bonne idée pour un fond transparent. Sinon, cela peut fonctionner.
ergunkocak
1
C'est vrai. Ce n'est pas une solution pour tous les cas mais cela fonctionnera pour certains! @ergunkocak
Craig
8

Si vous n'utilisez pas déjà des en-têtes de section (ou des pieds de page), vous pouvez les utiliser pour ajouter un espacement arbitraire aux cellules du tableau. Au lieu d'avoir une section avec n lignes, créez un tableau avec n sections avec une ligne chacune.

Implémentez la tableView:heightForHeaderInSection:méthode pour contrôler l'espacement.

Vous voudrez peut-être également implémenter tableView:viewForHeaderInSection:pour contrôler à quoi ressemble l'espacement.

Ferruccio
la source
8

Je l'ai résolu de cette façon dans Swift 4.

Je crée une extension de UITableViewCell et j'inclus ce code:

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
}

J'espère que ça t'aide.

JulianKro
la source
le texte de la cellule est rogné.
Mehdico
le remplacement CGRect fonctionne, et je n'en ai pas ajouté awakeFromNib.
Eric Tan
5

Exemple dans swift 3 ..

entrez la description de l'image ici

  1. Plier une application à vue unique
  2. ajouter tableview dans le contrôleur de vue
  3. ajouter une cellule personnalisée pour la cellule tablview
  4. le code du contrôleur de vue est ci-dessous comme

       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 (dans 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. Télécharger la source complète sur Github: lien

    https://github.com/enamul95/CustomSectionTable

Enamul Haque
la source
il a dupliqué une autre réponse à laquelle @Suragch a déjà reçu une réponse pour la version rapide, veuillez éviter de faire une duplication
Amr Angry
1
ce n'est pas une bonne solution. Si vous avez besoin d'une section d'en-tête avec un titre, cela ne fonctionnera pas
kuzdu
4

Trois approches auxquelles je peux penser:

  1. Créez une cellule de tableau personnalisée qui présente la vue de la cellule entière de la manière que vous souhaitez

  2. Au lieu d'ajouter l'image à la vue d'image, effacez les sous-vues de la vue d'image, créez une vue personnalisée qui ajoute une UIImageView pour l'image et une autre vue, peut-être une simple UIView qui fournit l'espacement souhaité, et ajoutez-la en tant que sous-vue de la vue de l'image.

  3. Je veux vous suggérer de manipuler l'UIImageView directement pour définir une taille / un remplissage fixe, mais je suis loin de Xcode, donc je ne peux pas confirmer si / comment cela fonctionnerait.

Cela a-t-il du sens?

csano
la source
4

Oui, vous pouvez augmenter ou réduire l'espacement (remplissage) entre deux cellules en créant une vue de base sur la vue de contenu dans la cellule.Définissez une couleur claire pour l'arrière-plan de la vue de contenu et vous pouvez ajuster la hauteur de la vue de base pour créer un espace entre les cellules.

divya d
la source
4

Basé sur la réponse de Husam: l'utilisation de la couche de cellule au lieu de la vue de contenu permet d'ajouter une bordure autour de la cellule entière et de l'accessoire si nécessaire. Cette méthode nécessite un ajustement soigneux des contraintes de fond de la cellule ainsi que de ces encarts sinon la vue ne sera pas correcte.

@implementation TableViewCell

- (void)awakeFromNib { 
    ... 
}

- (void) layoutSubviews {
    [super layoutSubviews];

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

@end
dev_exo
la source
3

Changer le nombre de lignes dans la section à 1 Vous avez changé le nombre de sections au lieu du nombre de lignes

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

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

Ici, vous mettez l'espacement entre les lignes

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

Je pense que c'est la solution la plus propre:

class MyTableViewCell: UITableViewCell {
    override func awakeFromNib() {
        super.awakeFromNib()
        layoutMargins = UIEdgeInsetsMake(8, 0, 8, 0)
    }
}
Aviel Gross
la source
1
Je ne pouvais voir aucun changement visuel après avoir appliqué layoutMarginscette méthode. Peut-être parce que j'utilise la mise en page automatique.
Cœur
Les marges ne "casseraient" pas une hauteur explicite pour la cellule, vous devez donc avoir une hauteur automatique pour les cellules pour que cela fonctionne
Aviel Gross
1
J'ai une hauteur automatique.
Cœur
2

Cet article a aidé, c'est à peu près ce que les autres réponses ont dit mais résumant et concis

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

Dans celui-ci, il ne les applique qu'aux côtés gauche et droit, mais l' UIEdgeInsetsMakeinit permet d'ajouter un rembourrage aux quatre points.

func UIEdgeInsetsMake (_ haut: CGFloat, _ gauche: CGFloat, _ bas: CGFloat, _ droite: CGFloat) -> UIEdgeInsets

Description
Crée un encart d'arête pour un bouton ou une vue. Un encart est une marge autour d'un rectangle. Les valeurs positives représentent des marges plus proches du centre du rectangle, tandis que les valeurs négatives représentent des marges plus éloignées du centre.

Paramètres
top: L'encart en haut d'un objet.
à gauche: L'encart à gauche d'un objet
bas: L'encart en bas d'un objet.
à droite: l'encart à droite d'un objet.

Renvoie
un encart pour un bouton ou une vue

Notez que UIEdgeInsets peut également être utilisé pour réaliser la même chose.

Xcode 9.3 / Swift 4

Mauricio Chirino
la source
Cette réponse indique à tort que le code est compatible Swift 4, mais UIEdgeInsetsMake est obsolète. UIEdgeInsets doit être utilisé à la place.
José
developer.apple.com/documentation/uikit/… exactement où est-il dit qu'il est obsolète? Je l'utilise dans mes projets et je travaille avec le dernier Xcode, donc Swift 9.3 @ José
Mauricio Chirino
Vous avez raison, désolé, mon mal. UIEdgeInsets est préférable, mais cela ne signifie pas que l'autre est obsolète. SwiftLint se plaindra cependant du constructeur hérité lors de l'utilisation de UIEdgeInsetsMake.
José
1
Ok compris. Veuillez supprimer le vote négatif si vous étiez celui qui a émis s'il vous plaît, je n'ai jamais dit que ma réponse était la seule possible.
Mauricio Chirino
Il dit que je ne peux pas changer mon vote à moins que vous ne changiez votre réponse. Pouvez-vous peut-être modifier un peu le libellé?
José
2

Il n'est pas nécessaire d'utiliser un tas de sections différentes. Les autres réponses utilisent des encarts de cadre et CGRect et des couches et ... BLAH. Pas bon; utilisez la disposition automatique et un UITableViewCell personnalisé. Dans cet UITableViewCell, au lieu de sous-afficher votre contenu dans le contentView, créez un nouveau containerView (un UIView), sous-visualisez la vue du conteneur dans le contentView, puis sous-visualisez toutes vos vues dans la vue du conteneur.

Pour créer l'espacement maintenant, modifiez simplement les marges de mise en page de la vue du conteneur, comme ceci:

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)
        ])
    }
}
Yoomama
la source
1

Essayez de regarder dans - (UIEdgeInsets) layoutMargins; sur la cellule

drunknbass
la source
1

Ma situation était que j'utilisais UIView personnalisé pour viewForHeader dans la section également heightForHeader dans la section retourner une hauteur constante, disons 40, le problème était quand il n'y avait pas de données, toutes les vues d'en-tête étaient touchées les unes aux autres. donc je voulais espacer entre la section en l'absence de données, donc j'ai fixé en changeant simplement le plan "style tableview" en "Groupe". et cela a fonctionné pour moi.

Avijit Nagare
la source
1

Découvrez ma solution sur GitHub avec sous-classification UITableViewet utilisation des fonctionnalités d'exécution d'Objective-C.
Il utilise essentiellement la structure de données privée d'Apple UITableViewRowDataque j'ai obtenue en recherchant l'en-tête d'exécution privé de UITableView:

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

et voici la classe privée souhaitée qui contient tout ce dont vous avez besoin pour disposer les espacements de vos cellules comme vous le souhaitez sans le définir dans les classes de cellules:

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

Gleb Linnik
la source
1

J'avais du mal à faire fonctionner cela avec les couleurs d'arrière-plan et les vues d'accessoires dans la cellule. J'ai fini par devoir:

1) Définissez la propriété de vue d'arrière-plan des cellules avec un UIView défini avec une couleur d'arrière-plan.

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

2) Repositionnez cette vue dans layoutSubviews pour ajouter l'idée d'espacement

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

Utiliser les en-têtes comme espacement fonctionnerait bien, je suppose que si vous ne voulez pas utiliser d'en-têtes. Sinon, probablement pas la meilleure idée. Ce que je pense, c'est créer une vue de cellule personnalisée.

Exemples:

Dans la cellule personnalisée, créez une vue d'arrière-plan avec des contraintes afin qu'elle ne remplisse pas toute la cellule, donnez-lui un peu de remplissage.

Ensuite, rendez l'arrière-plan de tableview invisible et supprimez les séparateurs:

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

// Remove the separators
tableview.separatorStyle = .none
TJ Olsen
la source
1

Si vous ne souhaitez pas modifier la section et le numéro de ligne de votre vue de tableau (comme je l'ai fait), voici ce que vous faites:

1) Ajoutez une ImageView au bas de votre vue de cellule de tableau.

2) Faites-lui la même couleur que la couleur d'arrière-plan de la vue de table.

J'ai fait cela dans mon application et cela fonctionne parfaitement. À votre santé! :RÉ

Deveesh
la source
0

entrez la description de l'image iciSWift-5, espacement entre 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!
MALIKK HABIB UR REHMAN
la source
0

Vous pouvez simplement utiliser une contrainte dans le code comme ceci:

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

    }
}

il est important d'ajouter une sous-vue (conteneur) et d'y mettre d'autres éléments.

Ali Tavakoli
la source
-2

ajoutez une vue intérieure à la cellule puis ajoutez-y vos propres vues.

user3812138
la source
-2

Solution Swift 5.0

Dans la sous-classe UITableViewCell

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

Utilisez UITableViewDelegate heightForRowAtIndexPathet renvoyez la hauteur de la ligne.

 (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
 return 100.0f ;
}
Développeur MARK IOS
la source
La question est de savoir comment ajouter un espacement entre les cellules plutôt que la hauteur de la cellule
shippo7