Изменить значок по умолчанию для перемещения ячеек в UITableView - PullRequest
33 голосов
/ 22 декабря 2011

Мне нужно изменить значок по умолчанию для перемещения ячеек в UITableView.

Вот этот:

enter image description here

Возможно ли это?

Ответы [ 10 ]

54 голосов
/ 22 декабря 2011

Это действительно хакерское решение, и оно может не работать долго, но может дать вам отправную точку. Элемент управления повторного заказа - UITableViewCellReorderControl, но это закрытый класс, поэтому вы не можете получить к нему доступ напрямую. Однако вы можете просто просмотреть иерархию подпредставлений и найти ее imageView.

Вы можете сделать это, создав подкласс UITableViewCell и переопределив его метод setEditing:animated: следующим образом:

- (void) setEditing:(BOOL)editing animated:(BOOL)animated
{
    [super setEditing: editing animated: YES];

    if (editing) {

        for (UIView * view in self.subviews) {
            if ([NSStringFromClass([view class]) rangeOfString: @"Reorder"].location != NSNotFound) {
                for (UIView * subview in view.subviews) {
                    if ([subview isKindOfClass: [UIImageView class]]) {
                        ((UIImageView *)subview).image = [UIImage imageNamed: @"yourimage.png"];
                    }
                }
            }
        }
    }   
}

Или в Свифте

override func setEditing(_ editing: Bool, animated: Bool) {
    super.setEditing(editing, animated: animated)

    if editing {
        for view in subviews where view.description.contains("Reorder") {
            for case let subview as UIImageView in view.subviews {
                subview.image = UIImage(named: "yourimage.png")
            }
        }
    }
}

Имейте в виду, что ... это не может быть долгосрочным решением, поскольку Apple может изменить иерархию представлений в любое время.

13 голосов
/ 06 сентября 2014

Ответ Эшли Миллс был превосходным в то время, когда он был предложен, но, как другие отмечали в комментариях, иерархия представлений менялась от версии к версии iOS.Чтобы правильно найти элемент управления переупорядочением, я использую подход, который пересекает всю иерархию представлений;надеюсь, что это даст подходу возможность продолжить работу, даже если Apple изменит иерархию представлений.

Вот код, который я использую для поиска элемента управления переупорядочением:

-(UIView *) findReorderView:(UIView *) view
{
    UIView *reorderView = nil;
    for (UIView *subview in view.subviews)
    {
        if ([[[subview class] description] rangeOfString:@"Reorder"].location != NSNotFound)
        {
            reorderView = subview;
            break;
        }
        else
        {
            reorderView = [self findReorderView:subview];
            if (reorderView != nil)
            {
                break;
            }
        }
    }
    return reorderView;
}

А воткод, который я использую для переопределения метода -(void) setEditing:animated: в моем подклассе:

-(void) setEditing:(BOOL)editing animated:(BOOL)animated
{
    [super setEditing:editing animated:animated];
    if (editing)
    {
        // I'm assuming the findReorderView method noted above is either
        // in the code for your subclassed UITableViewCell, or defined
        // in a category for UIView somewhere
        UIView *reorderView = [self findReorderView:self];
        if (reorderView)
        {
            // I'm setting the background color of the control
            // to match my cell's background color
            // you might need to do this if you override the
            // default background color for the cell
            reorderView.backgroundColor = self.contentView.backgroundColor;
            for (UIView *sv in reorderView.subviews)
            {
                // now we find the UIImageView for the reorder control
                if ([sv isKindOfClass:[UIImageView class]])
                {
                    // and replace it with the image we want
                    ((UIImageView *)sv).image = [UIImage imageNamed:@"yourImage.png"];
                    // note:  I have had to manually change the image's frame
                    // size to get it to display correctly
                    // also, for me the origin of the frame doesn't seem to
                    // matter, because the reorder control will center it
                    sv.frame = CGRectMake(0, 0, 48.0, 48.0);
                }
            }
        }
    }
}
6 голосов
/ 26 мая 2016

Swift версия ответа Рика с несколькими улучшениями:

override func setEditing(editing: Bool, animated: Bool) {
    super.setEditing(editing, animated: animated)

    if editing {
        if let reorderView = findReorderViewInView(self), 
            imageView = reorderView.subviews.filter({ $0 is UIImageView }).first as? UIImageView {
            imageView.image = UIImage(named: "yourImage")
        }
    }
}

