Scrollview with embedded tableview
Asked Answered
B

2

17

I'm building an iOS app in swift with Xcode 6. I'm trying to embed a view controller with a table view in a scrollview. When the user drags in the table view, it is suppose to move the table, not the the scrollview that it is embedded in. I've made this illustration, to clearify my view and view controller hierachy: View Hierachy

The red area is the content size area of the scrollview.

The green and blue areas are different view controllers, embedded in the scrollview.

The yellow area is a Text field in the blue view controller.

The orange area is a table view in the blue view controller.

I have enabled paging in the scrollview, so that it snaps to either the green or blue view controller. How can I pop the Table view to the top of the view hierachy, so that the only way to scroll the scrollview, will be to drag in the text field.

import UIKit

class RootViewController: UIViewController, UIScrollViewDelegate {

var scrollView: UIScrollView!

var greenViewController: GreenViewController!
var blueViewController: BlueViewController!

override func viewDidLoad() {
    super.viewDidLoad()

    scrollView = UIScrollView(frame: CGRectMake(0, 0, self.view.frame.width, self.view.frame.height))
    scrollView.delegate = self
    scrollView.pagingEnabled = true

    self.greenViewController = self.storyboard?.instantiateViewControllerWithIdentifier("Green View Controller") as! GreenViewController
    self.blueViewController = self.storyboard?.instantiateViewControllerWithIdentifier("Blue View Controller") as! BlueViewController

    greenViewController.view.frame = CGRectMake(0, 0, view.bounds.width, view.bounds.height)
    blueViewController = CGRectMake(0, view.bounds.height, view.bounds.width, view.bounds.height)


    scrollView.addSubview(greenViewController.view)
    scrollView.addSubview(blueViewController.view)

    scrollView.contentSize = CGSizeMake(view.bounds.width, view.bounds.height*2)

    self.view.addSubview(scrollView)

}

I hope that I have expressed myself clearly.

EDIT:

I've tried changing the size of the scrollview, when it scrolls. The idea was to change the height of the frame so it matches the height of the textfield when it is scrolled all the way down. But it seems that it also changes the visible part of whats embedded in the scrollview:

    func scrollViewDidScroll(scrollView: UIScrollView) {

    if self.scrollView.contentOffset.y > textField.View.bounds.height {
        self.scrollView.frame.size.height = view.bounds.height - scrollView.contentOffset.y - textField.View.bounds.height
        println(self.scrollView.frame)
    }
}
Bizet answered 9/9, 2015 at 22:1 Comment(2)
Does the tableView have its delegate set? Are you sure the content inside the tableView exceeds the tableView's height?Perth
If the tableView's content is bigger than the tableView's viewable area, should the tableView scroll then?Crownpiece
W
4

Ok it might be bit late now but still i m posting this as a tutorial ! This is a less prefered way to achieve this. Better way would be,

Using table view controller as parent view and then using prototype cells as static cell(In 'n' numbers as per your requirement) as a card view or for any other use

The every different cell used would be considered as a section and no of prototype cells will be equal to no of sections in code as in snippet below

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 3
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if section == 2 {
        return list.count
    }
    return 1
}

number of rows in case of section 0 and 1 would be 1 as static part Whereas No of rows in case of section 2 i.e dynamic part would be equal to count of list.

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell : CustomTableViewCell.swift = CustomTableViewCell.swift()
    switch indexPath.section {

        case 0:
            cell = tableView.dequeueReusableCellWithIdentifier("staticCell1", forIndexPath: indexPath) as! CustomTableViewCell
            break
        
        case 1:
            cell = tableView.dequeueReusableCellWithIdentifier("staticCell2", forIndexPath: indexPath) as! CustomTableViewCell
            break
        
        case 2:
            cell  = tableView.dequeueReusableCellWithIdentifier("dynamicCell", forIndexPath: indexPath) as! CustomTableViewCell
            break
        
        default:
            break
    }
    return cell;

}

and thats it! Work is done! Party!

I got reference from here Mixing static and dynamic sections in a grouped table view?

Weathered answered 31/7, 2016 at 10:27 Comment(0)
C
0

I mocked this up. My View hierarchy looks like this

ViewController's UIView
...UIView (to act as a container view for all the scrollable content)
.......UIView (for the top content) - green
.......UIView (for the bottom content) - blue
............UILabel
............UITableView (with scrollable content - more rows than visible)

I wired @IBOutlets to the UIScrollView (scrollView) and UIView (containerView) for the scrollable area.

in viewDidLoad I added:

scrollView.contentSize = containerView.frame.size

If I click anywhere outside the tableView (top area, text area, etc...) I scrolls the scrollView. If I try to scroll in the table view, the tableView scrolls (the scrollView does not).

Is that what you were trying to achieve?

Crownpiece answered 3/6, 2016 at 21:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.