Home > Blockchain >  Decreasing the topAnchor of an UIView by scrolling the tableView inside it
Decreasing the topAnchor of an UIView by scrolling the tableView inside it

Time:12-12

I have a view that there is tableView inside this view. This View is in the bottom of an UIViewController, and there is an another view is in top of it. But I set the top anchor of tableView View to the top side the screen that I can change it when I need - see the screenshot

I want when tableView is scrolling, the top anchor decrease. For this I did that in the UIView that contains TableView

  func scrollViewDidScroll(_ scrollView: UIScrollView) {
 
    let offset = scrollView.contentOffset.y
    scrollView.bounces = false
    eventHandler?(.scrollViewDidScroll(offset: offset))
}

With this eventHandler I send the offset the parent UIViewController And then use this function to reduce the the topAnchor

private func handleOffsetScrolling(offset: CGFloat) {
    let constant =  taskViewHeight - offset
    if constant > 0 {
        todosTableTopAnchor.constant = taskViewHeight - offset
        view.layoutIfNeeded()
    }
}

the taskViewHeightis the height of the second view in the top. It works well as expected, but during the decreasing the topAnchor, the tableView also scrolling, I want to prevent that. I mean the tableView should not scroll until the view reach to the top and then it scrolls. and when scrolling to the top of tableView again, it should increasing the top anchor and move the tableView view to its original position. I just want to prevent tableView scrolling during the increasing and decreasing the top anchor.

Is there any way to do that? Thanks

enter image description here

CodePudding user response:

You almost certainly don't want to put these views in a scroll view.

To get the (blue) table view to "slide up on-top-of" the green view, you can constrain the Top of both views to the same Y-position. Then set the table view's contentInset.top to the height of the green view, and start with the table view's .contentOffset.y at minus the height of the green view.

Here'a a really quick example:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    let greenHeaderView = UIView()
    let tableView = UITableView()
    
    // let's make the green view height: 100-points
    let greenHeight: CGFloat = 100.0
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // let's add a label to the green view so we can see what goes on
        let label = UILabel()
        label.textAlignment = .center
        label.text = "This is sample text for the Header View"
        label.textColor = .yellow
        
        greenHeaderView.backgroundColor = .systemGreen

        label.translatesAutoresizingMaskIntoConstraints = false
        greenHeaderView.addSubview(label)

        greenHeaderView.translatesAutoresizingMaskIntoConstraints = false
        tableView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(greenHeaderView)
        view.addSubview(tableView)
        
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            
            greenHeaderView.topAnchor.constraint(equalTo: g.topAnchor),
            greenHeaderView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
            greenHeaderView.trailingAnchor.constraint(equalTo: g.trailingAnchor),

            greenHeaderView.heightAnchor.constraint(equalToConstant: greenHeight),
            
            label.centerXAnchor.constraint(equalTo: greenHeaderView.centerXAnchor),
            label.centerYAnchor.constraint(equalTo: greenHeaderView.centerYAnchor),
            
            tableView.topAnchor.constraint(equalTo: g.topAnchor),
            tableView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
            tableView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
            tableView.bottomAnchor.constraint(equalTo: g.bottomAnchor),
            
        ])
        
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "c")
        tableView.dataSource = self
        tableView.delegate = self
    
        tableView.backgroundColor = .clear

        tableView.contentInset.top = greenHeight
        tableView.contentOffset.y = -greenHeight

    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 30
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let c = tableView.dequeueReusableCell(withIdentifier: "c", for: indexPath)
        c.textLabel?.text = "\(indexPath)"
        return c
    }
    
}

and it looks like this:

enter image description here

enter image description here

enter image description here

  • Related