Search code examples
iosios6uiscrollviewxcode4.6

How to control scrolling in grid type view


UPDATED I have a grid (SubViewGrid) that I have drawn on a UIView. I need to be able to prevent the far left column (time) from scrolling horizontally, and the top row (staff name) from scrolling vertically.

The data is drawn in SubViewData, which is within the UIScrollView. I would imagine that I would need two (2) UIScrollViews here, one for the SubViewGrid, the other for the SubViewData. Question is: how to sync them to accomplish the user's needs?

enter image description here

UPDATE Here is the REVISED structure:

revised image

@property (nonatomic, weak) IBOutlet UIScrollView *schedScrollView;  
@property (nonatomic, weak) IBOutlet UIView * topGridView;  
@property (nonatomic, weak) IBOutlet UIView * leftGridView;  
@property (nonatomic, weak) IBOutlet UIView * topLeftView;    // TODO

Solution

  • See this answer to a similar question.

    I think that's how you would need to approach this problem, with the fixed heading(s) in a separate subview to the data. Then set the frame of the fixed subview in scrollViewDidScroll: to create the appearance of a fixed heading at the top (or side) of the scroll view.

    For example: Set the initial frame of the header subview to (0, 0, width, height), and then in scrollViewDidScroll: set the frame to (0, contentOffset.y, width, height).

    EDIT: Here's an example. In the below screenshot I set up the top row (people), left column (time), and top left cell (to hide the overlapping of the headers) inside a UIScrollView. Then in scrollViewDidScroll: I set the frames of the subviews to fix them to the top, left, and top-left respectively.

    Grid with fixed headers
    enter image description here

    ViewController.h:

    @interface ViewController : UIViewController <UIScrollViewDelegate>
    
    @property (nonatomic, weak) IBOutlet UIScrollView * theScrollView;
    @property (nonatomic, weak) IBOutlet UIImageView * topView;
    @property (nonatomic, weak) IBOutlet UIImageView * leftView;
    @property (nonatomic, weak) IBOutlet UIView * topLeftView;
    
    @end
    

    ViewController.m:

    #import "ViewController.h"
    
    @implementation ViewController
    
    @synthesize theScrollView, topView, leftView, topLeftView;
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        self.theScrollView.delegate = self;
    }
    
    - (void)viewDidLayoutSubviews
    {
        [super viewDidLayoutSubviews];
        self.theScrollView.contentSize = CGSizeMake(502, 401);
    }
    
    #pragma mark UIScrollViewDelegate methods
    
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        CGRect tempFrame = self.topView.frame;
        tempFrame.origin.y = scrollView.contentOffset.y;
        self.topView.frame = tempFrame;
    
        tempFrame = self.leftView.frame;
        tempFrame.origin.x = scrollView.contentOffset.x;
        self.leftView.frame = tempFrame;
    
        tempFrame = self.topLeftView.frame;
        tempFrame.origin.x = scrollView.contentOffset.x;
        tempFrame.origin.y = scrollView.contentOffset.y;
        self.topLeftView.frame = tempFrame;
    }
    
    @end
    

    And that's all there is to it! Hopefully this helps you.