Question

I'm working through a tutorial on child view controllers in RubyMotion. (What I'm trying to do is create a tabbed interface in the likes of Instagram's profile pages.) I have things working, however my problem is that my container has a scrollView and the child I'm adding is a tableView, which is itself a scrollView. The two scroll independent of each other, where I'd like them to scroll as one. Is there a way I can do that given my code below?

My container:

class ProfileController < SharedController
  def viewDidLoad
    super

    scroll_frame = self.view.bounds

    @scroll = UIScrollView.alloc.initWithFrame(scroll_frame)
    @scroll.bounces = true
    @scroll.delegate = self
    @scroll.alwaysBounceVertical = true
    @scroll.contentSize = CGSizeMake(UIScreen.mainScreen.bounds.size.width, scroll_frame.size.height)

    main_container = UIViewController.alloc.init
    self.push(main_container)
  end

  def tap_child(sender)
    set_active_tab(sender)
    controller             = ChildPartialController.alloc.initWithNibName(nil, bundle:nil)
    controller.data        = @data[:child]
    controller.parent      = self
    controller.scroll_view = @scroll
    self.push(controller)
  end
end

The child:

class ChildPartialController < SharedController
  attr_accessor :data, :scroll_view, :parent

  def viewDidAppear(animated)
    scroll_view.contentSize = CGSizeMake(UIScreen.mainScreen.bounds.size.width, 272)
  end

  def viewDidLoad
    super

    self.title = "Child"

    @data = data

    @table = UITableView.alloc.initWithFrame(
      CGRectMake(0, parent.tab_bar.frame.origin.y + parent.tab_bar.frame.size.height, self.view.bounds.size.width, self.view.bounds.size.height),
      style: UITableViewStyleGrouped
    )
    @table.autoresizingMask = UIViewAutoresizingFlexibleHeight
    @table.rowHeight        = 30

    parent.view.addSubview(@table)

    @table.dataSource = self
    @table.delegate = self
  end
end

SharedCode:

class SharedController < UIViewController
  def push(to_vc, animated = false)
    from_vc = self.stack[-1] # could be nil

    self.stack.pop if self.stack.count > 1

    self.stack.push(to_vc)

    self.addChildViewController(to_vc)

    post_animate = lambda { |finished|
      to_vc.didMoveToParentViewController(self)
      to_vc.viewDidAppear(animated)
    }

    if !from_vc.nil?
      to_vc.view.frame = child_frame
      to_vc.viewWillAppear(animated)
    end

    @scroll.addSubview(to_vc.view)
    post_animate.call(true)

    p self.stack.count
  end

  def child_height
    self.view.bounds.size.height - 232
  end

  def child_width
    self.view.bounds.size.width
  end

  def child_frame
    CGRectMake(0, self.tab_bar.frame.origin.y + self.tab_bar.frame.size.height + 10, child_width, child_height)
  end

  def offscreen_top_frame
    CGRectMake(0, 50 - child_height, child_width, child_height)
  end

  def offscreen_bottom_frame
    CGRectMake(0, self.view.bounds.size.height, child_width, child_height)
  end
end
Was it helpful?

Solution

As it turns out I think I was just making things way too complicated with this approach. Instead, I turned my child view controllers into subclasses of UIView, added a UITableView to that, then added the UIView to the parent's scroll view as a subview. Here's an example in case anyone is interested:

My container:

class ProfileController < SharedController
  def viewDidLoad
    super

    scroll_frame = self.view.bounds

    @scroll = UIScrollView.alloc.initWithFrame(scroll_frame)
    @scroll.bounces = true
    @scroll.delegate = self
    @scroll.alwaysBounceVertical = true
    @scroll.contentSize = CGSizeMake(UIScreen.mainScreen.bounds.size.width, scroll_frame.size.height)
  end

  def tap_child(sender)
    set_active_tab(sender)
    controller             = ChildPartial.alloc.initWithFrame(CGRectMake(0, self.tab_bar.frame.origin.y + self.tab_bar.frame.size.height, self.view.bounds.size.width, self.view.bounds.size.height))
    controller.data        = @data[:child]
    controller.parent      = self
    controller.scroll_view = @scroll
    controller.build_table
    @scroll.addSubview(controller)
  end
end

Child:

class ChildPartial < UIView
  attr_accessor :data, :parent, :scroll_view

  def initWithFrame(frame)
    super

    self
  end

  def data=(data)
    @data = data
  end

  def parent=(parent)
    @parent = parent
  end

  def scroll_view=(scroll_view)
    @scroll_view = scroll_view
  end

  def build_table
    @table = UITableView.alloc.initWithFrame(self.bounds, style: UITableViewStyleGrouped)
    @table.autoresizingMask = UIViewAutoresizingFlexibleHeight
    @table.userInteractionEnabled = false

    @table.dataSource = self
    @table.delegate = self

    resize_scroll_view

    self.addSubview(@table)
  end

  def resize_scroll_view
    @scroll_view.contentSize = CGSizeMake(parent.view.bounds.size.width, parent.view.bounds.size.height + @table.bounds.size.height)
  end

end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top