Scrollview with embedded tableview

2019-02-06 11:58发布

问题:

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:

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)
    }
}

回答1:

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?



回答2:

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?