【问题标题】:Custom footerview not responding to my tap gesture recognizer label自定义页脚视图没有响应我的点击手势识别器标签
【发布时间】:2020-10-15 14:18:11
【问题描述】:

所以我已经在此工作了几天,但没有运气。我有一个由 xib 文件制成的自定义 UIView,我将它添加到我的 footerView 中。视图已显示,但它没有响应我添加到 ViewController 类中的标签的手势识别器。在 VC 中,我创建了一个 UIView 实例并将其添加到我的 tableView 中。

奇怪的是,当使用无障碍检查器时,它确实会读取标签

这里是容器视图

class AdviceCardWidgetContainerCurvedView: UIView {
    
    struct Constants {
        static let nibName = "ClariContainerView"
        static let containerHeight: CGFloat =  169.0
        static let curvedPercent: CGFloat = 0.2
    }
    
    let nibName = "ClariContainerView"
    var clariView: UIView?
    var clariTitle: String?
    var clariQuestion: String?

    @IBOutlet weak var clariTitleLabel: UILabel!
    @IBOutlet weak var clariQuestionLabel: UILabel!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }


    private func applyCurve(givenView view: UIView, curvedPercent: CGFloat) {
        let shapeLayer = CAShapeLayer(layer: view.layer)
        shapeLayer.path = self.pathForCurvedView(givenView: view, curvedPercent: curvedPercent).cgPath
        shapeLayer.frame = view.bounds
        view.layer.mask = shapeLayer
        addSubview(view)
    }
    
    private func pathForCurvedView(givenView view: UIView, curvedPercent: CGFloat) -> UIBezierPath {
        let path = UIBezierPath()
        path.move(to: CGPoint(x: 0.0, y: 0.0))

        path.addLine(to: CGPoint(x: 0.0, y: view.bounds.size.height))
        path.addLine(to: CGPoint(x: UIScreen.main.bounds.width, y: view.bounds.size.height))
        path.addLine(to: CGPoint(x: UIScreen.main.bounds.width, y: 0.0))
        path.addQuadCurve(to: CGPoint(x: 0, y: 0), controlPoint: CGPoint(x: UIScreen.main.bounds.width / 2, y: view.bounds.size.height * curvedPercent))
        path.close()

        return path
    }
    
    private func commonInit() {
        guard let clariView = loadViewFromNib() else { return }
        clariView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: containerHeight)
        clariView.backgroundColor = .lightGray
        applyCurve(givenView: clariView, curvedPercent: 0.1)
        addSubview(clariView)
        clariTitleLabel.text = "Ask TD Clari"
        clariQuestionLabel.text = "What is my balance"
    }
    
    func loadViewFromNib() -> UIView? {
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: Constants.nibName, bundle: bundle)
        return nib.instantiate(withOwner: self, options: nil).first as? UIView
    }

}

这就是我的视图控制器里面的东西

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!
    let curvedView = AdviceCardWidgetContainerCurvedView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    
    override func viewDidLayoutSubviews() {
        curvedView.clariTitleLabel.accessibilityTraits = .button
        curvedView.clariTitleLabel.isUserInteractionEnabled = true
        curvedView.clariTitleLabel.backgroundColor = .red
        curvedView.clariTitleLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(footerLableTapped)))

        tableView.tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 169))
        tableView.tableFooterView?.addSubview(curvedView)
    }
    
    @objc func footerLableTapped() {
        print("label tapped")
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
        cell.textLabel?.text = "1"
        return cell
    }
}

