简体   繁体   中英

UITableView in a subview doesn't respond to touch events and doesn't scroll

Language : Swift 5

iOS : 13.2

macOS : Catalina 10.15.4

I have following structure in my app:

在此处输入图像描述

Based on what I select from either segmented control OR the buttons at the bottom of the screen, different view is added as a subview to the ContainerView in following manner:

In case of the Segmented Control:

//viewControllerForSelectedSegmentIndex returns the appropriate UIViewController
if let vc = viewControllerForSelectedSegmentIndex(index: sender.selectedSegmentIndex, 
    control: sender) 
{
        self.addChild(vc)
        self.transition(from: self.currentViewController!, to: vc, duration: 0.5, 
        options:.transitionFlipFromRight, animations: 
        {
            self.currentViewController!.view.removeFromSuperview()
            vc.view.frame = CGRect(x: 0 , y: 130, width: self.view.frame.width, height: 
            self.view.frame.height-250)
            self.containerView.addSubview(vc.view)
            
            }, completion: { finished in
                vc.didMove(toParent: self)
                self.currentViewController!.removeFromParent()
                self.currentViewController = vc
            }
        )
        sender.changeUnderlinePosition()

    }

In case of selecting one of the buttons:

    let vc = BrowseController()
    self.addChild(vc)
    self.currentViewController!.view.removeFromSuperview()
    vc.view.frame = CGRect(x: 0 , y: 130, width: self.view.frame.width, height: 
            self.view.frame.height-250)
    self.containerView.addSubview(vc.view)
    vc.didMove(toParent: self)
    self.currentViewController!.removeFromParent()
    self.currentViewController = vc

UIViewController:

Every UIViewController added as a child, has a UIScrollView in it. All the UI elements are added to the view inside UIScrollView.

Problem:

Couple of viewControllers contain UITableView. The UITableView is rendered properly, however, I am not able to scroll it. One of the tableview has UIButton inside it's cell and that button i I also doubt that it is recognizing any user interaction like touch.

What I have tried so far / My Analysis so far:

  1. I Set isUserInteractionEnabled true for the UITableView mentioned in the problem.

  2. To check if touch events are being recognized, I added UITapGestureRecognizer with a print statement in it's selector function. Also, added a print statement in touchesBegan function. none of them are printed.

  3. I tried to bring the viewController's view to front using

     self.view.bringSubviewToFront(self.currentViewController.view)

    It didn't help either!

Could anyone please point out the problem here?

I have one example for child and segment, check the follow example.

import UIKit

class ViewController: UIViewController {

    let segment = UISegmentedControl(items: ["uno" , "dos","tres"])
    let containerView : UIView = {
        let view = UIView()
        view.backgroundColor = .red
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        addingChild(childViewController: tableViewController)
        
        segment.addTarget(self, action: #selector(selectedTapped), for: .valueChanged)
        self.view.addSubview(segment)
        self.view.addSubview(containerView)
        segment.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            segment.topAnchor.constraint(equalTo: self.view.topAnchor , constant: 50),
            segment.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
            segment.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
            containerView.topAnchor.constraint(equalTo: self.segment.bottomAnchor, constant: 10),
            containerView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
            containerView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
        ])
        
        
        
    }
    let tableViewController = TableViewChild(style: .grouped)
    let secondChild = SecondChild()
   //segment changed
    @objc func selectedTapped(_ segment : UISegmentedControl){
        
        if segment.selectedSegmentIndex == 0 {
            addingChild(childViewController: tableViewController)
            removeChild(childViewController: secondChild)
        }
        
        if segment.selectedSegmentIndex == 1 {
            addingChild(childViewController: secondChild)
            removeChild(childViewController: tableViewController)
            
        }else if segment.selectedSegmentIndex == 2 {
            removeChild(childViewController: tableViewController)
            removeChild(childViewController: secondChild)
        }
        
        
    }
    // remove child
    func removeChild(childViewController : UIViewController){
        willMove(toParent: nil)
        childViewController.view.removeFromSuperview()
        removeFromParent()
    }
    //Add child
    func addingChild(childViewController : UIViewController){
        addChild(childViewController)
        self.containerView.addSubview(childViewController.view)
        childViewController.didMove(toParent: self)
        childViewController.view.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            childViewController.view.topAnchor.constraint(equalTo: containerView.topAnchor),
            childViewController.view.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            childViewController.view.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            childViewController.view.bottomAnchor.constraint(equalTo: containerView.bottomAnchor)
        ])
    }

}

class SecondChild : UIViewController {
    let label : UILabel = {
        let label = UILabel()
        label.text = "Second Label"
        return label
    }()
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .gray
        self.view.addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
        label.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
    }
}

class TableViewChild : UITableViewController {
    let elements = ["1","2","3","4","5"]
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return elements.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.textLabel?.text = elements[indexPath.row]
        return cell
    }
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("hola")
    }
    
}

I recommend you use constraint instead frame for set the your child dimensions, in my example I add child and remove the other child when segment pressed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM