p2 avatar p2 committed 8b0a02b

Add simple top and bottom rows (FAR from perfect)

Comments (0)

Files changed (8)

ThumbScrolling.xcodeproj/project.pbxproj

 	objects = {
 
 /* Begin PBXBuildFile section */
+		EE3DB29A152A372700390816 /* background_top.png in Resources */ = {isa = PBXBuildFile; fileRef = EE3DB299152A372700390816 /* background_top.png */; };
+		EE3DB29D152A39E500390816 /* background_top@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EE3DB29C152A39E500390816 /* background_top@2x.png */; };
+		EE3DB2A0152A3F9300390816 /* background_bottom.png in Resources */ = {isa = PBXBuildFile; fileRef = EE3DB29E152A3F9300390816 /* background_bottom.png */; };
+		EE3DB2A1152A3F9300390816 /* background_bottom@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EE3DB29F152A3F9300390816 /* background_bottom@2x.png */; };
 		EEC5ED86150E709800F366C7 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEC5ED85150E709800F366C7 /* UIKit.framework */; };
 		EEC5ED88150E709800F366C7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEC5ED87150E709800F366C7 /* Foundation.framework */; };
 		EEC5ED8A150E709800F366C7 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEC5ED89150E709800F366C7 /* CoreGraphics.framework */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
+		EE3DB299152A372700390816 /* background_top.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = background_top.png; sourceTree = "<group>"; };
+		EE3DB29C152A39E500390816 /* background_top@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background_top@2x.png"; sourceTree = "<group>"; };
+		EE3DB29E152A3F9300390816 /* background_bottom.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = background_bottom.png; sourceTree = "<group>"; };
+		EE3DB29F152A3F9300390816 /* background_bottom@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background_bottom@2x.png"; sourceTree = "<group>"; };
 		EEC5ED81150E709800F366C7 /* ThumbScrolling.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ThumbScrolling.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		EEC5ED85150E709800F366C7 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
 		EEC5ED87150E709800F366C7 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
 				EEC5EDBC150EA22E00F366C7 /* PPTSView.m */,
 				EEC5EDAE150E802500F366C7 /* PPTSRowView.h */,
 				EEC5EDAF150E802500F366C7 /* PPTSRowView.m */,
+				EE3DB299152A372700390816 /* background_top.png */,
+				EE3DB29C152A39E500390816 /* background_top@2x.png */,
+				EE3DB29E152A3F9300390816 /* background_bottom.png */,
+				EE3DB29F152A3F9300390816 /* background_bottom@2x.png */,
 				EEC5EDAD150E800200F366C7 /* DemoApp */,
 				EEC5ED8C150E709800F366C7 /* Supporting Files */,
 			);
 				EEC5ED9F150E709800F366C7 /* MasterViewController.xib in Resources */,
 				EEC5EDA2150E709800F366C7 /* DetailViewController.xib in Resources */,
 				EEC5EDA9150E718300F366C7 /* dist.male.first.txt in Resources */,
+				EE3DB29A152A372700390816 /* background_top.png in Resources */,
+				EE3DB29D152A39E500390816 /* background_top@2x.png in Resources */,
+				EE3DB2A0152A3F9300390816 /* background_bottom.png in Resources */,
+				EE3DB2A1152A3F9300390816 /* background_bottom@2x.png in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 				EEC5EDA7150E709800F366C7 /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
 		};
 /* End XCConfigurationList section */
 	};

ThumbScrolling/PPTSRowView.h

 #import <UIKit/UIKit.h>
 #import <QuartzCore/QuartzCore.h>
 
-@interface PPTSRowView : UIView
+
+/**
+ *	A view representing one row
+ */
+@interface PPTSRowView : UIView {
+	CGFloat borderWidth;
+}
 
 @property (nonatomic, copy) NSString *text;
 @property (nonatomic, strong) UIFont *font;

