J'ai un groupe UITableview qui est créé par programme. De plus, une cellule avec un fichier xib est également renseignée par programme dans tableview. Jusqu'ici tout va bien. Mais je veux supprimer uniquement la ligne de séparation externe. J'ai utilisé le code ci-dessous, mais cette fois, j'ai supprimé toute la ligne de séparation.
self.tableView.separatorColor = [UIColor clearColor];
ce n'est pas une bonne option pour ma situation. Voici la capture d'écran de ce que je veux faire;
Après avoir inspecté la hiérarchie des vues, il semble que chaque UITableViewCell ne possède que trois sous-vues: la vue de contenu (UITableViewCellContentView
) et deux vues de séparation (_UITableViewCellSeparatorView
). Je ne suis pas un fan de l'instanciation dynamique de classe de NSStrings (et Apple non plus ????). Cependant, étant donné que la contentView
d'une UITableViewCell
est accessible sans utiliser d'API privée, la solution s'avère assez simple.
L'idée est simplement de parcourir les sous-vues de votre UITableViewCell
et de supprimer toutes les vues qui ne sont pas la contentView
:
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
let subviews = cell.subviews
if subviews.count >= 3 {
for subview in subviews {
if subview != cell.contentView {
subview.removeFromSuperview()
break
}
}
}
}
tableView(:willDisplayCell:forRowAtIndexPath:)
est appelé plusieurs fois lors du rendu de la vue table. Par conséquent, la procédure ci-dessus garde trace de l'état en vérifiant le nombre de sous-vues de la cellule. S'il comporte trois sous-vues, les deux séparateurs sont toujours intacts. En outre, il supprime uniquement l'un des séparateurs, mais vous pouvez supprimer les deux en supprimant la variable break
. Vous pouvez également spécifier si vous souhaitez supprimer le séparateur supérieur ou inférieur en vérifiant le cadre de la sous-vue. Si l'origine de l'axe des y de l'image est 0
, c'est le séparateur supérieur. Si ce n'est pas 0
, c'est le fond.
J'espère que cela t'aides!
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let subviews = cell.subviews
guard subviews.count >= 3 else {
return
}
for subview in subviews where NSStringFromClass(subview.classForCoder) == "_UITableViewCellSeparatorView" {
subview.removeFromSuperview()
}
}
Vous pouvez supprimer des séparateurs même dans UITableView groupé avec une cellule statique:
class Cell: UITableViewCell {
override func layoutSubviews() {
super.layoutSubviews()
for view in subviews where view != contentView {
view.removeFromSuperview()
}
}
Même en 2018, Google sert cette page comme premier résultat de cette question. Je n'ai eu aucune chance dans iOS 11 avec l'une des réponses fournies, alors voici ce que je suis venu avec:
extension UITableViewCell {
func removeSectionSeparators() {
for subview in subviews {
if subview != contentView && subview.frame.width == frame.width {
subview.removeFromSuperview()
}
}
}
}
L'appel de .removeSectionSeparators () sur n'importe quelle instance UITableViewCell résoudra le problème. Dans mon cas au moins, les séparateurs de section sont les seuls avec la même largeur que la cellule elle-même (les autres sont tous en retrait).
La seule question qui reste est de savoir comment nous devrions l'appeler. On pourrait penser que willDisplayCell serait le meilleur choix, mais j'ai découvert que l'appel initial avait lieu avant que les vues de séparation ne soient générées, donc pas de dés.
J'ai fini par mettre cela dans ma méthode cellForRowAtIndexPath juste avant de retourner une cellule rechargée:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyReusableIdentifier", for: indexPath)
Timer.scheduledTimer(withTimeInterval: 0.15, repeats: false) { (timer) in
cell.removeSectionSeparators()
}
return cell
}
Cela ne me semble pas si élégant, mais je n’ai encore rencontré aucun problème.
EDIT: On dirait que nous avons aussi besoin de ça (pour les cellules réutilisées):
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.removeSectionSeparators()
}
Voici un avant/après dans les screenshots avec ce code:
Je viens juste de trouver une solution car la cellule a contentView
qui est une UIView
, je pense donc que vous pouvez vous concentrer sur le résultat inférieur de contentView
.
Voici mon code:
d'abord, vous devez faire le séparateur pour effacer
tableView.separatorColor = UIColor.clear
Deuxièmement, dans la fonction cellForRowAt
:
let bottomBorder = CALayer()
bottomBorder.frame = CGRect(x: 0.0, y: 43.0, width: cell.contentView.frame.size.width, height: 1.0)
bottomBorder.backgroundColor = UIColor(white: 0.8, alpha: 1.0).cgColor
cell.contentView.layer.addSublayer(bottomBorder)
ici, vous verrez l'interface utilisateur comme ceci:
C’est une question très ancienne, mais c’est l’une des premières entrées de Google lorsqu’on cherche à savoir comment supprimer les séparateurs supérieur et inférieur de chaque section.
Après une enquête, j'ai découvert qu'il n'y avait aucun moyen ni aucune intention d'Apple de faire en sorte que cela se produise d'une manière ou d'une autre sans complication stupide de la hiérarchie des points de vue.
Heureusement, il existe un moyen absolument simple et facile d'obtenir un tel look:
Je dis simple mais pour un débutant, cela pourrait être difficile en raison d’un manque de compréhension de la manière dont fonctionne UITableView
et de la mise en oeuvre de vos propres cellules. Laissez-moi essayer de l'expliquer:
UITableViewCell
@IBOutlet weak var separatorView: UIView!
UITableView
s Separator Style
sur None
pour masquer le séparateur par défautUIView
sur votre cellule et redimensionnez-la afin qu'elle se trouve en bas (ou en haut) de la cellule. Utilisez le Size Inspector
s Autoresizing
pour le fixer au début/à la fin/en bas et donnez-lui une largeur de flex (ou Autolayout mais c'est juste au-dessus dans le cas présent)UITableViewDataSource
s cellForRowAtIndexPath:
, définissez la propriété isHidden
de votre séparateur personnalisé selon que le indexPath.row
est la dernière ligne (ou la première, si votre vue se trouve en haut) de la section.Voici un exemple de code:
class MyCell: UITableViewCell {
@IBOutlet weak var separatorView: UIView!
}
class ViewController: UITableViewController {
override func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MyCell
cell.separatorView.isHidden = indexPath.row == 2
return cell
}
}
Et voici quelques captures d'écran:
Oui, c'est du travail, mais il n'y a pas moyen de faire quelque chose de gratuit lors du codage. En fin de compte, nous sommes des programmeurs et c'est à nous de faire le codage. Il est toujours préférable de passer les 5 à 10 minutes à configurer ceci plutôt que de simplement coller du code hacky qui pourrait ne pas continuer à fonctionner à l'avenir lorsque Apple décidera de modifier la hiérarchie des vues.
En fait, cette réponse nécessitait plus de travail que la mise en œuvre du séparateur. Moi aussi, je cherchais une solution facile et rapide, mais au final, il n’en restait pas une assez bonne qui, à mon avis, valait la peine d’être utilisée.
J'espère que vous vous sentez également sceptique lorsque vous voyez des boucles répétées itérer sur des sous-vues de cellules pour masquer ou même supprimer des vues au moment de l'exécution de la hiérarchie des vues fournie par Apple, lorsqu'il existe une solution simple, polyvalente, stable et évolutive . 7 petites étapes suffisent vraiment et elles sont faciles à comprendre.
Voici ce que j'ai finalement trouvé:
Je n'ai pas été en mesure de trouver un meilleur moyen que celui-ci. Mais cela fonctionne beaucoup pour moi. Dernière tentative avec Xcode Version 7.3.1 (7D1014). Cette procédure a été réalisée via le storyboard.
Fondamentalement, j'ajoute une vue UIView de 0,5 pt de hauteur sur UITableViewCell, puis une couleur d'arrière-plan pour cette vue UIView. Définissez le séparateur de UITableView parent sur Aucun.
Voici les détails:
En considérant que vous avez déjà défini votre UITableViewCell, custom ou default. À la toute première étape, définissez le séparateur de UITableView sur Aucun.
Ensuite, ajoutez une vue UIV de 1 pt de hauteur et définissez le fond comme vous le souhaitez. Dans mon cas, il s'agit du rouge.
Commencez à définir les contraintes. Le problème est de définir la hauteur de UIView à 0.5 pt. C'est le seul problème qui pose problème pour ce flux de travail.
Partage de la manière de définir une hauteur de 0,5 pt de UIView.
D'abord (1) épinglez la vue puis (2) définissez la hauteur sur 0.5. Appuyez sur Entrée.
Enfin, votre UIView ressemblera à ce qui suit.
Je n'ai pas pu régler la hauteur à 0,5 autrement que de cette façon.
Voici la solution. Ceci est pour les cellules statiques. Si vous voulez dynamique, il suffit de réécrire "count". J'espère que ça aide.
extension NSObject {
var theClassName: String {
return NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last!
}
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.separatorStyle = .None
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
let count = tableView.numberOfRowsInSection(indexPath.section)
if ( indexPath.row != count - 1 ) {
for view in cell.subviews {
if view.theClassName == "_UITableViewCellSeparatorView" {
view.backgroundColor = UIColors.redColor()
}
}
}
}
Essayé diverses solutions basées sur la solution de contournement cell.separatorInset = UIEdgeInsetsMake()
, aucune d’entre elles ne fonctionnant correctement.
Pour mon projet iOS11 UITableViewStyleGrouped
, cela s’est avéré efficace:
self.tableView.separatorColor = self.tableView.backgroundColor;
Basé sur la réponse du cuisinier, mais sans minuterie:
override func didAddSubview(_ subview: UIView) {
super.didAddSubview(subview)
if NSStringFromClass(subview.classForCoder) != "UITableViewCellContentView" && subview.frame.width == frame.width {
subview.removeFromSuperview()
}
}
Ajoutez simplement ceci dans la sous-classe d'une cellule et vous n'avez besoin de rien d'autre. Fonctionne sur iOS 12.
Essayez ceci, il supprimera la ligne de séparation supérieure.
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == 0 && indexPath.section == 0) {
for (UIView *view in cell.subviews) {
if ([NSStringFromClass([view class]) containsString:@"CellSeparator"]) {
if (view.frame.Origin.y == 0 && CGRectGetHeight(view.frame) < 1.01 ) { //Hide first UITableViewCellSeparatorView
NSLog(@"%s Remove View From Cell[Section:0 Row:0] for top border [%@]:%@",__FUNCTION__,NSStringFromClass([view class]),view);
view.hidden = YES; //Hide
}
}
}
}
}
Pour supprimer les parties supérieure et inférieure de la ligne de séparation pour chaque section. Ajoutez ceci à votre cellule statique.
override func layoutSubviews() {
super.layoutSubviews()
//Get the width of tableview
let width = subviews[0].frame.width
for view in subviews where view != contentView {
//for top and bottom separator will be same width with the tableview width
//so we check at here and remove accordingly
if view.frame.width == width {
view.removeFromSuperview()
}
}
}
Résultat comme ci-dessous image
Vous pouvez accéder à la vue en utilisant
override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
let header = view as! UITableViewHeaderFooterView
header.backgroundView . .....
J'ai eu un problème similaire, où j'avais un Groupable UITableView avec des cellules personnalisées, tous conçus avec Interface Build en tant que fichiers .xib. Les cellules avaient des fonds blancs, supprimaient les séparateurs par défaut et ajoutaient les miens. J'avais aussi des vues d'en-tête personnalisées pour chaque section. Je règle la hauteur de ces vues d'en-tête à 44 (peut être n'importe quoi ...). Il y avait une vue en hauteur de 1 point entre mes sections, ce qui semblait bizarre. Apparemment, le système ajoute une vue d’arrière-plan claire entre les sections, même si nous spécifions une hauteur personnalisée, disons 44, et que la vue en-tête personnalisée que nous renvoyons a un blanc (ou une couleur d’arrière-plan concrète). La couleur que nous voyons derrière cette vue dégagée est en réalité la couleur de l'arrière-plan de la vue Tableau. Dans mon cas, les vues de tableau et les cellules devaient être de couleur blanche et définir le fond de la vue de table en blanc résolvait le problème (au moins visuellement, mais c'est ce que je voulais quand même). La deuxième solution consisterait à conserver le style de la vue Table à l’unis, mais à implémenter la méthode de délégué UITableView pour renvoyer 2 sections ou plus, et à créer également des en-têtes personnalisés, le cas échéant. Mais cela fera que les vues d’en-tête resteront collées au sommet pendant un certain temps (lors du défilement), jusqu’à ce que la vue d’en-tête de la section suivante se rapproche de celle-ci, puis elle commence à remonter aussi peut être un moyen facile de résoudre ce problème, pas sûr cependant).