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?
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;
}
_ {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 .
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.
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:
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.
Vous devrez définir un cadre pour votre image. Le code non testé est
cell.imageView.frame = CGRectOffset(cell.frame, 10, 10);
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.
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
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.
Trois approches auxquelles je peux penser:
Créez une cellule de tableau personnalisée qui présente la vue de l'ensemble de la cellule comme vous le souhaitez
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
Cela a-t-il du sens?
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))
}
Exemple dans Swift 3 ..
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
}
}
Téléchargez le code source complet sur Github: lien
Je pense que c'est la solution la plus propre:
class MyTableViewCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
layoutMargins = UIEdgeInsetsMake(8, 0, 8, 0)
}
}
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
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.
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
Essayez de regarder dans - (UIEdgeInsets) layoutMargins; Sur la cellule
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!
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.
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
}
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
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É
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
:
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: