Après de nombreuses années à éviter Interface Builder comme le fléau, j'ai décidé de lui donner une chance. Ce n'est pas facile.
Prenez UITableViewHeaderFooterView
par exemple. Comme UITableViewCell
, il a une propriété contentView
. Contrairement à UITableViewCell
, il n'y a pas de modèle dans la bibliothèque d'objets Interface Builder.
Comment sommes-nous censés utiliser Interface Builder pour créer une UITableViewHeaderFooterView
avec le contenu contenu dans contentView
? Le fait que registerNib:forHeaderFooterViewReuseIdentifier:
existe me fait penser que cela devrait être possible.
C’est ce qui me rapproche le plus pour définir une UITableViewHeaderFooterView
avec IB:
une. Créez une sous-classe UITableViewHeaderFooterView
(MYTableViewHeaderFooterView
).
b. Créez un fichier nib pour la contentView
uniquement (MYTableViewHeaderFooterContentView
).
c. Remplacez initWithReuseIdentifier:
dans MYTableViewHeaderFooterView
pour charger la vue définie dans le fichier nib.
- (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithReuseIdentifier:reuseIdentifier];
if (self)
{
NSArray* objects = [[NSBundle mainBundle] loadNibNamed:@"MYTableViewHeaderFooterView"
owner:self
options:nil];
UIView *nibView = [objects firstObject];
UIView *contentView = self.contentView;
CGSize contentViewSize = contentView.frame.size;
nibView.frame = CGRectMake(0, 0, contentViewSize.width, contentViewSize.height);
[contentView addSubview:nibView];
}
return self;
}
ré. Enregistrez la classe MYTableViewHeaderFooterView
au lieu du fichier nib:
[self.tableView registerClass:[MYTableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"cell"];
Je viens de faire cela avec un pied de page et un fichier NIB:
UITableViewHeaderFooterView
sur Par défaut .Dans votre UITableViewController viewDidLoad
, enregistrez le fichier NIB à utiliser avec un identifiant de réutilisation:
[self.tableView registerNib:[UINib nibWithNibName:@"CustomFooterView" bundle:nil] forHeaderFooterViewReuseIdentifier:@"Footer"];
Dans votre tableView:viewForFooterInSection:
de UITableViewController, utilisez l'identifiant de pied de page pour récupérer et renvoyer la vue:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
if (section == 2)
return [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"Footer"];
return nil;
}
Il suffit d'utiliser le UITableViewCell modèle dans IB. Changer la classe en UITableViewHeaderFooterView. Ici vous l'avez ... avec un contentView.
J'ai trouvé un moyen plus facile.
1) Créer une sous-classe de UITableViewCell et définir votre fichier xib
2) Dans votre fichier d'en-tête, changez la super-classe de UITableViewCell en UITableViewHeaderFooterView
C'est tout.
Cette solution fonctionne bien, en particulier si vous souhaitez qu'elle fonctionne correctement par rapport aux guides de contenu lisible (introduits dans iOS 9). Au lieu de créer un UITableViewHeaderFooterView, il renvoie simplement un UIView personnalisé (à partir d'un XIB) lorsqu'il est requis:
Créez une nouvelle classe qui sous-classe UIView ("AwesomeHeaderView") et créez vos points de vente:
class AwesomeHeaderView: UIView {
@IBOutlet var myCustomLabel: UILabel!
}
Dans votre UIViewController (ou UITableViewController), appelez ce qui suit:
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
guard let headerView = NSBundle.mainBundle().loadNibNamed("MyNewHeader", owner: nil, options: nil).first as? AwesomeHeaderView else {
return nil
}
// configure header as normal
headerView.backgroundColor = UIColor.redColor()
headerView.myCustomLabel.textColor = UIColor.whiteColor()
headerView.myCustomLabel.text = "Hello"
return header
}
Les solutions de contournement suivantes me permettent de glisser-assigner des éléments IB au code en tant que variables. UITableViewHeaderFooterView n'autorise pas cela par défaut.
créer un (Nouveau fichier/CocoaTouchClass) UITableViewHeaderFooterView . h.m.xib normalement
temporairementrenommer la superclassede UITableViewHeaderFooterView en UIView. Glissez-attribuez vos éléments d'interface utilisateur au code selon vos besoins, IB affectera la valeur-clé .__ correctement, revenez à UITableViewHeaderFooterView lorsque vous avez terminé.
J'ai également rencontré l'avertissement de désapprobation ci-dessus et une incapacité à définir la couleur d'arrière-plan, etc. Finalement, j'ai constaté que, selon la documentation d'Apple,
Vous pouvez utiliser la classe [the UITableViewHeaderFooter] en l’état sans sous-classement dans la plupart des cas. Si vous avez un contenu personnalisé à afficher, créez les sous-vues pour votre contenu et ajoutez-les à la vue dans la propriété contentView.
Suite à cette suggestion, j'ai pris les mesures suivantes:
Dans viewDidLoad, j'ai enregistré la classe UITableViewHeaderFooter intégrée.
tableView.registerClass (UITableViewHeaderFooterView.self, pourHeaderFooterViewReuseIdentifier: "sectionHeader")
Dans le délégué viewForHeaderInSection de mon UITableViewController, j'ai retiré la vue en-tête de cet identifiant et vérifié si cette vue contenait déjà une sous-vue. Sinon, je charge mon xib et l'ajoute. Ensuite, je règle mon texte au besoin.
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = self.tableView.dequeueReusableHeaderFooterViewWithIdentifier("sectionHeader")!
if header.contentView.subviews.count == 0 { header.contentView.addSubview(loadMyNib()) }
let myView = header.contentView.subviews[0] as! MyView
myView.label.text = "..."
Cela semble fonctionner, optimise la réutilisation et ne produit aucun avertissement.
Je me suis dit que je devais créer une classe IBOutlet contentView dans votre classe headerFooter et la relier à votre "vue du contenu" dans la bibliothèque xib (placez votre xib comme une tableViewCell, View-> contentView-> mystuff).
Vous aurez des avertissements, ok prêt pour le hack ...
Supprimez l'IBOutlet et tout fonctionnera.