Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Works in landscape orientation now too

  • Loading branch information...
commit 38259e966811f88a8d6763f756bea87c2331cd16 1 parent 629f443
@fictorial authored
View
10 BHTabBarDemo/BHTabBarDemo.xcodeproj/project.pbxproj
@@ -19,10 +19,11 @@
605798F113C4D40500D7494A /* BHTabView.m in Sources */ = {isa = PBXBuildFile; fileRef = 605798EF13C4D40500D7494A /* BHTabView.m */; };
6065447913C6B8CC00A14A88 /* bg.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 6065447813C6B8CC00A14A88 /* bg.jpg */; };
6092E07913C64F73004C03ED /* BHTabStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 6092E07813C64F72004C03ED /* BHTabStyle.m */; };
+ 60F48D6B13CC13AC00E42F17 /* BHTabsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 60F48D6A13CC13AC00E42F17 /* BHTabsView.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
- 604C22BA13C622D800D39052 /* BHTabsFooterView.h */ = {isa = PBXFileReference; fileEncoding = 4; path = BHTabsFooterView.h; sourceTree = "<group>"; };
+ 604C22BA13C622D800D39052 /* BHTabsFooterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BHTabsFooterView.h; sourceTree = "<group>"; };
604C22BB13C622D800D39052 /* BHTabsFooterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BHTabsFooterView.m; sourceTree = "<group>"; };
605798CD13C4C8A800D7494A /* BHTabBarDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BHTabBarDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
605798D113C4C8A800D7494A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
@@ -35,13 +36,15 @@
605798E013C4C8A800D7494A /* BHTabBarDemoAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BHTabBarDemoAppDelegate.h; sourceTree = "<group>"; };
605798E113C4C8A800D7494A /* BHTabBarDemoAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BHTabBarDemoAppDelegate.m; sourceTree = "<group>"; };
605798E413C4C8A800D7494A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = "<group>"; };
- 605798EC13C4D40500D7494A /* BHTabsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; path = BHTabsViewController.h; sourceTree = "<group>"; };
+ 605798EC13C4D40500D7494A /* BHTabsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BHTabsViewController.h; sourceTree = "<group>"; };
605798ED13C4D40500D7494A /* BHTabsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BHTabsViewController.m; sourceTree = "<group>"; };
605798EE13C4D40500D7494A /* BHTabView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BHTabView.h; sourceTree = "<group>"; };
605798EF13C4D40500D7494A /* BHTabView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BHTabView.m; sourceTree = "<group>"; };
6065447813C6B8CC00A14A88 /* bg.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = bg.jpg; sourceTree = "<group>"; };
6092E07713C64F72004C03ED /* BHTabStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BHTabStyle.h; sourceTree = "<group>"; };
6092E07813C64F72004C03ED /* BHTabStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BHTabStyle.m; sourceTree = "<group>"; };
+ 60F48D6913CC13AC00E42F17 /* BHTabsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BHTabsView.h; sourceTree = "<group>"; };
+ 60F48D6A13CC13AC00E42F17 /* BHTabsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BHTabsView.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -120,6 +123,8 @@
604C22BB13C622D800D39052 /* BHTabsFooterView.m */,
6092E07713C64F72004C03ED /* BHTabStyle.h */,
6092E07813C64F72004C03ED /* BHTabStyle.m */,
+ 60F48D6913CC13AC00E42F17 /* BHTabsView.h */,
+ 60F48D6A13CC13AC00E42F17 /* BHTabsView.m */,
);
name = Source;
path = ../Source;
@@ -191,6 +196,7 @@
605798F113C4D40500D7494A /* BHTabView.m in Sources */,
604C22BC13C622D800D39052 /* BHTabsFooterView.m in Sources */,
6092E07913C64F73004C03ED /* BHTabStyle.m in Sources */,
+ 60F48D6B13CC13AC00E42F17 /* BHTabsView.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
14 Source/BHTabsView.h
@@ -0,0 +1,14 @@
+#import <UIKit/UIKit.h>
+
+@class BHTabStyle;
+
+@interface BHTabsView : UIView {
+ NSArray *tabViews;
+ BHTabStyle *style;
+}
+
+@property (nonatomic, retain) NSArray *tabViews;
+@property (nonatomic, retain) BHTabStyle *style;
+
+
+@end
View
39 Source/BHTabsView.m
@@ -0,0 +1,39 @@
+#import "BHTabsView.h"
+#import "BHTabStyle.h"
+
+@implementation BHTabsView
+
+@synthesize tabViews;
+@synthesize style;
+
+- (void)layoutSubviews {
+ NSUInteger N = [self.tabViews count];
+
+ CGFloat W = self.frame.size.width / N;
+ NSUInteger overlap = W * self.style.overlapAsPercentageOfTabWidth;
+ W = (self.frame.size.width + overlap * (N-1)) / N;
+
+ NSUInteger tabIndex = 0;
+
+ for (UIView *tabView in self.tabViews) {
+ CGRect tabFrame = CGRectMake(tabIndex * W,
+ self.style.tabsViewHeight - self.style.tabHeight - self.style.tabBarHeight,
+ W, self.style.tabHeight);
+
+ if (tabIndex > 0)
+ tabFrame.origin.x -= tabIndex * overlap;
+
+ tabView.frame = tabFrame;
+
+ tabIndex++;
+ }
+}
+
+- (void)dealloc {
+ self.tabViews = nil;
+ self.style = nil;
+
+ [super dealloc];
+}
+
+@end
View
5 Source/BHTabsViewController.h
@@ -4,6 +4,7 @@
@class BHTabsViewController;
@class BHTabsFooterView;
@class BHTabStyle;
+@class BHTabsView;
@protocol BHTabsViewControllerDelegate <NSObject>
@optional
@@ -19,13 +20,11 @@
@end
@interface BHTabsViewController : UIViewController <BHTabViewDelegate> {
- NSArray *tabViews;
NSArray *viewControllers;
UIView *contentView;
- UIView *tabsContainerView;
+ BHTabsView *tabsContainerView;
BHTabsFooterView *footerView;
BHTabStyle *tabStyle;
- NSUInteger tabWidth;
NSUInteger currentTabIndex;
id <BHTabsViewControllerDelegate> delegate;
}
View
49 Source/BHTabsViewController.m
@@ -1,8 +1,7 @@
-// TODO I think we might need to handle layoutSubviews too.
-
#import "BHTabsViewController.h"
#import "BHTabsFooterView.h"
#import "BHTabStyle.h"
+#import "BHTabsView.h"
enum { kTagTabBase = 100 };
@@ -10,17 +9,15 @@ @interface BHTabsViewController ()
@property (nonatomic, retain) NSArray *viewControllers;
@property (nonatomic, assign, readwrite) UIView *contentView;
-@property (nonatomic, retain) NSArray *tabViews;
-@property (nonatomic, retain) UIView *tabsContainerView;
+@property (nonatomic, retain) BHTabsView *tabsContainerView;
@property (nonatomic, retain) BHTabsFooterView *footerView;
-@property (nonatomic, assign) NSUInteger tabWidth;
@end
@implementation BHTabsViewController
@synthesize delegate, style, viewControllers, contentView,
- tabViews, tabsContainerView, footerView, tabWidth;
+ tabsContainerView, footerView;
- (id)initWithViewControllers:(NSArray *)theViewControllers
style:(BHTabStyle *)theStyle {
@@ -38,7 +35,6 @@ - (id)initWithViewControllers:(NSArray *)theViewControllers
- (void)dealloc {
self.style = nil;
self.viewControllers = nil;
- self.tabViews = nil;
self.tabsContainerView = nil;
self.footerView = nil;
@@ -48,7 +44,7 @@ - (void)dealloc {
- (void)_reconfigureTabs {
NSUInteger thisIndex = 0;
- for (BHTabView *aTabView in self.tabViews) {
+ for (BHTabView *aTabView in self.tabsContainerView.tabViews) {
aTabView.style = self.style;
if (thisIndex == currentTabIndex) {
@@ -58,7 +54,9 @@ - (void)_reconfigureTabs {
aTabView.selected = NO;
[self.tabsContainerView sendSubviewToBack:aTabView];
}
-
+
+ aTabView.autoresizingMask = UIViewAutoresizingNone;
+
[aTabView setNeedsDisplay];
++thisIndex;
@@ -74,11 +72,10 @@ - (void)_makeTabViewCurrent:(BHTabView *)tabView {
[self.contentView removeFromSuperview];
self.contentView = viewController.view;
-
- self.contentView.frame = CGRectMake(0, self.tabsContainerView.frame.size.height,
- self.view.frame.size.width,
- self.view.frame.size.height - self.tabsContainerView.frame.size.height);
-
+
+ self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
+ self.contentView.frame = CGRectMake(0, self.tabsContainerView.bounds.size.height, self.view.bounds.size.width, self.view.bounds.size.height);
+
[self.view addSubview:self.contentView];
[self _reconfigureTabs];
@@ -107,20 +104,23 @@ - (void)loadView {
[view release];
self.view.backgroundColor = [UIColor clearColor];
+ self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth;
// The view that contains the tab views is located across the top.
CGRect tabsViewFrame = CGRectMake(0, 0, frame.size.width, self.style.tabsViewHeight);
- self.tabsContainerView = [[[UIView alloc] initWithFrame:tabsViewFrame] autorelease];
+ self.tabsContainerView = [[[BHTabsView alloc] initWithFrame:tabsViewFrame] autorelease];
self.tabsContainerView.backgroundColor = [UIColor clearColor];
+ self.tabsContainerView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
+ self.tabsContainerView.style = self.style;
[self.view addSubview:tabsContainerView];
// Tabs are resized such that all fit in the view's width.
// We position the tab views from left to right, with some overlapping after the first one.
- self.tabWidth = frame.size.width / [self.viewControllers count];
- NSUInteger overlap = self.tabWidth * self.style.overlapAsPercentageOfTabWidth;
- self.tabWidth = (frame.size.width + overlap * ([self.viewControllers count] - 1)) / [self.viewControllers count];
+ CGFloat tabWidth = frame.size.width / [self.viewControllers count];
+ NSUInteger overlap = tabWidth * self.style.overlapAsPercentageOfTabWidth;
+ tabWidth = (frame.size.width + overlap * ([self.viewControllers count] - 1)) / [self.viewControllers count];
NSMutableArray *allTabViews = [NSMutableArray arrayWithCapacity:[self.viewControllers count]];
@@ -129,9 +129,9 @@ - (void)loadView {
// The selected tab's bottom-most edge should overlap the top shadow of the tab bar under it.
- CGRect tabFrame = CGRectMake(tabIndex * self.tabWidth,
+ CGRect tabFrame = CGRectMake(tabIndex * tabWidth,
self.style.tabsViewHeight - self.style.tabHeight - self.style.tabBarHeight,
- self.tabWidth,
+ tabWidth,
self.style.tabHeight);
if (tabIndex > 0)
@@ -146,7 +146,7 @@ - (void)loadView {
[allTabViews addObject:tabView];
}
- self.tabViews = allTabViews;
+ self.tabsContainerView.tabViews = allTabViews;
CGRect footerFrame = CGRectMake(0, tabsViewFrame.size.height - self.style.tabBarHeight - self.style.shadowRadius,
tabsViewFrame.size.width,
@@ -155,17 +155,16 @@ - (void)loadView {
self.footerView = [[[BHTabsFooterView alloc] initWithFrame:footerFrame] autorelease];
self.footerView.backgroundColor = [UIColor clearColor];
self.footerView.style = self.style;
+ self.footerView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
+
[self.tabsContainerView addSubview:footerView];
[self.tabsContainerView bringSubviewToFront:footerView];
- [self _makeTabViewCurrent:[self.tabViews objectAtIndex:0]];
+ [self _makeTabViewCurrent:[self.tabsContainerView.tabViews objectAtIndex:0]];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
-// TODO what do I need to do to handle orientation changes?
-// TODO I would think I just need to set the autoresizingMask on each BHTabView to flexibleWidth.
-
@end
Please sign in to comment.
Something went wrong with that request. Please try again.