ThumbScrolling/PPTSRowView.m

 - (id)initWithFrame:(CGRect)frame
 {
     if ((self = [super initWithFrame:frame])) {
+		borderWidth = 1.f;
         self.backgroundColor = [UIColor whiteColor];
     }
     return self;
 {
 	CGFloat y = [self yForFocusY:focusY inBubble:bubbleSize withDensity:density];
 	CATransform3D t = [self transformForFocusY:focusY inBubble:bubbleSize withDensity:density];
+	//borderWidth = 2.f - (1.f * [self fractionForFocusY:focusY withDensity:density]);
+	//[self setNeedsDisplay];
 	
 	// animate transformation
 	[UIView animateWithDuration:(slow ? 0.3 : 0.05)
 	t = CATransform3DMakeTranslation(0.f, 0.f, myHeight/2);
 	t.m34 = 1.f / (-3 * myHeight);
 	t = CATransform3DRotate(t, -M_PI_2 * foldAmount, 1.f, 0.f, 0.f);
-	CGFloat scale = 0.89f + (expFraction * 0.07f);
+	CGFloat scale = 0.85f + (expFraction * 0.11f);
 	t = CATransform3DScale(t, scale, scale, 1.f);
 	
 	return t;
 }
 
-
+/**
+ *	Returns an exponential fraction between 0 and 1, with 0 for the rows farthest down from focus and 1 farthest up from focus
+ *	@attention targetY must have been set when calling this method
+ */
 - (CGFloat)fractionForFocusY:(CGFloat)focusY withDensity:(CGFloat)density
 {
 	NSUInteger num = 10;
 	CGContextFillRect(ctx, myBounds);
 	
 	// fill with white to leave left, top and right border
-	CGRect fill = CGRectInset(myBounds, 1.f, 1.f);
-	fill.size.height += 1.f;
+	CGRect fill = CGRectInset(myBounds, borderWidth, borderWidth);
+	fill.size.height += borderWidth;
 	CGContextSetFillColorWithColor(ctx, [self.backgroundColor CGColor]);
 	CGContextFillRect(ctx, fill);
 	

ThumbScrolling/PPTSView.m

 
 @property (nonatomic, strong) NSMutableArray *rowQueue;				///< Holds on to unused row objects
 
+@property (nonatomic, strong) UIView *topFakeRows;					///< The view to mimic folded rows on the top
+@property (nonatomic, strong) UIView *bottomFakeRows;					///< The view to mimic folded rows at the bottom
+
 - (void)enqueueRow:(PPTSRowView *)aRow;
 - (PPTSRowView *)dequeueRow;
 
 @synthesize bubbleSize;
 @synthesize offset, density, rowFrame;
 @synthesize rowQueue;
+@synthesize topFakeRows, bottomFakeRows;
 
 
 - (id)initWithFrame:(CGRect)aFrame
 		self.backgroundColor = [UIColor whiteColor];
 		bubbleSize = 80.f;
 		
-		// fake box bottom
+		// fake box background
 		CGRect bottomFrame = CGRectInset([self bounds], 30.f, 20.f);
 		UIView *bottom = [[UIView alloc] initWithFrame:bottomFrame];
 		bottom.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
 		bottom.layer.borderColor = [[UIColor lightGrayColor] CGColor];
 		bottom.layer.borderWidth = 1.f;
 		[self addSubview:bottom];
+		
+		// fake top rows
+		self.topFakeRows = [[UIView alloc] initWithFrame:[self bounds]];
+		topFakeRows.autoresizingMask = UIViewAutoresizingNone;
+		topFakeRows.opaque = NO;
+		topFakeRows.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"background_top.png"]];
+		
+		// fake bottom rows
+		self.bottomFakeRows = [[UIView alloc] initWithFrame:[self bounds]];
+		bottomFakeRows.autoresizingMask = UIViewAutoresizingNone;
+		bottomFakeRows.opaque = NO;
+		bottomFakeRows.backgroundColor = [UIColor clearColor];
+		bottomFakeRows.clipsToBounds = YES;
+		UIView *bgView = [[UIView alloc] initWithFrame:[bottomFakeRows bounds]];
+		bgView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
+		bgView.opaque = NO;
+		bgView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"background_bottom.png"]];
+		[bottomFakeRows addSubview:bgView];
     }
     return self;
 }
 	self.rowQueue = [NSMutableArray arrayWithCapacity:kPPTSViewNumRows];
 	self.rowFrame = CGRectZero;
 	
+	// add top fake rows
+	CGRect fakeFrame = [self bounds];
+	fakeFrame.origin.y = 2.f;
+	fakeFrame.size.height = startY - bubbleSize/3*2 - 6.f;
+	topFakeRows.frame = fakeFrame;
+	[self addSubview:topFakeRows];
+	
 	// add rows for all visible cells at their current position
 	PPTSRowView *active = nil;
 	PPTSRowView *prev = nil;
 		dist++;
 	}
 	
+	// add bottom fake rows
+	fakeFrame = [self bounds];
+	fakeFrame.origin.y = startY + bubbleSize/2 - 6.f;		// 6: manual correction
+	fakeFrame.size.height = fakeFrame.size.height - 2.f - fakeFrame.origin.y;
+	bottomFakeRows.frame = fakeFrame;
+	[self addSubview:bottomFakeRows];
+	
 	return YES;
 }
 
 	
 	// no active row, enqueue everybody (because we don't have a chain link) and dequeue an active one!
 	if (!active) {
-		DLog(@"NO ACTIVE FOR %@", activeIndexPath);
 		for (PPTSRowView *row in [self subviews]) {
 			if ([row isKindOfClass:[PPTSRowView class]]) {
 				[self enqueueRow:row];
 		active.center = CGPointMake(rowFrame.size.width / 2, newY);
 		active.layer.transform = [active transformForFocusY:newY inBubble:bubbleSize withDensity:density];
 		
-		[self addSubview:active];
+		[self insertSubview:active belowSubview:bottomFakeRows];
 	}
 	[active foldWithFocusAt:newY inBubble:bubbleSize withDensity:density slowAnim:beginning];
 	
 	
-	// update later cell values
+	// update lower cell values
 	CGFloat refY = active.targetY;
 	PPTSRowView *lastValid = active;
 	PPTSRowView *next = active.next;
 		[self enqueueRow:previous];
 		previous = prevPrev;
 	}
+	
+	// update fake rows
+	CGRect fakeFrame = topFakeRows.frame;
+	fakeFrame.origin.y = 2.f;
+	fakeFrame.size.height = hitPoint.y - bubbleSize/3*2 - 6.f;
+	topFakeRows.frame = fakeFrame;
+	
+	fakeFrame = [self bounds];
+	fakeFrame.origin.y = hitPoint.y + bubbleSize/2 - 6.f;			// 6: manual correction
+	fakeFrame.size.height = fakeFrame.size.height - 2.f - fakeFrame.origin.y;
+	bottomFakeRows.frame = fakeFrame;
 }
 
 
 		}
 	}
 	
+	// slide fake rows off
+	[topFakeRows removeFromSuperview];
+	[bottomFakeRows removeFromSuperview];
+	
 	return index;
 }
 
Add a comment to this file

ThumbScrolling/background_bottom.png

Added
New image
Add a comment to this file

ThumbScrolling/background_bottom@2x.png

Added
New image
Add a comment to this file

ThumbScrolling/background_top.png

Added
New image
Add a comment to this file

ThumbScrolling/background_top@2x.png

Added
New image
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.