Dans mon tableau, j'ai défini une ligne de séparation entre les cellules. J'autorise la sélection de plusieurs cellules. Voici mon code pour définir la couleur d'arrière-plan de cellule sélectionnée:
UIView *cellBackgroundColorView = [[UIView alloc] initWithFrame:cell.frame];
[cellBackgroundColorView setBackgroundColor:[UIColor darkGray]];
[cell setSelectedBackgroundView:cellBackgroundColorView];
Le problème est que si deux cellules adjacentes sont sélectionnées, il n'y a pas de séparateur entre elles dans iOS7, alors qu'il y en a (comme prévu) dans iOS6.
J'ai même essayé de régler la hauteur du cadre de cellBackgroundColorView
à celle de cell.frame - 1.0
, mais cela ne fonctionne pas non plus.
Des idées?
Je n'ai pas encore tout compris (à première vue, cela ressemble à un bogue d'iOS 7 ..), mais j'ai trouvé une solution de contournement. Dans tableView: didSelectRowAtIndexPath, si vous envoyez les deux messages ci-dessous, le problème est résolu visuellement (avec le coût probable de la performance).
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
Pour que cela fonctionne (pour moi), désélectionnezRowAtIndexPath: animé: doit contenir animé: YES. L'animation utilisée pour reloadRowsAtIndexPaths: withRowAnimation: n'a pas d'importance.
Ajoutez ce code à la cellule pour la ligne à indexpath
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.backgroundColor = [UIColor clearColor];
dans mon cas, j'animais une ligne, donc il me fallait juste en mettre comme ceci:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView beginUpdates];
[tableView deselectRowAtIndexPath:indexPath animated:NO];
//if you are doing any animation you have deselect the row here inside.
[tableView endUpdates];
}
@ samvermette's answer a résolu le problème pour moi, mais je devais d'abord désélectionner la ligne sélectionnée.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //Deselect Row [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; // fix for separators bug in iOS 7 self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; }
J'ai rencontré ce problème lorsque je définissais le style de sélection de ma cellule sur aucun par programme, puis lorsque je sélectionnais mes cellules de tableau par programme.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell!
if tableView == self.jobLevelTableView {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath) as! CheckboxCell
// for testing purposes
let checked = true
// I used M13Checkbox here, in case anybody was wondering
cell.checkbox.setCheckState(checked ? .checked : .unchecked, animated: false)
if checked {
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
}
// CULPRIT
cell.selectionStyle = .none
return cell
}
cell = UITableViewCell()
return cell
}
Lorsque j'ai défini le style de sélection sur le storyboard (et en supprimant l'équivalent de code), le problème a disparu!
Cela semble toujours poser un problème depuis iOS 7.0.3, mais j’ai travaillé avec un moyen peu sophistiqué de simuler le séparateur.
En définissant d’abord le style de séparateur de UITableView
à UITableViewCellSeparatorStyleNone
. Vous pouvez ensuite utiliser une sous-classe UITableViewCell
personnalisée pour simuler le séparateur entre les cellules des états sélectionné et non sélectionné:
@implementation MyTableViewCellSubclass
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
CGRect frame = self.bounds;
frame.Origin.y = frame.size.height - 1.f;
frame.size.height = 1.f;
// Selected background view
//
UIView * separatorView = [[UIView alloc] initWithFrame:frame];
separatorView.backgroundColor = [UIColor darkGrayColor];
separatorView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin;
UIView * selectedView = [[UIView alloc] initWithFrame:self.bounds];
selectedView.backgroundColor = [UIColor lightGrayColor];
[selectedView addSubview:separatorView];
self.selectedBackgroundView = selectedView;
// Add separator view to content view for unselected state
//
UIView * separatorView2 = [[UIView alloc] initWithFrame:frame];
separatorView2.backgroundColor = [UIColor darkGrayColor];
separatorView2.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin;
[self.contentView addSubview:separatorView2];
}
return self;
}
@end
Ce simple appel s’est fait sur iOS 8.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// ....
[tableView deselectRowAtIndexPath:indexPath animated:YES]
// ....
}
Déposez-le dans votre classe UITableViewCell.
override func layoutSubviews() {
super.layoutSubviews()
subviews.forEach { (view) in
if type(of: view).description() == "_UITableViewCellSeparatorView" {
view.alpha = 1.0
}
}
}
Cela se produira si vous laissez iOS appliquer son propre style de cellule sélectionné par défaut. Le meilleur travail que j'ai trouvé jusqu'à présent consiste à remplacer la mise en œuvre de la propriété sélectionnée:
dans votre implémentation de sous-classe de cellule:
@synthesize selected = _selected;
dans la méthode d'initialisation:
// problem actually is caused when you set following
// to UITableViewCellSelectionStyleDefault, so:
[self setSelectionStyle:UITableViewCellSelectionStyleNone];
méthodes dominantes:
- (BOOL)selected
{
return _selected;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
_selected = selected
if (selected) {
// apply your own selected style
}
else {
// apply your own deselected style
}
}
J'ai résolu ce problème (hckishly) en rechargeant non seulement la cellule sélectionnée, mais également en rechargeant celle qui se trouvait juste au-dessus de celle-ci. Aucune des solutions ci-dessus n'a fonctionné pour moi.
NSIndexPath *indexPathOfCellAbove = [NSIndexPath indexPathForRow:(indexPath.row - 1) inSection:indexPath.section];
if (indexPath.row > 0)
[self.tableView reloadRowsAtIndexPaths:@[indexPathOfCellAbove, indexPath] withRowAnimation:UITableViewRowAnimationNone];
else
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
- cellForRowAtIndexPath
Create two separator views (sv1, sv2)
[cell addsubview:sv1];
[cell.selectedBackgroundView addsubview:sv2];
- didSelectRowAtIndexPath
[tableView deselectRowAtIndexPath:indexPath animated:NO];
Pour moi, c'est arrivé quand j'ai défini par programme:
cell.selectionStyle = UITableViewCellSelectionStyleNone;
Lorsque je définis cette propriété dans le storyboard, cela fonctionne bien.
utilisez ceci:
- (BOOL) tableView: (UITableView *) tableView shouldHighlightRowAtIndexPath: (NSIndexPath *) indexPath { UITableViewCell * cell = (UITableViewCell *) [tableView cellForRowAtIndexPath: indexPath]; UIView * selectionColor = [[UIView alloc] init]; selectionColor.backgroundColor = [UIColor clearColor]; cell.selectedBackgroundView = selectionColor; //71 UIView * separatorLineView = [[UIView alloc] initWithFrame: CGRectMake (0, 71, 320, 2)]; /// modifiez la taille à votre guise, où - coordonnée 71 - y, 320 - poids, 2 - hauteur. // separatorLineView.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @ "divider_goriz.png"]] //, vous pouvez également insérer une image ici separatorLineView.backgroundColor = [UIColor redColor]; [cell.selectedBackgroundView addSubview: separatorLineView]; retourner OUI; }
ce qui a résolu le problème pour moi, c'était de recharger les données après beginUpdates et endUpdates:
private func animateCellHeighChangeForTableView(tableView: UITableView, withDuration duration: Double) {
UIView.animateWithDuration(duration) { () -> Void in
tableView.beginUpdates();
tableView.endUpdates();
tableView.reloadData();
}
}
Les solutions ici ne m'ont pas aidé. Dans la plupart des cas, il a été proposé de supprimer la sélection, mais je voulais que les cellules conservent leur état sélectionné. L'idée est donc de désactiver la ligne de séparation par défaut et d'utiliser votre propre ligne de séparation. J'ai essayé cela mais j'ai eu des problèmes avec ça (vous pouvez en lire plus à ce sujet ici ). Le problème principal était de tracer la ligne dans la zone accessoryView
. Cela ne fonctionnait que sur iOS 8, mais j'avais également besoin d'une solution pour iOS 7.
Mes exigences étaient:
En particulier, le troisième point posait problème car iOS utilise une sorte d’effet anti-aliasing pour le passage de UITableViewCell
au suivant. Comme je l'ai découvert, cela ne se produit que sur iPad. Il a la taille d'environ un point dans chaque direction (cellule actuellement sélectionnée, cellule ci-dessus), de sorte qu'une ligne sur la cellule disparaît même si elle est dessinée sur la cellule elle-même (et non celle par défaut utilisée). Cela ne fait aucune différence si cette ligne est sur la cellule au-dessus ou sur la cellule sélectionnée. Cet effet de rendu spécial cache mes lignes.
La solution se présente comme suit:
backgroundView
où vous tracez deux lignes: une en haut (+1 point dans la direction y pour iPad et 0 en position y pour iPhone) et une en bas. Donc, il n'est jamais couvert par l'effet de sélection.cell.selectedBackgroundView = selectedBackground
). La ligne de séparation par défaut est activée pour les autres cellules.J'ai un exemple de travail avec le code C # posté ici bien que vous deviez l'adapter à vos besoins. Maintenant mes problèmes de sélection sont partis!
Trop excitant, j’ai résolu ce problème . Ajoutez l’appel de méthode suivant dans une cellule personnalisée et définissez le séparateur de couleur et le cadre. Je vais masquer le séparateur de cellules, puis personnaliser la vue sur un séparateur de charge dans Superview. La cellule de séparation d'impact est sélectionnée lorsque ce problème est résolu. Amis
@interface MyCustomTableViewCell(){
UIView *customSeparatorView;
CGFloat separatorHight;
}
@property (nonatomic,weak)UIView *originSeparatorView;
@end
-(void)setSeparatorWithInset:(UIEdgeInsets)insets{
if (customSeparatorView) {
customSeparatorView.frame = CGRectMake(insets.left, insets.top,self.width - insets.left - insets.right, self.originSeparatorView.height-insets.bottom - insets.top);
self.originSeparatorView.hidden = YES;
self.originSeparatorView.alpha = 0;
}else{
for (int i = ([self.contentView.superview.subviews count] - 1); i >= 0; i--) {
UIView *subView = self.contentView.superview.subviews[i];
if ([NSStringFromClass(subView.class) hasSuffix:@"SeparatorView"]) {
self.originSeparatorView = subView;
subView.hidden = YES;
subView.alpha = 0;
subView.frame = CGRectMake(insets.left, insets.top,self.width - insets.left - insets.right, subView.height-insets.bottom - insets.top);
customSeparatorView = [[subView superview] viewWithTag:separatorViewTag];
if (!customSeparatorView) {
customSeparatorView = [[UIView alloc] initWithFrame:subView.frame];
customSeparatorView.tag = separatorViewTag;
[[subView superview] addSubview:customSeparatorView];
customSeparatorView.backgroundColor = [subView backgroundColor];
}
[[subView superview] bringSubviewToFront:customSeparatorView];
break;
}
}
}
}
-(void)setSeparatorColorWithColor:(UIColor *)sepColor{
if (customSeparatorView) {
customSeparatorView.backgroundColor = sepColor;
self.originSeparatorView.hidden = YES;
self.originSeparatorView.alpha = 0;
}else {
for (int i = ([self.contentView.superview.subviews count] - 1); i >= 0; i--) {
UIView *subView = self.contentView.superview.subviews[i];
if ([NSStringFromClass(subView.class) hasSuffix:@"SeparatorView"]) {
self.originSeparatorView = subView;
if (sepColor) {
subView.hidden = YES;
subView.alpha = 0;
subView.backgroundColor = sepColor;
customSeparatorView = [[subView superview] viewWithTag:separatorViewTag];
if (!customSeparatorView) {
customSeparatorView = [[UIView alloc] initWithFrame:subView.frame];
customSeparatorView.tag = separatorViewTag;
[[subView superview] addSubview:customSeparatorView];
customSeparatorView.backgroundColor = [subView backgroundColor];
}
[[subView superview] bringSubviewToFront:customSeparatorView];
}
break;
}
}
}
}
-(void)layoutSubviews{
[super layoutSubviews];
[self setSeparatorWithInset:UIEdgeInsetsMake(0, 0, 0, 0)];
[self setSeparatorColorWithColor:[UIColor colorWithRed:31/255.0 green:32/255.0f blue:35/255.0 alpha:0.2]];
}
Ce problème existe également pour la sélection d'une seule cellule.
Une autre solution consiste à recharger la vue tableau, sélectionnez suivie de désélectionner:
self.selectedIndex = inIndexPath.row;
[inTableView reloadData];
[inTableView selectRowAtIndexPath:inIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[inTableView deselectRowAtIndexPath:inIndexPath animated:YES];
Cela supprime un problème de sélection graphique subtil que j'ai vu dans la solution de Mark.
J'avais besoin de ce qui suit:
"Lorsque l'utilisateur sélectionne une ligne, la couleur d'arrière-plan de la sélection est Transparente/blanche/comme vous pouvez l'appeler et les lignes de séparation ne le sont pas Disparaissent"
J'ai également cherché une solution au problème suivant:
"Lorsque je sélectionnais une ligne dans une table (table type simple), j'avais la sélection Couleur grise, et si je définissais cell.selectionStyle sur aucune -> Séparateurs Entre les cellules disparaissait."
Xcode - version 9.2
Trouvé la solution suivante:
let colorView = UIView(frame: CGRect(x: 0.0, y: 3.0, width:
cell.frame.width, height: cell.frame.height - 1.0))
colorView.backgroundColor = UIColor.white
UITableViewCellClass.appearance().selectedBackgroundView = colorView
UITableViewCellClass - est votre classe de cellules prototypeit permet de changer la couleur de sélection en blanc
dans 'tableView (... didSelectRowAt)' cell.selectionStyle = .none
dans UITableViewCellClass (votre classe de cellules prototype)
remplacez func layoutSubviews () { super.layoutSubviews ()
subviews.forEach { (view) in
if type(of: view).description() == "_UITableViewCellSeparatorView" {
view.alpha = 1.0
}
}
}
cela permet de garder la ligne sélectionnée avec une coche et tous les séparateurs sont en place.
Ce que j'ai fait était ceci:
Dans mon cas, je ne voulais pas du tout que mes lignes soient ombrées lors de la sélection. J'ai donc laissé la vue d'arrière-plan sélectionnée nette, mais vous pouvez la rendre de la couleur de votre choix.
De plus, je n'utilise pas l'autolayout, alors définissez mes tailles correctement. Je suppose qu'avec l'autolayout, vous devez définir des contraintes appropriées.
Pour moi, cela a complètement résolu le problème (bien que je convienne que cela semble vraiment être un bogue dans iOS 7).
cette solution n’aidera de toute façon personne qui n’utilise pas backgroundView sur ses cellules:
- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
[cell setBackgroundColor:[UIColor grayColor]];
}
de cette façon, l'effet visuel gênant est considérablement réduit sans avoir à recharger le tableau . bien sûr, vous pouvez changer grayColor
avec tout ce qui vous aide à améliorer le résultat dans votre cas
Vous pouvez également essayer de régler les incrustations de séparateur sur 0. Je l'ai fait et le problème a été résolu, mais le compromis est que vous perdez le joli aspect des incrustations.