1

I have a screen which consist of two elements (UIView and UITableView). When user scrolls the screen, I want UIView go out of screen (top) and UITableView start to scroll. I'm giving a fixed height for UIView and fixed height for UITableViewCells'. In addition I'm setting bottom and top anchors but UITableView doesn't show if I don't give a specific height to UITableView. If I give specific height for a UITableView, It just show some cells not all.

In addition: At first tableView is empty because Its datasource is empty. When user taps a button inside UIView, datasource fulfills and tableview refresh data.

I some posts but all of them says giving fixed height for UITableView. I don't know how to show all cells with fixed height. Eg: Dynamic height TableView in a Scroll View

Anchors:

boxView.anchor(self.view.topAnchor, left: self.view.leftAnchor, bottom: nil, right: self.view.rightAnchor, topConstant: 20, leftConstant: 10, bottomConstant: 0, rightConstant: 10, widthConstant: 0, heightConstant: 240)
sTableView.anchor(self.boxView.bottomAnchor, left: self.view.leftAnchor, bottom: self.scrollView.bottomAnchor, right: self.view.rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 100)

How I declare UITableView:

let sTableView = UITableView()
var dataSource: [SupportedService]?

let scrollView = UIScrollView()

viewDidLoad(){
sTableView.delegate = self
sTableView.dataSource = self
sTableView.register(BaseCell.self, forCellReuseIdentifier:"supportedServicesCell")
sTableView.tableFooterView = UIView()
sTableView.isScrollEnabled = false
self.scrollView.addSubview(sTableView)

self.view.addSubview(scrollView)
}
@objc func buttonTapped(_ sender: UIButton){
//Do Some Network Requests Here (Data is temp)
dataSource = DATA
sTableView.reloadData()
}

TableView Functions:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if let data = dataSource{
        return data.count
    }else{
        return 0
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "supportedServicesCell", for: indexPath) as! BaseCell
    guard let data = dataSource else { return cell }
    cell.textLabel?.text = data[indexPath.row].title

    return cell
}

How I want it before scroll:

After Scroll:

Emre Önder
  • 2,408
  • 2
  • 23
  • 73

2 Answers2

1

I have seen some apps do this. But their approach is different. I will explain that approach though if it helps. Here is what they do.

  • User interaction is disabled for the tableView in the beginning.
  • Once the user swipes the screen up. The view is animated to hide itself by going out of the screen and the tableView takes up the whole screen.
  • Now user interaction is again enabled on the tableView and it functions like a normal tableView.
  • Once the user tries to scroll down even after reaching the top of the tableView, the view is animated back to the place and the parentView return to how it was originally.
Rakesha Shastri
  • 11,053
  • 3
  • 37
  • 50
  • If I can get the touch position and the swipe position, I can move view header as you told but I may face with a problem that UITableViews CellForRowAt function will be not called. I'll check it – Emre Önder Jul 04 '18 at 12:28
  • You can get the touch position and and swipe position. Apple has delegates for getting those values. – Rakesha Shastri Jul 04 '18 at 12:35
0

You need to change your approach of designing the app UI for such designs. For the current design that you are making a UITableview with headerview is the easy, nice and a better approach then embedding UIView and UITableview inside the UIScrollView.

Y_Y
  • 331
  • 1
  • 6