Skip to content

Instantly share code, notes, and snippets.

@FlorianMielke
Created December 6, 2011 06:58
Show Gist options
  • Star 37 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save FlorianMielke/1437123 to your computer and use it in GitHub Desktop.
Save FlorianMielke/1437123 to your computer and use it in GitHub Desktop.
Info Panel attached to a UIScrollViewIndicator like in the Path 2 app. More information: http://cl.ly/CN2p
//
// FMInfoPanelViewController.h
// Created by Florian Mielke (@FlorianMielke) on 06.12.11.
//
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
@interface FMInfoPanelViewController : UIViewController <UIScrollViewDelegate>
{
UIScrollView *scrollView;
UIView *infoPanel;
CGSize initialSizeOfInfoPanel;
CGFloat initialHeightOfScrollIndicator;
}
@end
//
// FMInfoPanelViewController.m
// Created by Florian Mielke (@FlorianMielke) on 06.12.11.
//
#import "FMInfoPanelViewController.h"
@implementation FMInfoPanelViewController
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad
{
CGRect viewFrame = [[self view] frame];
scrollView = [[UIScrollView alloc] initWithFrame:viewFrame];
[scrollView setDelegate:self];
[scrollView setContentSize:CGSizeMake(viewFrame.size.width, viewFrame.size.height * 4)];
[[self view] addSubview:scrollView];
UIImageView *backgroundImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"infoPanel.png"]];
initialSizeOfInfoPanel = [backgroundImage frame].size;
infoPanel = [[UIView alloc] initWithFrame:CGRectMake(initialSizeOfInfoPanel.width * (-1), 0, initialSizeOfInfoPanel.width, initialSizeOfInfoPanel.height)];
[infoPanel addSubview:backgroundImage];
[backgroundImage release], backgroundImage = nil;
}
#pragma mark -
#pragma mark Scroll view delegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)aScrollView
{
if (![infoPanel superview])
{
UIView *indicator = [[aScrollView subviews] lastObject];
CGRect indicatorFrame = [indicator frame];
initialHeightOfScrollIndicator = indicatorFrame.size.height;
[[infoPanel layer] setBackgroundColor:[[indicator layer] backgroundColor]];
[[indicator layer] addSublayer:[infoPanel layer]];
// Center the info panel
CGRect infoPanelFrame = [infoPanel frame];
infoPanelFrame.size = initialSizeOfInfoPanel;
infoPanelFrame.origin.y = indicatorFrame.size.height / 2 - infoPanelFrame.size.height / 2;
[infoPanel setFrame:CGRectIntegral(infoPanelFrame)];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
UIView *indicator = [[aScrollView subviews] lastObject];
CGRect indicatorFrame = [indicator frame];
// We are somewhere at the edge (top or bottom)
if (indicatorFrame.size.height < initialHeightOfScrollIndicator)
{
CGRect infoPanelFrame = [infoPanel frame];
// The indicator starts shrinking, so we need to adjust our info panel's y-origin to stays centered
if (indicatorFrame.size.height > infoPanelFrame.size.height + 2)
{
infoPanelFrame.origin.y = (indicatorFrame.size.height / 2) - (infoPanelFrame.size.height / 2);
}
// We are at the bottom of the screen and the indicator is now smaller than our info panel
else if (indicatorFrame.origin.y > 0)
{
infoPanelFrame.origin.y = (infoPanelFrame.size.height - indicatorFrame.size.height) * -1;
}
[infoPanel setFrame:infoPanelFrame];
}
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
[infoPanel removeFromSuperview];
}
#pragma mark -
#pragma mark Memory management
- (void)dealloc
{
[infoPanel release], infoPanel = nil;
[scrollView release], scrollView = nil;
[super dealloc];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment