8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

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

Shrikar Kalagi 2月前

40 0

我需要更改 UITableView 中移动单元格的默认图标。这个:可以吗?

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

这个:

enter image description here

是否可以?

帖子版权声明 1、本帖标题:更改 UITableView 中移动单元格的默认图标
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Shrikar Kalagi在本站《uitableview》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 这是一个非常棘手的解决方案,可能无法长期使用,但可以为您提供一个起点。重新排序控件是一个 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"];
                        }
                    }
                }
            }
        }   
    }
    

    或者用 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")
                }
            }
        }
    }
    

    但请注意...这可能不是一个长期的解决方案,因为苹果可能随时改变视图层次结构。

  • 有没有人找到一种方法来做到这一点而不冒着被 App Store 拒绝的风险?这是一种非常脆弱和不可靠的方法。

  • 如果失败了,我认为最有可能的结果是我们只会再次看到默认图标,这还不算太糟。我也尝试了 Phil 的方法,如果失败了,它会在错误的位置显示自定义图标,并且默认图标也可见。所以我会尝试这种方法。

  • 我的自定义图标与默认图标的大小不同,因此我还将找到的子视图的框架设置为我的 UIImage 的框架。我还扩展了它以自定义出现在表格单元格左侧的插入和删除图标。太棒了!

  • Beu 2月前 0 只看Ta
    引用 6

    这在 iOS 8 上同样有效。因此,你可以在 iOS 5、6 和 8 上使用它,在 iOS 7 上也可以使用 OgreSwamp 的解决方案。唯一的区别是,在 iOS 7 中视图层次结构从更深的一级开始。

  • @Brian - 这意味着在代码中引用私有类名,这会使应用程序面临被拒绝的风险。我疯狂的思维中有方法!

  • Ashley Mills 的答案在提出时非常出色,但正如其他人在评论中指出的那样,视图层次结构在 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);
                    }
                }
            }
        }
    }
    
  • ddaa 2月前 0 只看Ta
    引用 9

    Swift 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
        }
    
  • Rick 答案的 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
    }
    
  • 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"];
                    }
                }
            }
        }
    }
    
  • - (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;
                    }
                }
            }
        }   
    }
    
  • 由于明确使用了 UITableViewCellReorderControl 类名,这很可能会导致应用商店审批流程失败。

  • @Ashley Mills 我们在我们的应用程序中使用它,现在在 AppStore 中。

  • 从 iOS 5 开始,此功能不再起作用(至少现在不完美)。将单元格置于编辑模式时不会立即调用 willDisplayCell,而是在完成拖动后调用。这意味着默认重新排序控件最初显示时没有变化,直到您触摸并将其移动到 UITableView 中的其他位置。只有当您放下它时才会刷新(只有那时您的控件才会可见)。

  • 从技术上讲,这并非使用未记录的 API。您使用公共 API 遍历视图层次结构并根据需要进行更改。这与使用未记录的 API 的区别在于,如果 Apple 更改视图层次结构,这不会使应用程序崩溃,它只会将原始图像放回原位。据我了解,未记录的 API 是被禁止的,因为一旦 Apple 更改它们,应用程序就会崩溃。我保证此代码在 App Store Review 中是安全的。

  • 引用 17

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

    1. 创建 UITableViewCell 的子类。
    2. 覆盖 setEditing。只需隐藏重新排序控件并将 editingAccessoryView 设置为带有重新排序图像的 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;
    
    }
    

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

  • 引用 18

    虽然这可以显示自定义的editingAccessoryView,但我实际上无法通过按下并拖动来移动单元格。

  • 我无法找到任何其他适合我的答案,但我找到了一个解决方案。

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

    这适用于 Swift 5 iOS 13

    // Change default reorder icon in UITableViewCell
    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 = 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
    }
    
  • 我在 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)
                        }
                    }
                }
            }
        }
    
返回
作者最近主题: