web-dev-qa-db-fra.com

Comment ajouter un espacement entre UITableViewCell

Est-il possible d'ajouter un espacement entre UITableViewCell?

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

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

mais cela rend l'image agrandie et s'adapte à toute la cellule, sans espacement.

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

130
saili

Pour ajouter de l’espacement entre les cellules, j’ai recours à numberOfSections = "Le nombre de vos tableaux" et à chaque section ne contient qu’une seule ligne. 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;
}
122
JonatWang

Version rapide

_ {Mis à jour pour Swift 3} _

Cette réponse est un peu plus générale que la question initiale à l’intention des futurs téléspectateurs. C'est un exemple supplémentaire à l'exemple de base UITableView pour Swift

 enter image description here

Vue d'ensemble

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 leur en-tête.

Comment faire

  • Configurez votre projet comme décrit dans Exemple UITableView pour Swift . (C’est-à-dire, ajoutez une UITableView et connectez la sortie tableView au contrôleur de vue). 

  • Dans Interface Builder, modifiez la couleur d'arrière-plan de la vue principale en bleu clair et la couleur d'arrière-plan UITableView à effacer.

  • Remplacez le code ViewController.Swift par le suivant.

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 indexPath.section est utilisé plutôt que indexPath.row afin d'obtenir les valeurs appropriées pour les éléments du tableau et les positions de prise. 

Comment avez-vous obtenu le rembourrage/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 pin dans Interface Builder pour ajouter un espacement entre les contraintes de début et de fin.

117
Suragch

Ma solution facile en utilisant 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 enter image description here

68
Husam

J'avais besoin de faire le même concept pour que UITableCells ait un "espace" entre eux. Etant donné que 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 réalisé dans un autre projet test lorsque je simulais ceci:

Spacing between UITableViewCells

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

Premièrement, je devais définir la heightForRowAtIndexPath pour permettre différentes hauteurs sur 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'apparence des UITableViewCells afin de le faire dans la méthode willDisplayCell:(NewsUITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath.

- (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 créé ma hauteur whiteRoundedCornerView 70.0 et que c'est ce qui cause l'espace simulé car la hauteur de la cellule est en réalité de 80.0 mais mon contentView est de 70.0, ce qui lui donne l'aspect.

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.

39
Flea

Vous devrez définir un cadre pour votre image. Le code non testé est

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

Si vous n'utilisez pas déjà les en-têtes de section (ou les 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 méthode tableView:heightForHeaderInSection: pour contrôler l'espacement.

Vous pouvez également vouloir implémenter tableView:viewForHeaderInSection: pour contrôler l'apparence de l'espacement.

7
Ferruccio

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

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

Oui, vous pouvez augmenter ou diminuer 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.

3
divya d

Trois approches auxquelles je peux penser:

  1. Créez une cellule de tableau personnalisée qui présente la vue de l'ensemble de la cellule comme vous le souhaitez

  2. Au lieu d’ajouter l’image à la vue Image, effacez les sous-vues de La vue image, créez une vue personnalisée Ajoutant un UIImageView pour l’image et une autre vue, peut-être une simple vue UIV offrant espacement, et l'ajouter en tant que sous-vue de la vue d'image

  3. Je veux suggérer que vous manipuliez UIImageView directement pour définir une taille/un remplissage fixe, mais je ne suis pas du tout près de Xcode, donc je ne peux pas confirmer si/comment cela fonctionnerait.

Cela a-t-il du sens?

3
csano

Solution Swift 4.2

// Inside UITableViewCell subclass
override func layoutSubviews() {    
    super.layoutSubviews()

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

Exemple dans Swift 3 ..

 enter image description here

  1. Crease une application de vue unique
  2. ajouter une vue de table dans le contrôleur de vue
  3. ajouter une cellule personnalisée pour une cellule tablview
  4. voir le code du contrôleur 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échargez le code source complet sur Github: lien 

    https://github.com/enamul95/CustomSectionTable

2
Enamul Haque

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

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

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

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

Dans ce document, il ne les applique qu'aux côtés gauche et droit, mais UIEdgeInsetsMake init permet d’ajouter du remplissage aux quatre points.

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

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

Paramètres
top: L'encart en haut d'un objet.
left: l'insert à gauche d'un objet
bottom: L'encart au bas d'un objet.
right: L'encart à droite d'un objet.

Résultats
Un encart pour un bouton ou une vue

Notez que UIEdgeInsets peut également être utilisé pour atteindre le même objectif.

Xcode 9.3/Swift 4

1
Mauricio Chirino

Je l'ai résolu comme ça dans Swift 4.

Je crée une extension de UITableViewCell et inclut 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.

1
JulianKro

Sur la base de la réponse de Husam: L'utilisation de la couche de cellules au lieu de la vue du contenu permet d'ajouter une bordure autour de la cellule entière et de l'accessoire si besoin est. Cette méthode nécessite un ajustement soigneux des contraintes de fond de la cellule ainsi que de celles insérées, 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
1
dev_exo

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

0
drunknbass

J'étais dans le même bateau. Au début, j’ai essayé de changer de section, mais dans mon cas, c’était davantage un mal de tête que je ne le pensais au départ, alors j’ai cherché une alternative. Pour continuez à utiliser des lignes (et ne modifiez pas la façon dont vous accédez aux données de votre modèle), voici ce qui a fonctionné pour moi juste en 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 qu'il vous reste à faire est de augmenter la hauteur de la cellule de la même valeur que votre verticalPadding désirée, puis de modifier votre disposition interne de sorte que les vues espacées des bords de la cellule soient augmentées de ce même espacement. verticalPadding/2. Inconvénient mineur: vous obtenez un remplissage verticalPadding/2 en haut et en bas de la table, mais vous pouvez y remédier rapidement en définissant tableView.contentInset.bottom = -verticalPadding/2 et tableView.contentInset.top = -verticalPadding/2. J'espère que cela aide quelqu'un!

0
Raimondo Previdi

Dans ma situation, j’ai utilisé UIView personnalisé pour afficher ViewForHeader dans la section ainsi que heightForHeader dans la section return return height, disons 40, le problème était qu’il n’existait pas de données dans lesquelles toutes les vues d’en-tête étaient touchées. donc je voulais espacer la section en l’absence de données, donc j’ai corrigé en changeant simplement le plan "style tableview" en "groupe" .et cela a fonctionné pour moi. 

0
Avijit Nagare

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

1) Définissez la propriété d'affichage de l'arrière-plan des cellules avec un jeu UIView 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
}
0
Harry Bloom

Utiliser les en-têtes comme espacement fonctionnerait bien, je suppose, si vous ne voulez pas utiliser d'en-tête. 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 pour qu’elle ne remplisse pas la totalité de la cellule, mais complétez-la.

Ensuite, rendez l’arrière-plan de la table invisible et supprimez les séparateurs:

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

// Remove the separators
tableview.separatorStyle = .none
0
TJ Olsen

Si vous ne souhaitez pas modifier la section et le numéro de ligne de votre vue Table (comme je l'ai fait), procédez comme suit:

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

2) Faites-en la même couleur que la couleur de fond de la vue tableau.

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

0
Deveesh

Consultez ma solution sur GitHub avec un sous-classement de UITableView et en utilisant les fonctionnalités d'exécution d'Objective-C.
Il utilise essentiellement la structure de données privée d'Apple UITableViewRowData que j'ai obtenue en cherchant 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

0
Gleb Linnik