Click here to Skip to main content
15,886,137 members
Articles / Mobile Apps / iPhone

Switch between views Mobile Safari-style

Rate me:
Please Sign up or sign in to vote.
4.96/5 (34 votes)
23 Jul 2010CPOL15 min read 80.4K   661   20  
A reusable library (specifically, an UIViewController subclass) to implement Mobile Safari page/tab switching interface in your own app. Now supports orientation changes!
//
//  LSPagesPresentationView.h
//  ViewSwitcher
//
//  Created by Le Son on 5/24/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

/*
 IMPORTANT: Read these to understand how this class functions
 
 - You don't usually interact with this class.
   LSPageViewController do this for you.
 
 - When LSPageViewController wants to show this view:
   + After - [LSPagesPresentationView init], it sets selectedIndex and pageViewController (and delegate as well, if needed)
   + After that, call - [LSPagesPresentationView setup]
   + Then show this view
   + When this view is visible to the user, a - [LSPagesPresentationView startEntranceAnimation] is sent
 
 - When an external instance wants to supply LSPageViewController a new view controller
   (by invoking - [LSPageViewController addViewController:])
   if this view is currently being shown to the user,
   after adding the new view, LSPageViewController will proceed to call - [LSPagesPresentationView addNewLayer:]
 - Same for removing view controller, but the invoked method will be - [LSPagesPresentationView removeLayerAtIndex:]
   Note: the removal method is called internally as well, when the close button on the top left of a view (technically, layer) is tapped.
 
 - When an external instance want to dismiss this view,
   it calls - [LSPageViewController shouldDismissPagesPresentationView].
   LSPageViewController in turn calls - [LSPagesPresentationView zoomCurrentLayerForEnding].
   This method animate the currently selected layer representing the view to be displayed
   after this view is dismissed.
 
   Customization notices:
 - For customization regarding size and position of layers, refer to the category Maths
   in LSPagesPresentationView.m. Read LSPagesPresentationViewPrivate.m to see a list of Maths method.
   Be aware that many Maths method are dependent on other Maths method (but not any method outside)
   so modifying one can affect all.
 - In general, study all Maths method before customizing.
 
 - For customization regarding animation (speed, etc.),
   refer to the category Animations.
 
 - To configure names, refer to - setupNameLayer.
   If you don't want any text, just remove all references to setupNameLayer.
   Remember to change - boundsForContainerLayer, - positionForContainerLayer and - boundsForViewLayer
   to make up for the empty space.
 
 - To modify gesture recognition algorithms, focus specifically on - (void)processTouch:(UITouch *)touch;
   Of course, if you recompile for 4.0, you should just use Apple's built-in gesture recognizer instead.
   If you plan to completely rewrite - processTouch:, keep in mind that the 4 touchesBegan/Moved/Ended/Cancelled
   need to be modified to accommodate your new - processTouch: as well.
   Your - processTouch: need to store processed data in the provided (NSMutableArray *)touchStorage.
   Be aware that many other methods use data stored in touchStorage, and you might need to modify those methods.
 - You generally don't need to be concerned about vertical movement of a touch, just horizontal ones.
 - A list of keys commonly used to store data in touchStorage:
   + type:              The type of gesture - LSTouchTypeTap, LSTouchTypeMoveStop or LSTouchTypeSwipe.
                        (of course you are free to use your own names)
   + originalLocation:  The original X value of the touch.
   + hitTest:           The layer "hit" by the touch. Used if the touch is a tap.
   + totalTravelLength: The difference between current X of the touch and the original X
                        Used to - moveLayerWithOffset:
   + velocity:          For swipes, totalTravelLength is redundant.
                        Instead, this value represents the speed of the swipe.
   + direction:         For move-then-stop, "left" if totalTravelLength is negative, and vice versa.
                        For swipes, "left" if velocity is negative, and vice versa.
                        Used to determine the direction to move layers.
 - If you're unsure which method uses touchStorage, find the text: "This makes use of touchStorage".
 
 - If you need to customize this view's background (currently a simple gradient),
   focus on - drawLayer:atIndex:
 
   Enjoy ;)
 */

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "CALayer+Extra.h"
#import "NSArray+Extra.h"

@class CloseButtonLayer;
@class LSTextLayer;
@class LSPageViewController;
@class LSDotLayer;

@interface LSPagesPresentationView : UIView {
	BOOL isLayingOutLayers;
	
	NSMutableArray *pagesLayers;
	LSPageViewController *pageViewController;
	
	NSInteger selectedIndex;
	NSInteger closeIndex;
	
	CALayer *contentContainerLayer;
	LSTextLayer *nameLayer;
	LSDotLayer *dotLayer;
		
	NSMutableDictionary *touchStorage;
	
	id delegate;
}

@property (nonatomic, assign) LSPageViewController *pageViewController;
@property NSInteger selectedIndex;
@property (assign) id delegate;

- (id)initWithFrame:(CGRect)frame layers:(NSArray *)layers;
- (void)setup;

- (void)startEntranceAnimation;
- (void)zoomCurrentLayerForEnding;

- (void)addNewLayer:(CALayer *)layer;
- (void)removeLayerAtIndex:(int)index;

@end

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Other Hanoi - Amsterdam High School
Vietnam Vietnam
I'm a 16 year old high school student. I know some about Objective-C and a bit about C#, mostly through reading stuff online.

Comments and Discussions