it-roy-ru.com

Как сделать пользовательский шрифт и цвет в UITableViewRowAction без раскадровки

У меня есть классический TableView, где вы можете удалить элемент, если вы проводите, а затем нажмите на кнопку. Я знаю, как установить пользовательский фон для ячейки, но не могу найти, как я могу установить собственный шрифт и цвет для этого.

Спасибо за помощь!

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]?  {

    var deleteAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, 
                   title: "Delete", 
                   handler: { 
                      (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
                           println("Delete button clicked!")
                   })

    deleteAction.backgroundColor = UIColor.redColor()

    return [deleteAction]
}
11
Vlastimil Fiser

Что ж, единственный способ установить собственный шрифт - использовать метод appearanceWhenContainedIn протокола UIAppearance. Этот метод еще не доступен в Swift, поэтому вы должны сделать это в Objective-C.

Я создал метод класса в служебном классе Objective-C, чтобы настроить его:

+ (void)setUpDeleteRowActionStyleForUserCell {

    UIFont *font = [UIFont fontWithName:@"AvenirNext-Regular" size:19];

    NSDictionary *attributes = @{NSFontAttributeName: font,
                      NSForegroundColorAttributeName: [UIColor whiteColor]};

    NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString: @"DELETE"
                                                                          attributes: attributes];

    /*
     * We include UIView in the containment hierarchy because there is another button in UserCell that is a direct descendant of UserCell that we don't want this to affect.
     */
    [[UIButton appearanceWhenContainedIn:[UIView class], [UserCell class], nil] setAttributedTitle: attributedTitle
                                                                                          forState: UIControlStateNormal];
}

Это работает, но это определенно не идеально. Если вы не включите UIView в иерархию содержания, то это также повлияет на индикатор раскрытия (я даже не подозревал, что индикатор раскрытия был подклассом UIButton). Кроме того, если в вашей ячейке есть кнопка UIB, которая находится внутри подпредставления в ячейке, то и эта кнопка будет затронута и этим решением.

Учитывая сложности, возможно, было бы лучше просто использовать одну из более настраиваемых библиотек с открытым исходным кодом для параметров прокрутки ячейки таблицы.

10
Logan Gauthier

Если вы используете иерархию отладочных представлений XCode для просмотра того, что происходит в UITableView, когда активны кнопки прокрутки, вы увидите, что элементы UITableViewRowAction преобразуются в кнопку с именем _UITableViewCellActionButton, содержащуюся в UITableViewCellDeleteConfirmationView. Один из способов изменить свойства кнопки - перехватить ее, когда она добавлена ​​в UITableViewCell. В своем производном классе UITableViewCell напишите что-то вроде этого:

private let buttonFont = UIFont.boldSystemFontOfSize(13)
private let confirmationClass: AnyClass = NSClassFromString("UITableViewCellDeleteConfirmationView")!

override func addSubview(view: UIView) {
    super.addSubview(view)

    // replace default font in swipe buttons
    let s = subviews.flatMap({$0}).filter { $0.isKindOfClass(confirmationClass) }
    for sub in s {
        for button in sub.subviews {
            if let b = button as? UIButton {
                b.titleLabel?.font = buttonFont
            }
        }
    }
}
2
apetrovic

Я хочу поделиться своим решением для ObjC, это всего лишь прием, но он работает, как и ожидалось. 

- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // this just convert view to `UIImage`
    UIImage *(^imageWithView)(UIView *) = ^(UIView *view) {

        UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
        [view.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image;
    };

    // This is where the magic happen,
    // The width and height must be dynamic (it's up to you how to implement it)
    // to keep the alignment of the label in place
    //
    UIColor *(^getColorWithLabelText)(NSString*, UIColor*, UIColor*) = ^(NSString *text, UIColor *textColor, UIColor *bgColor) {

        UILabel *lbDelete = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 47, 40)];
        lbDelete.font = [UIFont boldSystemFontOfSize:11];
        lbDelete.text = text;
        lbDelete.textAlignment = NSTextAlignmentCenter;
        lbDelete.textColor = textColor;
        lbDelete.backgroundColor = bgColor;

        return [UIColor colorWithPatternImage:imageWithView(lbDelete)];
    };

    // The `title` which is `@"   "` is important it 
    // gives you the space you needed for the 
    // custom label `47[estimated width], 40[cell height]` on this example
    //
    UITableViewRowAction *btDelete;
    btDelete = [UITableViewRowAction
                rowActionWithStyle:UITableViewRowActionStyleDestructive
                title:@"   "
                handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
                    NSLog(@"Delete");
                    [tableView setEditing:NO];
                }];
    // Implementation
    //
    btDelete.backgroundColor = getColorWithLabelText(@"Delete", [UIColor whiteColor], [YJColor colorWithHexString:@"fe0a09"]);

    UITableViewRowAction *btMore;
    btMore   = [UITableViewRowAction
                rowActionWithStyle:UITableViewRowActionStyleNormal
                title:@"   "
                handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
                    NSLog(@"More");
                    [tableView setEditing:NO];
                }];
    // Implementation
    //
    btMore.backgroundColor = getColorWithLabelText(@"More", [UIColor darkGrayColor], [YJColor colorWithHexString:@"46aae8"]);

    return @[btMore, btDelete];
}

[YJColor colorWithHexString:<NSString>]; просто для преобразования шестнадцатеричной строки в UIColor.

Проверьте пример выходного скриншота. 
 enter image description here

2
0yeoj

Кажется, это работает, по крайней мере, для установки цвета шрифта:

- (void)setupRowActionStyleForTableViewSwipes {
    UIButton *appearanceButton = [UIButton appearanceWhenContainedInInstancesOfClasses:@[[NSClassFromString(@"UITableViewCellDeleteConfirmationView") class]]];
    [appearanceButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
}
0
Alexandru