func findReorderViewInView(view: UIView) -> UIView? {
    for subview in view.subviews {
        if String(subview).rangeOfString("Reorder") != nil {
            return subview
        }
        else {
            findReorderViewInView(subview)
        }
    }
    return nil
}
5 голосов
/ 06 ноября 2013

Обновленное решение Ashley Mills (для iOS 7.x)

if (editing) {
    UIView *scrollView = self.subviews[0];
    for (UIView * view in scrollView.subviews) {
        NSLog(@"Class: %@", NSStringFromClass([view class]));
        if ([NSStringFromClass([view class]) rangeOfString: @"Reorder"].location != NSNotFound) {
            for (UIView * subview in view.subviews) {
                if ([subview isKindOfClass: [UIImageView class]]) {
                    ((UIImageView *)subview).image = [UIImage imageNamed: @"moveCellIcon"];
                }
            }
        }
    }
}
4 голосов
/ 13 сентября 2018

Свифт 4

   // Change default icon (hamburger) for moving cells in UITableView
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        let imageView = cell.subviews.first(where: { $0.description.contains("Reorder") })?.subviews.first(where: { $0 is UIImageView }) as? UIImageView

        imageView?.image = #imageLiteral(resourceName: "new_hamburger_icon") // give here your's new image
        imageView?.contentMode = .center

        imageView?.frame.size.width = cell.bounds.height
        imageView?.frame.size.height = cell.bounds.height
    }
4 голосов
/ 28 октября 2014

Я использую editAccessoryView для замены значка переупорядочения.

  1. Создание подкласса UITableViewCell.
  2. Переопределение setEditing.Просто скройте элемент управления переупорядочением и установите для editAccessoryView вид uiimageview с вашим изображением переупорядочения.
 - (void) setEditing:(BOOL)editing animated:(BOOL)animated
{

    [super setEditing: editing animated: YES];

    self.showsReorderControl = NO;

    self.editingAccessoryView = editing ? [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"yourReorderIcon"]] : nil;

}

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

4 голосов
/ 22 декабря 2011
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    for (UIControl *control in cell.subviews)
    {       
        if ([control isMemberOfClass:NSClassFromString(@"UITableViewCellReorderControl")] && [control.subviews count] > 0)
        {           
            for (UIControl *someObj in control.subviews)
            {
                if ([someObj isMemberOfClass:[UIImageView class]])
                {
                    UIImage *img = [UIImage imageNamed:@"reorder_icon.png"];
                    ((UIImageView*)someObj).frame = CGRectMake(0.0, 0.0, 43.0, 43.0);
                    ((UIImageView*)someObj).image = img;
                }
            }
        }
    }   
}
1 голос
/ 06 июля 2019

После отладки UITableViewCell вы можете использовать KVC в подклассе UITableViewCell, чтобы изменить его.

// key
static NSString * const kReorderControlImageKey = @"reorderControlImage";

// setting when cellForRow calling
UIImage *customImage;
[self setValue:customImage forKeyPath:kReorderControlImageKey];

// to prevent crash
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
    if ([key isEqualToString:kReorderControlImageKey]) return;
    else [super setValue:value forUndefinedKey:key];
}
0 голосов
/ 09 апреля 2019

Я сделал это на iOS 12 с swift 4.2

Надеюсь, это поможет:

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        for view in cell.subviews {
            if view.self.description.contains("UITableViewCellReorderControl") {
                for sv in view.subviews {
                    if (sv is UIImageView) {
                        (sv as? UIImageView)?.image = UIImage(named: "your_image")
                        (sv as? UIImageView)?.contentMode = .center
                        sv.frame = CGRect(x: 0, y: 0, width: 25, height: 25)
                    }
                }
            }
        }
    }
0 голосов
/ 29 марта 2012

Вы также можете просто добавить свой собственный вид переупорядочения над всеми остальными внутри своей ячейки.

Все, что вам нужно сделать, это убедиться, что этот пользовательский вид всегда над другими, что можно проверить в [UITableViewDelegate tableView: willDisplayCell: forRowAtIndexPath: indexPath:].

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

В зависимости от того, как выглядит ваша ячейка, вам может потребоваться более или менее сложныйпользовательский вид переупорядочения (для имитации фона ячейки для примера).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...