J'utilise UITableViewRowAction dans la méthode "editActionsForRowAtIndexPath". Je peux changer la couleur de fond de UITableViewRowAction, mais je ne peux pas changer la couleur du titre. Mais je voudrais changer la couleur de UITableViewRowAction. Toute contribution à cet égard sera appréciable.
Je crains qu'il n'y ait aucun moyen de changer la couleur du titre de UITableViewRowAction.
Les seules choses que vous pouvez changer dans l'action sont:
Pour plus d'informations, reportez-vous au Apple Doc UITableViewRowAction
Il existe un moyen d’atteindre ce que vous recherchez. Mais c'est quand même un peu délicat.
Exemple de résultat:
L'idée de cette astuce est que vous pouvez réellement modifier la couleur de fond. Cela signifie que vous pouvez définir + colorWithPatternImage: de UIColor et définir une image bitmap correspondant au style souhaité. Cela peut être réalisé soit en créant une image à l'aide de l'éditeur graphique, soit en la rendant à l'aide, par exemple, de Core Graphics. Le seul problème avec cette solution est que vous devez imiter la longueur du titre original avec vos attributs de texte spécifiques pour le faire fonctionner correctement et vous devez également définir le titre de l'action de ligne de la vue tableau sous la forme d'une chaîne d'espaces blancs afin que la cellule de la vue tableau se prépare suffisamment espace pour vous "bouton d'action personnalisé". La création d'actifs png statiques dans photoshop peut être inappropriée si vous utilisez des lignes de cellules variables.
C'est la catégorie pour NSString qui crée une chaîne d'espaces vides qui créeront un espace pour votre bouton personnalisé et la seconde générera une image bitmap qui sera placée en tant qu'image de modèle d'arrière-plan. Pour les paramètres, vous devez définir des attributs de texte pour le titre d'origine, c'est-à-dire @{NSFontAttributeName: [UIFont systemFontOfSize:18]}
, plutôt que pour les attributs de texte souhaités. Peut-être y a-t-il un meilleur moyen d'y parvenir :)
@implementation NSString (WhiteSpace)
- (NSString *)whitespaceReplacementWithSystemAttributes:(NSDictionary *)systemAttributes newAttributes:(NSDictionary *)newAttributes
{
NSString *stringTitle = self;
NSMutableString *stringTitleWS = [[NSMutableString alloc] initWithString:@""];
CGFloat diff = 0;
CGSize stringTitleSize = [stringTitle sizeWithAttributes:newAttributes];
CGSize stringTitleWSSize;
NSDictionary *originalAttributes = systemAttributes;
do {
[stringTitleWS appendString:@" "];
stringTitleWSSize = [stringTitleWS sizeWithAttributes:originalAttributes];
diff = (stringTitleSize.width - stringTitleWSSize.width);
if (diff <= 1.5) {
break;
}
}
while (diff > 0);
return [stringTitleWS copy];
}
@end
La deuxième partie importante est le code qui rend l'image bitmap qui peut être utilisée comme image de modèle pour backgroundColor de UITableViewRowAction.
- (UIImage *)imageForTableViewRowActionWithTitle:(NSString *)title textAttributes:(NSDictionary *)attributes backgroundColor:(UIColor *)color cellHeight:(CGFloat)cellHeight
{
NSString *titleString = title;
NSDictionary *originalAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:18]};
CGSize originalSize = [titleString sizeWithAttributes:originalAttributes];
CGSize newSize = CGSizeMake(originalSize.width + kSystemTextPadding + kSystemTextPadding, originalSize.height);
CGRect drawingRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, cellHeight));
UIGraphicsBeginImageContextWithOptions(drawingRect.size, YES, [UIScreen mainScreen].nativeScale);
CGContextRef contextRef = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(contextRef, color.CGColor);
CGContextFillRect(contextRef, drawingRect);
UILabel *label = [[UILabel alloc] initWithFrame:drawingRect];
label.textAlignment = NSTextAlignmentCenter;
label.attributedText = [[NSAttributedString alloc] initWithString:title attributes:attributes];
[label drawTextInRect:drawingRect];
//This is other way how to render string
// CGSize size = [titleString sizeWithAttributes:attributes];
// CGFloat x = (drawingRect.size.width - size.width)/2;
// CGFloat y = (drawingRect.size.height - size.height)/2;
// drawingRect.Origin = CGPointMake(x, y);
// [titleString drawInRect:drawingRect withAttributes:attributes];
UIImage *returningImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return returningImage;
}
Et ensuite, lorsque vous créez votre action de rangée, vous pouvez faire quelque chose comme ceci:
NSDictionary *systemAttributes = @{ NSFontAttributeName: [UIFont systemFontOfSize:18] };
NSDictionary *newAttributes = @{NSFontAttributeName: [UIFont fontWithName:@"Any font" size:15]};
NSString *actionTitle = @"Delete";
NSString *titleWhiteSpaced = [actionTitle whitespaceReplacementWithSystemAttributes:systemTextFontAttributes newAttributes:newAttributes];
UITableViewRowAction *rowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:titleWhiteSpaced handle:NULL];
UIImage *patternImage = [self imageForTableViewRowActionWithTitle:actionTitle textAttributes:newAttributes backgroundColor:[UIColor redColor] cellHeight:50];
rowAction.backgroundColor = [UIColor colorWithPatternImage:patternImage];
Cette solution est évidemment astucieuse, mais vous pouvez obtenir les résultats souhaités sans utiliser d'API privée et, à l'avenir, en cas de problème, votre application ne sera pas endommagée. Seul le bouton semblera inapproprié.
Exemple de résultat:
Ce code a bien sûr beaucoup de place pour des améliorations, toutes les suggestions sont les bienvenues.
Rapide
Pas besoin de jouer avec UIButton.appearance ...
Mettez ceci dans votre classe de cellules et changez le bouton d'action UITableViewCell en fonction de vos besoins.
override func layoutSubviews() {
super.layoutSubviews()
for subview in self.subviews {
for subview2 in subview.subviews {
if (String(subview2).rangeOfString("UITableViewCellActionButton") != nil) {
for view in subview2.subviews {
if (String(view).rangeOfString("UIButtonLabel") != nil) {
if let label = view as? UILabel {
label.textColor = YOUR COLOUR
}
}
}
}
}
}
}
Il existe en effet un moyen de changer la couleur du titre de UITableViewRowAction. C'est un bouton. Vous pouvez utiliser le proxy d'apparence UIButton
:
[[UIButton appearance] setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
Réponse de Lee Andrew in Swift 3/Swift 4:
class MyCell: UITableViewCell {
override func layoutSubviews() {
super.layoutSubviews()
for subview in self.subviews {
for sub in subview.subviews {
if String(describing: sub).range(of: "UITableViewCellActionButton") != nil {
for view in sub.subviews {
if String(describing: view).range(of: "UIButtonLabel") != nil {
if let label = view as? UILabel {
label.textColor = UIColor.black
}
}
}
}
}
}
}
}
Vous pouvez ajouter ces deux fonctions dans votre sous-classe UITableViewCell
et appeler la fonction setActionButtonsTitleColor
pour définir la couleur de titre des boutons d'action.
func setActionButtonsTitleColor(color: UIColor) {
let actionButtons: [UIButton] = self.getActionButtons()
for actionButton in actionButtons {
actionButton.setTitleColor(color, for: .normal)
}
}
func getActionButtons() -> [UIButton] {
let actionButtons: [UIButton] = self.subviews.map {
(view: UIView) -> [UIView] in
return view.subviews
}
.joined()
.filter {
(view: UIView) -> Bool in
return String(describing: view).contains("UITableViewCellActionButton")
}.flatMap {
(view: UIView) -> UIButton? in
return view as? UIButton
}
return actionButtons
}
iOS 11 solution:
Créez une extension UITableViewCell
comme ceci:
extension UITableViewCell {
/// Returns label of cell action button.
///
/// Use this property to set cell action button label color.
var cellActionButtonLabel: UILabel? {
for subview in self.superview?.subviews ?? [] {
if String(describing: subview).range(of: "UISwipeActionPullView") != nil {
for view in subview.subviews {
if String(describing: view).range(of: "UISwipeActionStandardButton") != nil {
for sub in view.subviews {
if let label = sub as? UILabel {
return label
}
}
}
}
}
}
return nil
}
}
Et écrivez ceci dans votre UITableViewCell
override func layoutSubviews() {
super.layoutSubviews()
cellActionButtonLabel?.textColor = .red
}
Mais il y a un bug - si vous tirez la cellule rapidement ce code ne change parfois pas la couleur.
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewRowAction *editAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"edit" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// Action something here
}];
editAction.backgroundColor = [UIColor whiteColor];
[[UIButton appearance] setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
return @[editAction];
SI quelqu'un cherche toujours une solution alternative:
Vous pouvez utiliser le pod swipecellkit
https://github.com/SwipeCellKit/SwipeCellKit
Cela vous permet de personnaliser la couleur de l'étiquette, la couleur de l'image et même tout l'arrière-plan tout en préservant l'apparence réelle de la mise en œuvre native.