Added an example for TUIControl tracking with sliding tabs!

It's pretty fun to play with sliding tabs…. :D
This commit is contained in:
Aditya Nrusimha
2012-09-25 18:18:55 -07:00
parent 039df74764
commit a433398d43
+70 -16
View File
@@ -16,35 +16,89 @@
#import "ExampleTabBar.h"
@interface ExampleTab : TUIView
@interface ExampleTab : TUIControl
@property (nonatomic, assign) CGFloat originalPosition;
@end
@implementation ExampleTab
- (ExampleTabBar *)tabBar
{
// Convinience to call delegate methods, since by default, our
// superview SHOULD be a tab bar, and nothing else. This will
// horribly crash if you add an ExampleTab to anything but a tab bar.
- (ExampleTabBar *)tabBar {
return (ExampleTabBar *)self.superview;
}
- (void)mouseDown:(NSEvent *)event
{
[super mouseDown:event]; // always call super when overriding mouseXXX: methods - lots of plumbing happens in TUIView
// If a tracking event occurs within a tab, we want to move the
// tab around, so return YES.
- (BOOL)beginTrackingWithEvent:(NSEvent *)event {
[self setNeedsDisplay];
// So the tab doesn't move over just on mouse pressed.
self.originalPosition = [self convertPoint:[event locationInWindow] fromView:nil].x;
return YES;
}
- (void)mouseUp:(NSEvent *)event
{
[super mouseUp:event];
// Find the tab that was being dragged- although this isn't the
// most efficient way, this will suffice for now.
- (BOOL)continueTrackingWithEvent:(NSEvent *)event {
// rather than a simple -setNeedsDisplay, let's fade it back out
[TUIView animateWithDuration:0.5 animations:^{
[self redraw]; // -redraw forces a .contents update immediately based on drawRect, and it happens inside an animation block, so CoreAnimation gives us a cross-fade for free
// Offset the tab's x origin by whatever we dragged by.
// Animating it makes it fun if the drag goes pretty far.
CGFloat currentPosition = [self convertPoint:[event locationInWindow] fromView:nil].x;
[TUIView animateWithDuration:0.1 animations:^{
// Setting an ease-in-out animation curve slows down
// the animation at the start and finish, but speeds it up
// during the middle. Just for that "don't slide me!" fun.
[TUIView setAnimationCurve:TUIViewAnimationCurveEaseInOut];
CGRect draggedRect = self.frame;
draggedRect.origin.x += roundf(currentPosition - self.originalPosition);
self.frame = draggedRect;
}];
if([self eventInside:event]) { // only perform the action if the mouse up happened inside our bounds - ignores mouse down, drag-out, mouse up
[[self tabBar].delegate tabBar:[self tabBar] didSelectTab:self.tag];
}
return YES;
}
// Restore tabs to their original condition.
- (void)endTrackingWithEvent:(NSEvent *)event {
// By nature, the event *must* be inside the tab's bounds, otherwise the
// tracking process will not be invoked. If we were dragged, we were NOT
// pressed, so don't call the delegate.
CGFloat currentPosition = [self convertPoint:[event locationInWindow] fromView:nil].x;
if(self.originalPosition == currentPosition)
[[self tabBar].delegate tabBar:[self tabBar] didSelectTab:self.tag];
// Since tracking is done, move the tab back. This whole ordeal lets us
// "stretch" our tabs around.
float originalPoint = self.tag * (self.tabBar.bounds.size.width / self.tabBar.tabViews.count);
[TUIView animateWithDuration:0.2 animations:^{
CGRect draggedRect = self.frame;
draggedRect.origin.x = roundf(originalPoint);
self.frame = draggedRect;
}];
// Rather than a simple -setNeedsDisplay, let's fade it back out.
[TUIView animateWithDuration:0.3 animations:^{
// -redraw forces a .contents update immediately based on drawRect,
// and it happens inside an animation block, so CoreAnimation gives
// us a cross-fade for free.
[self redraw];
}];
}
@end
@interface ExampleTabBar ()
@property (nonatomic, assign) ExampleTab *draggingTab;
@end
@implementation ExampleTabBar
@@ -61,7 +115,7 @@
t.tag = i;
t.layout = ^(TUIView *v) { // the layout of an individual tab is a function of the superview bounds, the number of tabs, and the current tab index
CGRect b = v.superview.bounds; // reference the passed-in 'v' rather than 't' to avoid a retain cycle
float width = b.size.width / nTabs;
float width = (b.size.width / nTabs);
float x = i * width;
return CGRectMake(roundf(x), 0, roundf(width), b.size.height);
};