在多选tableview时使用自定义图像替换复选标记

问题描述 投票:0回答:3

我尝试用自定义图像替换复选标记。我使用的方法如下:

-(void)layoutSubviews
{
    [super layoutSubviews];
    for (UIControl *control in self.subviews){
        if ([control isMemberOfClass:NSClassFromString(@"UITableViewCellEditControl")]){
            for (UIView *v in control.subviews)
            {
                if ([v isKindOfClass: [UIImageView class]]) {
                    UIImageView *img=(UIImageView *)v;
                    if (self.selected) {
                        img.image= [UIImage createImageWithColor:[UIColor redColor]];
                    }else
                    {
                        img.image= [UIImage createImageWithColor:[UIColor yellowColor]];
                    }
                }
            }
        }
    }
}

尽管仍然存在问题,但它确实工作正常。开头的

UIControl
中没有
self.subviews

enter image description here

如图所示。在我单击复选标记之前,复选标记不会被黄色图像替换。

ios objective-c uitableview
3个回答
1
投票

您应该在 -layoutSubviews 和 -didTransitionToState 中调用 -setImageForCheckMark。 -didTransitionToState 用于更改单元格状态,-layoutSubviews 用于更改单击状态

-(void)layoutSubviews
{
    // well ,while you change your cells' state into EditState ,-layoutSubviews will be invoked.
    // but the _imageView of control always be nil at end of layoutSubviews
    // I've try KVO to observe this _imageView ,but obviously it's not an attribute
    // Thankfully, UITableViewCell provide us with -willTransitionToState/-didTransitionToState
    [super layoutSubviews];
    [self setImageForCheckMark];
}


- (void)didTransitionToState:(UITableViewCellStateMask)state{
    // you should override it by your subclass ,when this method get called
    // all details of cell will be completed
    if (UITableViewCellStateShowingEditControlMask) {
        [self setImageForCheckMark];
    }
}

- (void)setImageForCheckMark{
    for (UIControl *control in self.subviews){
        if ([control isMemberOfClass:NSClassFromString(@"UITableViewCellEditControl")]){
            UIImageView *image = [control valueForKey:@"_imageView"];
            imageView.image = [UIImage createImageWithColor:self.selected?[UIColor yellowColor]:[UIColor greenColor]];
            break;
        }
    }
}

0
投票

此解决方案应该适用于 swift 4 和 5。

我正在使用 xcode 系统映像,因此运行此代码时不需要替换映像

// Add this to your Table View Controller

// Step 1

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    if(tableView.cellForRow(at: indexPath)?.imageView?.image == UIImage(systemName:"checkmark.circle")) {
        tableView.cellForRow(at: indexPath)?.imageView?.image = UIImage(systemName:"circle")
    } else {
        tableView.cellForRow(at: indexPath)?.imageView?.image = UIImage(systemName:"checkmark.circle")
    }
}

//Step 2

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    cell.textLabel?.text = employeeValues[indexPath.row]
    cell.imageView?.image = UIImage(systemName:"circle")

    return cell
}

0
投票

@user6187857 答案的快速版本:

override func layoutSubviews() {
    setImageForCheckMark()
    super.layoutSubviews()
}

override func didTransition(to state: UITableViewCell.StateMask) {
    if state.contains(.showingEditControl) {
        setImageForCheckMark()
    }
}

func setImageForCheckMark() {
    if let editControl = getEditControl() {
        for candidateImageView in editControl.subviews {
            if let imageView = candidateImageView as? UIImageView {
                imageView = ...
            }
        }
    }
}

static let editControlClass: AnyClass? = NSClassFromString("UITableViewCellEditControl")

func getEditControl() -> UIView? {
    guard let editControlClass = UITableViewCell.editControlClass else { return nil }
    for subview in subviews {
        if subview.isMember(of: editControlClass) {
            return subview
        }
    }
    return nil
}

如果您想完全删除复选标记:

imageView.isHidden = true

请注意,上面的内容仍然在左侧的复选标记所在位置留下了一个间隙。您可能还想将内容向左偏移以填补此空白,使用:

func getContentViewOffset() -> CGFloat{
    if let editControl = getEditControl() {
        return editControl.frame.origin.x + editControl.frame.width
    }
    return 0
}
© www.soinside.com 2019 - 2024. All rights reserved.