web-dev-qa-db-fra.com

Comment personnaliser le séparateur uitableView sur iPhone

Par défaut, il existe un séparateur de ligne unique dans uitableview.

Mais je veux mettre ma ligne personnalisée en tant que séparateur.

C'est possible? Comment?

64
Sagar R. Kothari

Si vous voulez faire plus que changer la couleur du séparateur en utilisant la propriété separatorColor de UITableView , vous pouvez définir la propriété separatorStyle sur UITableViewCellSeparatorStyleNone , puis

  • créer des UITableViewCell personnalisés qui incluent votre séparateur personnalisé en leur sein 
  • créer d'autres UITableViewCell contenant le séparateur personnalisé

Par exemple, si votre table affiche actuellement 5 lignes, vous pouvez la mettre à jour pour afficher 9 lignes. Les lignes d'index 1, 3, 5, 7 sont des cellules de séparation.

Voir Subclassing UITableViewCell dans le Guide de programmation de la vue Table pour plus d'informations sur la création de UITableViewCell personnalisés.

81
Daniel Richardson

Une meilleure solution consiste à utiliser la largeur et la hauteur actuelles de la cellule. Quelque chose comme ça:

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, cell.contentView.frame.size.height - 1.0, cell.contentView.frame.size.width, 1)];

lineView.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview:lineView];
34
Jerry Destremps

Si vous avez besoin de différentes couleurs de séparateur pour différentes lignes OR, vous souhaitez que le séparateur reste visible lorsque la ligne est mise en surbrillance lorsque vous appuyez sur, puis essayez ceci:

self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

// We have to use the borderColor/Width as opposed to just setting the 
// backgroundColor else the view becomes transparent and disappears during 
// the cell's selected/highlighted animation
UIView *separatorView = [[UIView alloc] initWithFrame:CGRectMake(0, 43, 1024, 1)];
separatorView.layer.borderColor = [UIColor redColor].CGColor;
separatorView.layer.borderWidth = 1.0;
[cell.contentView addSubview:separatorView];

Cela suppose que la couleur d'arrière-plan de votre cellule est transparente.


La solution ci-dessus est issue d'une vaste expérimentation. Voici quelques notes sur mes découvertes qui, j'en suis sûr, aideront les gens:

Dans l'état normal «non sélectionné»

  • ContentView (ce qui se trouve dans votre XIB sauf si vous l'avez codé autrement) est dessiné normalement
  • Le backgroundView sélectionné est masqué
  • BackgroundView est visible (si votre contentView est transparent, vous voyez alors backgroundView ou (si vous n'avez pas défini backgroundView, vous verrez la couleur d'arrière-plan de UITableView elle-même).

Une cellule est sélectionnée, les événements suivants se produisent immédiatement sans aucune animation:

  • Toutes les vues/sous-vues de la propriété contentView ont leur couleur d'arrière-plan effacée (ou définie sur transparente), le libellé etc. de la couleur du texte est remplacé par la couleur sélectionnée
  • SelectedBackgroundView devient visible (cette vue est toujours la taille de la cellule (un cadre personnalisé est ignoré, utilisez une sous-vue si vous en avez besoin). Notez également que les propriétés backgroundColor de subViews ne sont pas affichées, elles sont peut-être transparentes. comme le contentView). Si vous n'avez pas défini selectedBackgroundView, Cocoa créera/insérera le fond dégradé bleu (ou gris) et l'affichera pour vous.)
  • Le backgroundView est inchangé

Lorsque la cellule est désélectionnée, une animation pour supprimer la mise en surbrillance commence:

  • La propriété selectedBackgroundView alpha est animée de 1.0 (totalement opaque) à 0.0 (totalement transparent).
  • BackgroundView est à nouveau inchangé (donc l'animation ressemble à un fondu enchaîné entre selectedBackgroundView et backgroundView)
  • Après que l'animation soit terminée, contentView est redessiné dans l'état "non sélectionné" et sa sous-vue backgroundColor est à nouveau visible (cela peut rendre votre animation horrible, il est donc conseillé de ne pas utiliser UIView.backgroundColor dans votre contentView)
31
Oliver Pearmain

Ces réponses ont pour effet de remplacer le trait de surbrillance par le séparateur que vous ajoutez à votre cellule (sur iOS 6 au moins avec mes tests). Vous devez définir la separatorColor sur [UIColor clearColor] pour que les cellules soient toujours séparées par 1px. Vous pouvez ensuite tracer votre séparateur dans l’espace:

- (void)viewDidLoad {
    self.tableView.separatorColor = [UIColor clearColor];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // snip
    CALayer *separator = [CALayer layer];
    separator.backgroundColor = [UIColor redColor].CGColor;
    separator.frame = CGRectMake(0, 43, self.view.frame.size.width, 1);
    [cell.layer addSublayer:separator];
    return cell;
}
13
mxcl

Vous ajoutez le code suivant cellForRowAtIndexPath délégué de tableView pour créer une vue d'image personnalisée d'une hauteur de 1 pixel et d'une largeur de 200 pixels pour chaque

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 200, self.view.bounds.size.width, 1)];
lineView.backgroundColor = [UIColor blackColor];
[cell.contentView addSubview:lineView];

Note : Je ne sais pas à quel point il est lourd sur la performance.

8
carbonr

Je ne sais pas si cela peut être fait "automatiquement" avec certains réglages. Mais une suggestion serait de définir le séparateur de lignes sur none et de tracer le séparateur de lignes que vous souhaitez dans les limites de vos cellules.

4
Daniel

Si vous utilisez des cellules personnalisées dans Swift: Une autre approche consiste à étendre UITableViewCell avec une fonction permettant de tracer une ligne en haut de cette cellule. 

import UIKit

extension UITableViewCell {
    func addSeparatorLineToTop(){
        let lineFrame = CGRectMake(0, 0, bounds.size.width, 1)
        let line = UIView(frame: lineFrame)
        line.backgroundColor = UIColor.myGray_300()
        addSubview(line)
    }
}

Ensuite, vous pouvez ajouter cette ligne à n’importe quelle cellule personnalisée, par exemple dans awakeFromNib.

override func awakeFromNib() {
    super.awakeFromNib()
    addSeparatorLineToTop()
}

Cette solution est agréable car elle ne gâche pas votre story-board et limite votre code supplémentaire à 1 ligne. 

3
Pbk

Testé sur iOS 7 (GM):

@implementation MyTableViewController

- (void)viewDidLayoutSubviews {
    for (UIView *view in self.view.subviews) {
        if ([view isKindOfClass:NSClassFromString(@"_UITableViewCellSeparatorView")])
            view.backgroundColor = [UIColor redColor];
    }
}

@end

REMARQUE: il apparaît que UITableView move separators dans les cellules de certaines configurations, ce qui empêcherait ce code de fonctionner à moins que vous descendiez également dans tous les UITableViewCells.

1
mxcl

Sur un écran Retina, même si vous tracez une ligne de 0,5 unité, vous obtiendrez une ligne de deux pixels en raison de l'anti-aliasing. Pour le rendre sous la forme d'un pixel unique sur les deux écrans, décalez-le d'un quart d'unité:

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, self.contentView.frame.size.height - (1.0 - 0.25), self.contentView.frame.size.wi
lineView.backgroundColor = [UIColor colorWithRed:(230.0/255.0f) green:(233/255.0f) blue:(237.0/255.0f) alpha:1.0f];
[self.contentView addSubview:lineView];
1
tooluser

La cellule dans Gist ci-dessous est une sous-classe UITableViewCell où chaque cellule pourrait avoir son propre séparateur avec plusieurs styles (actuellement, seuls les fichiers .None et .Default sont pris en charge). Il est écrit en Swift et suppose l’utilisation de Autolayout.

https://Gist.github.com/evgeniyd/fa36b6f586a5850bca3f

Comment utiliser la classe:

  1. définir le style de séparateur de l'objet UITableView sur UITableViewCellSeparatorStyle.None

    tableView.separatorStyle = .None
    
  2. Créer une sous-classe de MPSTableViewCell

  3. Quelque part dans awakeFromNib() définir le style de séparateur de cellule

Remarque: le code ci-dessous suppose que la cellule est chargée à partir de xib/storyboard.

    class FASWorkoutCell: FASTableViewCell {

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

     override func awakeFromNib() {
         super.awakeFromNib()

         separatorType = .Default
     }

     // ...

     }
1
Yevhen Dubinin

Version rapide:

private let kSeparatorTag = 123
private let kSeparatorHeight: CGFloat = 1.5

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
{
    if cell.viewWithTag(kSeparatorTag) == nil //add separator only once
    {
        let separatorView = UIView(frame: CGRectMake(0, cell.frame.height - kSeparatorHeight, cell.frame.width, kSeparatorHeight))
        separatorView.tag = kSeparatorId
        separatorView.backgroundColor = UIColor.redColor()
        separatorView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]

        cell.addSubview(separatorView)
    }
}
0
ChikabuZ

Si vous utilisez un UITableViewCell personnalisé, vous pouvez simplement ajouter UIView au bas du fichier UItableViewCell.xib et définir la couleur d'arrière-plan comme couleur de votre choix.

Par exemple, sur xib, j'ajoute UIView sur le bas et définit la hauteur sur 1. À l'aide de autolayout, je règle la contrainte de gauche sur 12, la contrainte de fond sur 0, la contrainte de droite sur 0 et la hauteur sur 1.

0
Kyle Ju