【问题讨论】:

    标签: ios swift xcode uitableview tablefooterview


    【解决方案1】:

    好的,经过一周的尝试,我解决了这个问题。最后将自定义 xib 文件添加到 footerView 会导致一些错误并与 autoLayout 冲突。一切看起来都应该是这样,但是对于您添加的按钮和标签等子视图,框架基本上不存在,这就是为什么它们不能被点击的原因。确保您从情节提要中引用了您的 tableView 或您是如何创建它的。

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let remainingBottomFooterSpace = remaingBottomFooterViewSpace(for: tableView)
        
        let footerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 169))
        footerView.backgroundColor = .clear
        applyCurve(givenView: footerView, curvedPercent: 0.04)
        
        let remainingFooterView = UIView(frame: CGRect(x: 0, y: 169, width: tableView.frame.size.width, height: remainingBottomFooterSpace))
        remainingFooterView.backgroundColor = .lightGray
    
        let curve = UIView()
        curve.translatesAutoresizingMaskIntoConstraints = false
        curve.backgroundColor = .lightGray
        
        let icon = UIImageView()
        icon.translatesAutoresizingMaskIntoConstraints = false
        icon.image = UIImage(named: "mytd_clari")
        icon.contentMode = .scaleAspectFill
        curved.addSubview(icon)
        
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.isUserInteractionEnabled = true
        button.setTitle("Ask", for: .normal)
        button.titleLabel?.font = .systemFont(ofSize: 16.0, weight: .medium)
        button.setTitleColor(.blue, for: .normal)
        button.addTarget(self, action: #selector(footerLableTapped), for: .touchUpInside)
        
        let questionLabel = UILabel()
        questionLabel.translatesAutoresizingMaskIntoConstraints = false
        questionLabel.text = "What is my balance"
        questionLabel.textColor = .green
        questionLabel.font = .systemFont(ofSize: 13, weight: .regular)
        questionLabel.textAlignment = .center
        curve.addSubview(clariQuestionLabel)
        
        let buttonContainer = UIView(frame: CGRect(x: 0, y: 0, width: self.tableView.frame.size.width, height: 169))
        curve.addSubview(buttonContainer)
        buttonContainer.addSubview(button)
        
        tableView.tableFooterView = footerView
        tableView.tableFooterView?.addSubview(remainingFooterView)
        tableView.tableFooterView?.addSubview(curve)
        
        NSLayoutConstraint.activate([
            footerView.trailingAnchor.constraint(equalTo: tableView.trailingAnchor),
            footerView.leadingAnchor.constraint(equalTo: tableView.leadingAnchor)
        ])
        
        NSLayoutConstraint.activate([
            curve.widthAnchor.constraint(equalToConstant: tableView.frame.size.width),
            curve.heightAnchor.constraint(equalToConstant: 169)
        ])
        
        NSLayoutConstraint.activate([
            icon.topAnchor.constraint(equalTo: curve.topAnchor, constant: 39),
            icon.widthAnchor.constraint(equalToConstant: 40),
            icon.heightAnchor.constraint(equalToConstant: 40),
            icon.centerXAnchor.constraint(equalTo: curve.centerXAnchor),
        ])
        
        NSLayoutConstraint.activate([
            button.topAnchor.constraint(equalTo: icon.bottomAnchor),
            button.centerXAnchor.constraint(equalTo: icon.centerXAnchor)
        ])
        
        NSLayoutConstraint.activate([
            label.topAnchor.constraint(equalTo: button.bottomAnchor),
            label.centerXAnchor.constraint(equalTo: icon.centerXAnchor),
        ])
    }
    

    如果要添加曲线,方法如下:

    func applyCurve(givenView view: UIView, curvedPercent: CGFloat) {
            let shapeLayer = CAShapeLayer(layer: view.layer)
            shapeLayer.path = self.pathForCurvedView(curvedPercent: curvedPercent).cgPath
            shapeLayer.frame = view.bounds
            view.layer.mask = shapeLayer
        }
        
    func pathForCurvedView(curvedPercent: CGFloat) -> UIBezierPath {
            let path = UIBezierPath()
            path.move(to: CGPoint(x: 0.0, y: 0.0))
    
            path.addLine(to: CGPoint(x: 0.0, y: UIScreen.main.bounds.height))
            path.addLine(to: CGPoint(x: UIScreen.main.bounds.width, y: UIScreen.main.bounds.height))
            path.addLine(to: CGPoint(x: UIScreen.main.bounds.width, y: 0.0))
            path.addQuadCurve(to: CGPoint(x: 0, y: 0), controlPoint: CGPoint(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height * curvedPercent))
            path.close()
    
            return path
        }
    

    如果你想添加剩余的footerView空间,这里是func

    func remaingBottomFooterViewSpace(for tableView: UITableView) -> CGFloat {
            //Get content height & calculate new footer height
            let cells = tableView.visibleCells
            var height: CGFloat = 0
            for i in 0..<cells.count {
                height += cells[i].frame.height
            }
            height = tableView.bounds.height - ceil(height)
            
            //If theh footer new height is negative, we make it 0 since we don't need extra footer view anymore
            height = height > 0 ? height : 0
            return height
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多