Loading Alternative UITabBarController for iPhone5 support - iphone

I have to add support for iPhone5 to my app. Currently the appdelegate uses a nib that is a UITabBarController, and code like this. Works fine.
[window addSubview:rootController.view];
[window makeKeyAndVisible];
rootController is an instance of UITabBarController.
So I have created a new nib for iPhone5 and changed the code to...
if ([self IsTall])
rootController = [[[UITabBarController alloc] initWithNibName:#"MainWindow_5" bundle:nil] autorelease];
else
rootController = [[[UITabBarController alloc] initWithNibName:#"MainWindow" bundle:nil] autorelease];
[window addSubview:rootController.view];
[window makeKeyAndVisible];
But, the screen is blank with this code, like the nib is not loading.
If I try this I get the correct nibs loading and displaying on the screen but the "MORE" button is not shown and only the first 4 tabs are shown (there are 7 tabs in the tabBarController
if ([self IsTall])
rootController = [[rootController initWithNibName:#"MainWindow_5" bundle:nil] autorelease];
else
rootController = [[rootController initWithNibName:#"MainWindow" bundle:nil] autorelease];
[window addSubview:rootController.view];
[window makeKeyAndVisible];
I also tried...
if ([self IsTall])
[[NSBundle mainBundle] loadNibNamed:#"MainWindow_5" owner:rootController options:nil];
else
[[NSBundle mainBundle] loadNibNamed:#"MainWindow" owner:rootController options:nil];
But this causes a crash on the tab buttons for the nib not declared in the plist under Main
"nib file base name" setting.
Any help very much greatly appreciated. This has stumped me for a couple of days now.
Kind Regards
Rob.

Miscellaneous thoughts:
iPhone 5 is iOS 6. Was your app working under iOS 6 before? If not, get it working for iOS 6 first. My apps came up blank when linked against iOS 6 even if no other changes were made. That's because view controllers work in a whole different way. So step one is to get the simple of act of launch ironed out for iOS 6. This is particularly true if you are launching into landscape; everything is totally changed in this regard.
Do not add the subview yourself. Just set the window's rootViewController. It adds the subview for you.
On the whole you should NOT be loading a different nib in any case. You should be using layout to lay out the same interface in such a way that it doesn't matter whether the screen is tall or not.
Hope something in there will help...
Your second code is totally illegal. Never never never say "init" except in the very same line where you just said "alloc" (except in an initializer, of course).

Here is the method I use
+ (BOOL)isPad{
BOOL result = NO;
if ([[UIDevice currentDevice] respondsToSelector:#selector(userInterfaceIdiom)]){
result = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad;
}
return result;
}
+ (BOOL) isPhone{
BOOL result = NO;
static NSString *model;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
model = [UIDevice currentDevice].model;
});
if ([model hasPrefix:#"iPhone"]){
result = YES;
}
return result;
}
+ (BOOL)isWidescreen{
BOOL result = NO;
static CGFloat ratio;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
CGSize size = [UIScreen mainScreen].bounds.size;
CGFloat numerator = MAX(size.height, size.width);
CGFloat denominator = MIN(size.height, size.width);
ratio = numerator / denominator;
});
if (ratio > 1.77 && ratio < 1.78){
result = YES;
}
return result;
}
I then have Define statements to make them easier to reach
#define IS_IPAD() [StaticContainer isPad]
#define IS_WIDESCREEN() [StaticContainer isWidescreen]
#define IS_IPHONE() [StaticContainer isPhone]
I also have a UIViewController category
#implementation UIViewController (initHelpers)
- (id) initClassDevice{
NSString *device = #"";
if (IS_IPAD()) {
device = #"iPad";
}
else if (IS_WIDESCREEN()){
device = #"iPhone5";
}
else {
device = #"iPhone";
}
NSString *nibName = [NSString stringWithFormat:#"%#_%#",[self class],device];
self = [self initWithNibName:nibName bundle:nil];
return self;
}
#end
You will need to have a nib file for each one that has the different items in it. and they need to be connected to everything separately.
Mine currently only separates iphone and ipad so for a view controller i would have
MyMagicViewController.h/MyMagicViewController.m
and for the xib files i would have
MyMagicViewController_iPad.xib, MyMagicViewController_iPhone5.xib and MyMagicViewController_iPhone.xib
the important thing is to match the name of the xib file with the call to initWithNibName:
Also Another thing to think of. is the View you are initializing needs to be the same size as the View it is going into .
view.frame = superView.bounds;
then it will fit properly

for me adding Default-568h#2x.png to my project resolved it.

Related

iOS switching view controllers depending on the device orientation

I'm developing an Augmented Reality application, everything worked properly till now that I need two different kind of visualization (AR and Map) depending on the device orientation. In particular the application should use the landscapeViewController when the device is in landscape mode while it should use another controller (named faceUpViewController ) when the device's orientation is "face up". I tried doing it with two simple view controllers and it works fine. The problem happens when the landscapeViewController uses the AR controller. The view is completely white and I don't understand why. Both the two controllers are "contained" by a Root View Controller. I'm doing everything by coding so without nib files. Here is the code:
RootViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(deviceOrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
}
- (void)deviceOrientationDidChange:(NSNotification *)notification{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationLandscapeLeft) {
if (self.landscapeViewController.view.superview == nil) {
if (self.landscapeViewController == nil) {
LandscapeViewController *lvc = [[LandscapeViewController alloc] init];
self.landscapeViewController = lvc;
[lvc release];
}
[self.faceUpViewController.view removeFromSuperview];
[self.view addSubview:self.landscapeViewController.view];
}
}
if (orientation == UIDeviceOrientationFaceUp) {
if (self.faceUpViewController.view.superview == nil) {
if (self.faceUpViewController == nil) {
FaceUpViewController *fvc = [[FaceUpViewController alloc] init];
self.faceUpViewController = fvc;
[fvc release];
}
[self.landscapeViewController.view removeFromSuperview];
[self.view addSubview:self.faceUpViewController.view];
}
}
}
#end
LandscapeViewController.m
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
UIView *landscapeView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
landscapeView.backgroundColor = [UIColor yellowColor];
self.view = landscapeView;
[landscapeView release];
ARController *arC = [[ARController alloc] initWithViewController:self];
arC.landscapeViewController = self;
self.arController = arC;
[arC release];
}
//When the view appear present the camera feed
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[_arController presentModalARControllerAnimated:NO];
}
FaceUpViewController.m
- (void)loadView
{
UIView *faceUpView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
faceUpView.backgroundColor = [UIColor blueColor];
self.view = faceUpView;
[faceUpView release];
}
ARController.m Very simple version
- (id) initWithViewController:(UIViewController *)theView{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
self.rootController = theView;
//Retrieve screen bounds
CGRect screenBounds = [[UIScreen mainScreen] bounds];
UIView *overlaidView = [[UIView alloc] initWithFrame: screenBounds];
self.overlayView = overlaidView;
[overlaidView release];
self.rootController.view = overlayView;
// Initialise the UIImagePickerController
UIImagePickerController *picker= [[UIImagePickerController alloc] init];
self.pickerController = picker;
[picker release];
self.pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
self.pickerController.cameraViewTransform = CGAffineTransformScale(
self.pickerController.cameraViewTransform, 1.0f, 1.12412f);
self.pickerController.showsCameraControls = NO;
self.pickerController.navigationBarHidden = YES;
self.pickerController.cameraOverlayView = _overlayView;
}
return self;
}
- (void)presentModalARControllerAnimated:(BOOL)animated{
[self.rootController presentModalViewController:[self pickerController] animated:animated];
self.overlayView.frame = self.pickerController.view.bounds;
}
#end
I say again that I'm doing everything by coding thereby without nib files.
I really appreciate any advice!
Thanks
The primary problem with adding and removing your "child" view controllers' views as you've done here is that the view controller life cycle methods (viewWillAppear:, viewDidAppear:, etc.) won't ever get called on your child view controllers. Containers like UINavigationController and UITabBarController have always known how to delegate methods like these appropriately to their children, but UIViewController didn't officially support the ability to nest view controllers under your own custom container before iOS 5. It was possible, but it took a lot more work to do it right.
If you want to stick with the approach of adding and removing subviews, you have two options:
Require iOS 5+, and call addChildViewController:, removeFromParentViewController,
transitionFromViewController:toViewController:duration:options:animations:completion:,
willMoveToParentViewController:, and
didMoveToParentViewController: as described in the Implementing a Container View Controller section of the UIViewController Class Reference.
To support older iOS versions, you'll have to override many of the methods of the UIViewController class and delegate those calls manually to your child view controllers to make them behave as expected. I'd pay particular attention to the sections titled, "Responding to View Events", and "Responding to View Rotation Events" in the UIViewController Class Reference.
A different approach for pre-iOS 5 support is to present your child view controllers using presentModalViewController:animated: rather than adding their views as subviews to a container. Apple describes this approach in the View Controller Programming Guide for iOS under the section, Creating an Alternate Landscape Interface. The advantage of this approach is that your child view controllers are officially supported as first-class members of the view controller hierarchy, so UIKit will automatically manage their life cycles appropriately. You won't have to override and delegate all those methods manually.
You might want to try getting your acceptance rate up a little bit - more people would be willing to help you.
Anyway, wild guess: in your root controller, try putting the contents of
deviceOrientationDidChange
into
deviceOrientationWillChange.

Presenting Game Center problems

I am trying to add High Scores in my game, and I don't know why i can't present the Leader boards. I can connect the user and send data. But can't see it.
My Game its in Cocos2d. But my MENU isn't when the user click on Play CCDirector Start
My main windows structure its:
-Navigation Contoller
- Menu -Ui View controller
- Navigation Item
I try to do it like a navigation and push it and crash. Also add it as subview. And crash. My leader boards code
- (IBAction)showLeader:(id)sender {
if ([self isGameCenterAvailable]) {
GKLeaderboardViewController *leaderboardController = [[[GKLeaderboardViewController alloc] init] autorelease];
if (leaderboardController != nil) {
leaderboardController.leaderboardDelegate = self;
//[self presentModalViewController:leaderboardController animated:YES];
[self.navigationController pushViewController:leaderboardController animated:YES];
}
}
}
-(BOOL)isGameCenterAvailable {
// Check for presence of GKLocalPlayer API.
Class gcClass = (NSClassFromString(#"GKLocalPlayer"));
// The device must be running running iOS 4.1 or later.
NSString *reqSysVer = #"4.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);
return (gcClass && osVersionSupported);
}
What could i do?
And another question. Could i put my own effect to present the leader bords scores? Or apple will reject it?
I am trying to do a small framework. So i don't need to codify allot in the Menu Game etc..
Thanks :D
I found how to do this.
menu2Game = [[Menu2Game alloc] initWithNibName:#"Menu2Game" bundle:nil];
menu2Game.wantsFullScreenLayout = YES;
[self.view addSubview:menu2Game.view];
[menu2Game presentModalViewController:leaderboardController animated:YES];
menu2Game its a clean View Controller. Maybe I can create a view controller temporally here. But I need to save it somewhere so i could dismiss it.
It work. But i am trying to do it in a landscape

Universal iOS App : UIWebView in detailViewController does not display content for iPad part

I am working on a Universal iOS Application on Xcode 4. It's my first time trying to create an iPhone/iPad app. I am using the Master-Detail Application Template.
This app is roughly a RSS Feed Reader.
I have followed this tutorial to get the big idea: http://cocoadevblog.com/iphone-tutorial-creating-a-rss-feed-reader
I succeed to make the iPhone part working but i have a problem with the UIWebView in the iPad part.
Here is the code which may not be correct.
From MasterViewController ... :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
if (!self.detailViewController) {
NSDictionary *theItem = [items objectAtIndex:indexPath.row];
DetailViewController *nextController = [[DetailViewController alloc] initWithNibName:#"DetailViewController_iPhone" bundle:nil];
[nextController setDetailItem:theItem];
[self.navigationController pushViewController:nextController animated:YES];
}
}
else {
if (!self.detailViewController){
NSDictionary *theItem = [items objectAtIndex:indexPath.row];
DetailViewController *nextController = [[DetailViewController alloc] initWithNibName:#"DetailViewController_iPad" bundle:nil];
[nextController setDetailItem:theItem];
self.detailViewController = nextController;
}
else {
[self.detailViewController setDetailItem:[self.items objectAtIndex:indexPath.row]];
}
}
}
... to DetailViewController, here is the implementation of setDetailItem: and configureView :
- (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
if (self.masterPopoverController != nil) {
[self.masterPopoverController dismissPopoverAnimated:YES];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
if (_detailItem) {
NSLog(#"webpage creation");
NSString *html = [_detailItem objectForKey:#"title"];
[...html stuff added to html string...]
webView = nil;
webView.delegate=self;
//[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.com"]]];
[self.webView loadHTMLString:html baseURL:nil];
NSLog(#"webView loaded");
}
}
I got a blank screen on the detailView pane when i select a row on the MasterView (MasterView/detailView -> in the universal app case, the iPad app is a splitview style App).
I linked the webView in InterfaceBuilder (for both iPhone/iPad .xib files), i received every NSLog, but i cannot make the UIWebViewDelegate answer me even if i implemented it. Of course, the comment with loading the Google Home page doesnt work either.
UPDATE 25/10/11:
I created an new Universal App, a simple one, where i added a UIWebView and i try to load Google webPage.
I can load the page from the viewDidLoad/viewDidAppear (detailViewController) but not from configureView (detailViewController) which is called when i select a row (fire the setDetailItem in detailViewController).
It is like i cannot modify it after loading the panel. There is something I dont get.
(The code I use to launch a webpage is the same code line than the comment above in configureView)
UPDATE 26/10/11
The webView has no value (null) in configureView (when i try to display it for a selected row). I tried this, which is not working but I (obviously/at least) get a value for webView in that case :
- (void)configureView{
if (_detailItem) {
UIWebView *tempWebView = [[UIWebView alloc] init];
self.webView = tempWebView;
NSLog(#"webpage creation");
NSString *html = [_detailItem objectForKey:#"title"];
[...html stuff added to html string...]
//[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.com"]]];
[self.webView loadHTMLString:html baseURL:nil];
self.webView.delegate=self;//better to add "self" to get it working
NSLog(#"webView loaded");
NSLog(#"%#",self.webView); //i got this : <UIWebView: 0x6a5a550; frame = (0 0; 0 0); layer = <CALayer: 0x6a59750>>
}}
By writting "self.webView.delegate=self;" i got the delegate answering me. However this one produce two answers (??) like if there were two webView running ?:
2011-10-26 10:49:57.089 APPName[18334:f803] didStart Loading web Page
2011-10-26 10:49:59.416 APPName[18334:f803] didStart Loading web
Page
2011-10-26 10:49:59.523 APPName[18334:f803] finished loading web
page
2011-10-26 10:49:59.806 APPName[18334:f803] finished loading
web page
I finally got it working.
However, the only solution i've found is to create another project with STORYBOARD and not xib files, which was I guess the problem.
So i dont really have the answer for my problem, but i guess it is for sure a problem of link in the xib files. But i didnt find it.
With Storyboard, I worked out the iPad version easily, but not the iPhone version... until I found the good tutorial : http://www.youtube.com/watch?v=NHIOx_1mz-Q
So for the Storyboard, i deleted the tableview section (inserted by default) and put this code :
MasterViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
NSLog(#"SELECT ROW IPHONE");
if (!self.detailViewController){
NSDictionary *theItem = [items objectAtIndex:indexPath.row];
DetailViewController *nextController = [self.storyboard instantiateViewControllerWithIdentifier:#"Detail"];
[nextController setDetailItem:theItem];
[self.navigationController pushViewController:nextController animated:YES];
}
}
else {
NSLog(#"SELECT ROW IPAD");
self.detailViewController.detailItem = [self.items objectAtIndex:indexPath.row];
}
}
DetailViewController
- (void)configureView{
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = [self.detailItem description];
self.webView.delegate=self;
NSString *html = #"";
[...html stuff...]
[self.webView loadHTMLString:html baseURL:nil];
}
}
I dont mention it, but i also created and linked webview of course.
If someone find the answer for the xib version of a simple project with TableView linked to a detailView for iPad (on Universal iOS project), i would like to ear it.
I don't know if this will fix your problem completely, but at least this line is suspicious:
webView = nil;
It looks to me like you are setting the webView to nil just before you set the delegate? If it is nil at that point, there is no way that the delegate is going to be set. In fact, when you try to send it any messages, it will just ignore them.
(Also that may be leaking memory.)
A split view controller must always be the root of any interface you create.
The panes of your split-view interface may then contain navigation controllers,
tab bar controllers,…
the split view controller automatically handles most of the rotation behaviors
And we can’t use UISplitViewController inside TabBars !!

Need Help with applicationDidBecomeActive

I have been trying for days to get this code to work, but I have no idea what I am doing wrong. Everytime the app wakes up from sleep, or the user closes the app and opens it again (without closing the app from multitasking), I want a label value to change.
In my applicationDidBecomeActive, I am running a counter, which I want to display on whatever viewcontroller is open at that moment.
Code:
- (void)applicationDidBecomeActive:(UIApplication *)application {
counter = counter + 1;
W1G1 *view1 = [[[W1G1 alloc] initWithNibName:#"W1G1" bundle:nil] retain];
[view1 setlabel];
}
In my viewcontroller W1G1, I have the following code:
Code:
- (void) setlabel {
NSString *string = [NSString stringWithFormat:#"%d", counter];
vocabword.text = string;
}
I have imported W1G1 in my appdelegate, but the code does not run :( Please help!
Thanks
In the AppDelegate.m file, where you have
- (void)applicationDidBecomeActive:(UIApplication *)application {
counter = counter + 1;
W1G1 *view1 = [[[W1G1 alloc] initWithNibName:#"W1G1" bundle:nil] retain];
[view1 setlabel];
}
the variable counter being incremented is confined to the AppDelegate. In other words, your view controller doesn't know that it has been incremented.
I would suggest that you use NSUserDefaults to store the value of counter so that you can easily pass it between these view controllers. Either that, or you could allow for an input into the method setLabel, e.g.
- (void) setlabel:(int)counter {
NSString *string = [NSString stringWithFormat:#"%d", counter];
vocabword.text = string;
}
and then in the AppDelegate you'll want to do:
- (void)applicationDidBecomeActive:(UIApplication *)application {
counter = counter + 1;
W1G1 *view1 = [[[W1G1 alloc] initWithNibName:#"W1G1" bundle:nil] retain];
[view1 setlabel:counter]; // <-- now you're using counter
[self.window addSubview:view1];
}
1) When you say 'the code does not run' do you mean that? That is, if you put NSLogs in applicationDidBecomeActive: and in setLabel does it show the code is run?
2) I would suspect the code is running. But your code won't "show the counter on whatever view controller is open at that moment". Your code creates a new view (view1), but that view won't be displayed. It is not added as a subview to anything. Your code will also leak. You create a W1G1 object, but it is never released and you throw away any reference you have to it.
To achieve what you want, you could add a subview to the application's window. Depending how your app delegate is set up, something like the following should do the trick:
counter++;
W1G1 *viewController1 = [[W1G1 alloc] initWithNibName:#"W1G1" bundle:nil];
[viewController1 setlabel: counter];
[[self window] addSubview: [viewController1 view]]
// you'll want to save a reference to the viewController somehow so you can release it at a later date
Then in W1G1
- (void) setlabel: (int) counter;
{
NSString *string = [NSString stringWithFormat:#"%d", counter];
vocabword.text = string;
}
There are, of course, lots of other approaches you could take towards this problem. And you'll need some strategy for removing the W1G1 view that you are adding at some stage, otherwise you'll just get more and more views added.
Update: You ask (in comments) how to keep track of your viewController throughout lifetime of the app... One approach is to keep track of it in your appDelegate. In the header have something like:
#class W1G1;
#interface MyAppDelegate : : NSObject <UIApplicationDelegate>
{
// other decelerations
int counter;
W1G1 * _myW1G1
}
#property (nonatomic, retain) W1G1* theW1G1
In the .m file include
#synthesize theW1G1 = _myW1G1;
Probably in application:didFinishLaunchingWithOptions: create the viewController, set the property to refer to it, and add its view to the view hierarchy.
W1G1* theViewController = [[W1G! alloc] initWithNibName: #"W1G1" bundle: nil];
[[self window] addSubview: [theViewController view]];
[self setTheW1G1: theViewController];
[theViewController release];
Then when you want to access the viewController again from with the app delegate use [self theW1G1], e.g.
[[self W1G1] setlabel: counter];

TableView obstructed by Titlebar

I'm building my first basic tabbed, application with one of the views as a navigation controller that will display a view controller.
I'm running into an issue at the point the user selects a category from the first tableview as shown in the screenshot: http://www.cl.ly/7YOF
When another instance of the tableviewcontroller is loaded and pushed onto the stack of the navigationcontroller, the table is obstructed by the title bar:
http://www.cl.ly/7ZRz
The table view select logic is below:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
KHCategory *selectedItem = [categoryArray objectAtIndex:indexPath.row];
if (selectedItem.categories.count > 0) {
KHCategoryTableViewController *nextCategoryController = [[KHCategoryTableViewController alloc] init];
nextCategoryController.categoryArray = [[NSArray alloc] initWithArray:selectedItem.categories];
nextCategoryController.title = selectedItem.labelValue;
[self.navigationController pushViewController:nextCategoryController animated:YES];
[nextCategoryController release];
} else {
NSLog(#"show detail view");
}
}
EDIT:
I should be clear that an instance of KHCategoryTableViewController is the root of my NavigationController and the NavController is wired up to the first tab of a TabController.
Two interesting things: it measures 20 pixels down (size of status bar) and your line "nextCategoryController.title = ..." doesn't seem to do anything. So...
1) I assume you haven't used setStatusBarHidden?
2) Looks like navController stuff isn't working. Can you give the code from the appDelegate that creates the tabBar and NavController?
3) Add this code, and try calling [self dumpWindow: #"VDL"] from your Subcategory ViewDidLoad method. I find it invaluable whenever checking whether my view structure is correct.
- (void) dumpWindowFrom:(NSString *) fromText {
[self dumpViews: nil from:fromText];
}
void dumpViewsRecursive(UIView* view, NSString *text, NSString *indent) {
Class cl = [view class];
NSString *classDescription = [cl description];
if ([text compare:#""] == NSOrderedSame)
NSLog(#"%d: %# %# %#", (int)view, classDescription, NSStringFromCGRect(view.frame), view.hidden ? #"Inv" : #"Vis");
else
NSLog(#"%d: %# %# %# %#", (int)view, text, classDescription, NSStringFromCGRect(view.frame), view.hidden ? #"Inv" : #"Vis");
for (NSUInteger i = 0; i < [view.subviews count]; i++)
{
UIView *subView = [view.subviews objectAtIndex:i];
NSString *newIndent = [[NSString alloc] initWithFormat:#" %#", indent];
NSString *msg = [[NSString alloc] initWithFormat:#"%#%d:", newIndent, i];
dumpViewsRecursive (subView, msg, newIndent);
[msg release];
[newIndent release];
}
}
- (void) dumpViews: (UIView *) view {
dumpViewsRecursive (( (!view) ? [[UIApplication sharedApplication] keyWindow] : view), #"" ,#"");
}
- (void) dumpViews: (UIView *) view from:(NSString *) fromText{
dumpViewsRecursive ((!view) ? [[UIApplication sharedApplication] keyWindow] : view, fromText, #"");
}
4) You could always just cheat and add:
CGRect frame = [nextCategoryController.view frame];
frame.origin.y = frame.origin.y+20.0;
[nextCategoryController.view setFrame:frame];
Check the autoResizingMask of your KHCategoryTableViewController's view.
UINavigationController overview at iPhone Dev Center says:
Note: Because the amount of space
available for the custom view can vary
(depending on the size of the other
navigation views), your custom view’s
autoresizingMask property should be
set to have a flexible width and
height. Before displaying your view,
the navigation controller
automatically positions and sizes it
to fit the available space.
This issue became resolved when I built against iOS 4.3 and not iOS 5.