swift - 在可重用的表格 View 单元格中自动触摸按钮

标签 swift uitableview swift3

我的表格 View 的自定义单元格中有一个按钮。每当我滚动表格 View 时,按钮就会自动处于按下状态(我已从 isTouchInside 检查过)。我使用了可重复使用的电池。我该如何解决这个问题?

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "bookTimeCellView", for: indexPath) as! BookTimeCellView
        print("Button state : \(cell.bookButton.isTouchInside)")
        cell.timeLabel.text = timeArray[indexPath.row]
        return cell
}

这是我的自定义单元格的图像 Custom View Cell Image

每当我单击“booknow”按钮并滚动时,单元格中的其他按钮也处于按下状态。

这是我用于按钮的自定义类 UIButtonX

import UIKit

@IBDesignable
class UIButtonX: UIButton {

    enum FromDirection:Int {
        case Top = 0
        case Right = 1
        case Bottom = 2
        case Left = 3
    }

    var shadowView: UIView!
    var direction: FromDirection = .Left
    var alphaBefore: CGFloat = 1

    @IBInspectable var animate: Bool = false
    @IBInspectable var animateDelay: Double = 0.2
    @IBInspectable var animateFrom: Int {
        get {
            return direction.rawValue
        }
        set (directionIndex) {
            direction = FromDirection(rawValue: directionIndex) ?? .Left
        }
    }

    @IBInspectable var popIn: Bool = false
    @IBInspectable var popInDelay: Double = 0.4

    override func draw(_ rect: CGRect) {
        self.clipsToBounds = true

        if animate {
            let originalFrame = frame

            if direction == .Bottom {
                frame = CGRect(x: frame.origin.x, y: frame.origin.y + 200, width: frame.width, height: frame.height)
            }

            UIView.animate(withDuration: 0.3, delay: animateDelay, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: .allowUserInteraction, animations: {
                self.frame = originalFrame
            }, completion: nil)
        }

        if popIn {
            transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
            UIView.animate(withDuration: 0.8, delay: popInDelay, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: .allowUserInteraction, animations: {
                self.transform = CGAffineTransform.identity
            }, completion: nil)
        }

        if shadowView == nil && shadowOpacity > 0 {
            shadowView = UIView(frame: self.frame)
            shadowView.backgroundColor = UIColor.clear
            shadowView.layer.shadowColor = shadowColor.cgColor
            shadowView.layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: self.cornerRadius).cgPath
            shadowView.layer.shadowOffset = shadowOffset
            shadowView.layer.shadowOpacity = Float(shadowOpacity)
            shadowView.layer.shadowRadius = shadowRadius
            shadowView.layer.masksToBounds = true
            shadowView.clipsToBounds = false

            self.superview?.addSubview(shadowView)
            self.superview?.bringSubviewToFront(self)
        }
    }

    override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
        alphaBefore = alpha

        UIView.animate(withDuration: 0.2, delay: 0, options: .allowUserInteraction, animations: {
            self.alpha = 0.4
        })

        return true
    }

    override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
        UIView.animate(withDuration: 0.35, delay: 0, options: .allowUserInteraction, animations: {
            self.alpha = self.alphaBefore
        })
    }

    // MARK: - Borders

    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
            layer.masksToBounds = cornerRadius > 0
        }
    }

    @IBInspectable var borderWidth: CGFloat = 0.0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }

    @IBInspectable var borderColor: UIColor = UIColor.clear {
        didSet {
            layer.borderColor = borderColor.cgColor
        }
    }

    // MARK: - Shadow

    @IBInspectable public var shadowOpacity: CGFloat = 0
    @IBInspectable public var shadowColor: UIColor = UIColor.clear
    @IBInspectable public var shadowRadius: CGFloat = 0
    @IBInspectable public var shadowOffset: CGSize = CGSize(width: 0, height: 0)


   //    MARK: - Gradient
    @IBInspectable var firstColor: UIColor = UIColor.white {
        didSet {
            updateView()
        }
    }

    @IBInspectable var secondColor: UIColor = UIColor.white {
        didSet {
            updateView()
        }
    }

    @IBInspectable var horizontalGradient: Bool = false {
        didSet {
            updateView()
        }
    }

    override public class var layerClass: AnyClass {
        get {
            return CAGradientLayer.self
        }
    }

    func updateView() {
        let layer = self.layer as! CAGradientLayer
        layer.colors = [ firstColor.cgColor, secondColor.cgColor ]

        if (horizontalGradient) {
            layer.startPoint = CGPoint(x: 0.0, y: 0.5)
            layer.endPoint = CGPoint(x: 1.0, y: 0.5)
        } else {
            layer.startPoint = CGPoint(x: 0, y: 0)
            layer.endPoint = CGPoint(x: 0, y: 1)
        }
    }

}

最佳答案

您可以覆盖 UITableViewCellprepareForReuse,这是您在重用之前恢复任何 UI 控件的位置,如下所示:

class BookTimeCellView: UITableViewCell {

    @IBOutlet var button = CustomButton()

    override func prepareForReuse() {
        super.prepareForReuse()

        // normally following are the button states you would reset
        self.button.isSelected = false
        self.button.isHighlighted = false

        // This seems some CustomButton property
        self.bookButton.isTouchInside = false
    }

}

关于swift - 在可重用的表格 View 单元格中自动触摸按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55448742/

相关文章:

ios - 如何在不重启模拟器的情况下将项目添加到 TableView

ios - 后退按钮在 subview Controller 中不可见

swift - 不能在属性初始值设定项中使用实例成员 'getA';属性初始值设定项在 'self' 可用之前运行

swift - 在 Swift 中将字符转换为整数

ios - 跟踪将 iOS 小部件添加到主屏幕的用户的分析

带有 fetchedresultscontroller 的 ios UITableView - 添加自定义行

iOS UITableViewCell 重叠

ios - 使用 FileHandler 写入文件时出现问题

ios - Swift 2 - Xcode 7 - 失败,退出代码 1

ios - 如何更新工具栏按钮