Search code examples
iosswiftcalayer

iOS : Any Other way to put an image over a UITableView, the UITableView works normally?


iOS : The goal is to put an image over a UITableView, the UITableView works normally.

Generally, put an image over a UITableView, the touch events of the UITableView is cut off.

Here is the scene, there is a piano score app. The music notes line by line is shown by a UITableView.

Then user could put a canvas over the notes list, they could draw over the score.

I need to put the custom drawing over the piano score UITableView, and the UITableView works normally.

Here is my idea:

put the drawing View on the tableView, underneath the cells.

Each cell have a reference of the drawing View.

Each cell also have a canvas slice view on its top.

The key method is CALayer's open func render(in ctx: CGContext)

Here is the relevant code:

class RenderV: UIView {
    
    var renderer: UIView?
    
    var index = -1

    override func draw(_ rect: CGRect) {
        
        guard let context = UIGraphicsGetCurrentContext()
            else { return }
        var f: CGSize = .zero
        if let v = renderer{
            f = v.frame.size
        }
        let w = frame.size.width
        let h = frame.size.height

        context.translateBy(x: w/2 - f.width/2, y: h * CGFloat(index) - f.height)

        renderer?.layer.render(in: context)
        
    }
}

canvas used in UITableViewCell:

class TableViewCell: UITableViewCell {
    
    
    var renderer: UIView?{
        didSet{
            guard idx > 0 else {
                return
            }
            contain.index = idx
            contain.renderer = renderer
            contain.setNeedsDisplay()
        }
    }
    
    
    @IBOutlet weak var contain: RenderV!
    
    var idx = -1
}

Call code:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cel = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
        cel.idx = 6 - indexPath.row
        cel.renderer = img
        return cel
    }

My solution is not intuitive, and needs calculating.

Any better idea?


Here is an easy demo effect:

111

222


Solution

  • I'm not sure that I understand completely what is the problem. What I understand is that the view that you render over the UITableView is blocking the touch events that you want to be passed to the table, right?

    If it's the case, just set the view's isUserInteractionEnabled = false. That will enable the events to penetrate the view and be captured by the UITableView.