ios 更改 UITableView 中移动单元格的默认图标

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8603359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:00:05  来源:igfitidea点击:

Change default icon for moving cells in UITableView

iosuitableview

提问by devgeek

I need to change default icon for moving cells in UITableView.

我需要更改用于在 UITableView 中移动单元格的默认图标。

This one:

这个:

enter image description here

在此处输入图片说明

Is it possible?

是否可以?

回答by Ashley Mills

This is a really hacky solution, and may not work long term, but may give you a starting point. The re-order control is a UITableViewCellReorderControl, but that's a private class, so you can't access it directly. However, you could just look through the hierarchy of subviews and find its imageView.

这是一个非常棘手的解决方案,可能不会长期有效,但可能会给您一个起点。重新排序控件是一个UITableViewCellReorderControl,但这是一个私有类,因此您不能直接访问它。但是,您可以查看子视图的层次结构并找到它的 imageView。

You can do this by subclassing UITableViewCelland overriding its setEditing:animated:method as follows:

您可以通过子类化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"];
                    }
                }
            }
        }
    }   
}


Or in Swift

或者在斯威夫特

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")
            }
        }
    }
}

Be warned though... this may not be a long term solution, as Apple could change the view hierarchy at any time.

不过请注意……这可能不是一个长期的解决方案,因为 Apple 可以随时更改视图层次结构。

回答by Rick Morgan

Ashley Mills' answer was excellent at the time it was offered, but as others have noted in the comments, the view hierarchy has changed from version to version of iOS. In order to properly find the reorder control, I'm using an approach that traverses the entire view hierarchy; hopefully this will give the approach an opportunity to continue working even if Apple changes the view hierarchy.

Ashley Mills 的回答在提供时非常出色,但正如其他人在评论中指出的那样,视图层次结构已从 iOS 版本更改为版本。为了正确找到重新排序控件,我使用了一种遍历整个视图层次结构的方法;希望这将使该方法有机会继续工作,即使 Apple 更改了视图层次结构。

Here's the code I'm using to find the reorder control:

这是我用来查找重新排序控件的代码:

-(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;
}

And here's the code I'm using to override the -(void) setEditing:animated:method in my subclass:

这是我用来覆盖-(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);
                }
            }
        }
    }
}

回答by Grzegorz R. Kulesza

Swift 4

斯威夫特 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: { 
override func setEditing(editing: Bool, animated: Bool) {
    super.setEditing(editing, animated: animated)

    if editing {
        if let reorderView = findReorderViewInView(self), 
            imageView = reorderView.subviews.filter({ 
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"];
                }
            }
        }
    }
}
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 }
.description.contains("Reorder") })?.subviews.first(where: {
- (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;
                }
            }
        }
    }   
}
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 }

回答by Andrey Gordeev

Swiftversion of Rick's answer with few improvements:

瑞克答案的Swift版本,有一些改进:

 - (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;

}

回答by OgreSwamp

Updated solution of Ashley Mills (for iOS 7.x)

Ashley Mills 的更新解决方案(适用于 iOS 7.x)

 - (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;

}

回答by Padavan

    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)
                    }
                }
            }
        }
    }

回答by Hubert Wang

I use editingAccessoryView to replace reorder icon.

我使用editingAccessoryView 来替换重新排序图标。

  1. Make a subclass of UITableViewCell.
  2. Override setEditing. Simply hide reorder control and set editingAccessoryView to an uiimageview with your re-order image.
  1. 创建 UITableViewCell 的子类。
  2. 覆盖 setEditing。只需隐藏重新排序控件并将editingAccessoryView 设置为带有重新排序图像的uiimageview。
// 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];
}
// Change default reorder icon in UITableViewCell
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    let imageView = cell.subviews.first(where: { ##代码##.description.contains("Reorder") })?.subviews.first(where: { ##代码## is UIImageView }) as? UIImageView
    imageView?.image = UIImage(named: "your_custom_reorder_icon.png")
    let size = cell.bounds.height * 0.6 // scaled for padding between cells
    imageView?.frame.size.width = size
    imageView?.frame.size.height = size
}

If you are not using editing accessory view, this may be a good choice.

如果您不使用编辑附件视图,这可能是一个不错的选择。

回答by meow2x

I did this on iOS 12 with swift 4.2

我在 iOS 12 上用 swift 4.2 做了这个

I hope this helps:

我希望这有帮助:

##代码##

回答by bqlin

After debuging the UITableViewCell, you can use KVC in UITableViewCell subclass to change it.

调试完 UITableViewCell 之后,就可以在 UITableViewCell 子类中使用 KVC 来改变它。

##代码##

回答by nickcin

I could not get any other answer to work for me, but I found a solution.

我找不到任何其他适合我的答案,但我找到了解决方案。

Grzegorz R. Kulesza's answer almostworked for me but I had to make a couple changes.

Grzegorz R. Kulesza 的回答几乎对我有用,但我不得不做一些改变。

This works with Swift 5and iOS 13:

这适用于Swift 5iOS 13

##代码##