I've been doing everything programmatically in the past, but now I'm trying to learn to use Interface Builder. An experience in and of itself.
My problem is with UISearchDisplayController. Just dropping it on top of my UITableViewController (see figure 1) should set up all relevant connections (and I think add it to the tableView header), and as such it should (?) show up when I run the app. But no! Nothing shows up (see figure 2). Has anyone had any similar experiences, or know what the problem might be?
Figure 1
Figure 2
It's a navigation based app - if that makes any difference - with the navigation part of the app set up programmatically like so:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
bookmarksController = [[BookmarksViewController alloc] init];
bookmarksController.managedObjectContext = [self managedObjectContext];
navController = [[UINavigationController alloc] initWithRootViewController:bookmarksController];
[bookmarksController release];
[self.window addSubview:navController.view];
[self.window makeKeyAndVisible];
return YES;
}
Turns out I had to explicitly point out which NIB to load:
bookmarksController = [[BookmarksViewController alloc] initWithNibName:#"BookmarksViewController" bundle:nil];
in the ViewDidLoad method:
self.searchDisplayController.searchBar.hidden = NO;
if that dosen't help then check all the connections in IB.
This a screenshot of the connections of the Files Owner in my tableview xib.
If even this dosen't help, please comment and I will try to figure out something else.
Related
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I'm developing a first iPhone app for iOS 4.x/5.0 and have some confusions on how to comply with the recommended Apple guidelines. I have also attached code snippet.
Here is the scenario:
When the app loads, I want to show the following functionalities in the bottom of the screen: Test, Settings. My first question is do I have to go with a UISegmentedControl or UITabBar? The trickiest part is I don't want the first "Test" tab/button to be selected automatically. I want the user to select the tab/button. Until that happens, I want a timer that runs showing some text. I tried to use a UITabBar and when the app loads, the first "Test" tab is selected and the associated ViewController is shown by default. I circumvented this by pushing a "root view controller" in the "didFinishLaunchingWithOptions" method in the AppDelegate.m. This works and when I click on the "Scores" tab, it pops the "root view controller" and pushes the "test view controller". But if I select the "Settings" tab immediately after the app loads and click on the "Test" tab, the view controller for the "Test" tab is not loading at all, but the "main view controller" is still displayed. I also have a UINavigationController in place on the "Test" tab and I hide it in the "viewDidAppear" event. I also want to eliminate the animation (pushing back) when I click on the "Test" tab.
My confusions are:
Can I replace the UINavigationController with some other control to let the user click on a "Start/Stop" button (displayed on the top) when in the "test view controller"?.
Is there a click event on the tabs in the UITabBar for each of the tabs?
I wanted to do everything from code (except adding controls) to ViewControllers. It looks confusing to me to use IB to do the same thing. Is this is a bad approach?
The following is the code snippet:
AppDelegate.m
#import "NavTabTestAppDelegate.h"
#import "RootViewController.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
#implementation NavTabTestAppDelegate
#synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
RootViewController *rootViewController = [[RootViewController alloc ] initWithNibName:#"RootViewController" bundle: nil];
[rootViewController.view setBackgroundColor:[UIColor blueColor]];
// [rootViewController setTitle:#"RootViewController"];
FirstViewController *firstViewController = [[FirstViewController alloc ] initWithNibName:#"FirstViewController" bundle: nil];
[firstViewController.view setBackgroundColor:[UIColor yellowColor]];
[firstViewController setTitle:#"FirstViewController"];
SecondViewController *secondViewController = [[SecondViewController alloc ] initWithNibName:#"SecondViewController" bundle: nil];
[secondViewController.view setBackgroundColor:[UIColor redColor]];
[secondViewController setTitle:#"SecondViewController"];
//create the navigation controller and use NavRootController as its root
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:firstViewController];
//create an array of views that will be passed to our tabbar
NSArray *viewsArray = [NSArray arrayWithObjects:nav, secondViewController, nil];
//Now create our tab bar controller
UITabBarController *tabbarController = [[UITabBarController alloc] init];
//then tell the tabbarcontroller to use our array of views
[tabbarController setViewControllers:viewsArray];
[nav pushViewController:rootViewController animated:NO];
//nav.view.hidden = YES;
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
//then the last step is to add the our tabbarcontroller as subview of the window
self.window.rootViewController = tabbarController;
return YES;
}
RootViewController.m (added the following code)
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:animated];
// NSLog(#"Inside RootViewController.m viewWillAppear %#", animated);
}
- (void) viewWillDisappear:(BOOL)animated{
// NSLog(#"Inside RootViewController.m viewWillDisappear %#", "Done");
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
FirstViewController.m (added the following code to prevent the animation but didn't work)
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:NO];
[self.navigationController setNavigationBarHidden:NO animated:NO];
// NSLog(#"Inside FirstViewController.m viewWillAppear %#", animated);
}
- (void) viewWillDisappear:(BOOL)animated{
// NSLog(#"Inside FirstViewController.m viewWillDisappear %#", "Done");
[super viewWillAppear:NO];
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
NSLogs throws exception when I click on a tab (BAD_ACCESS). Couldn't figure out why.
I come from a Windows developer background and I apologize for the long post. Please help.
Thanks.
My first question is do I have to go with a UISegmentedControl or
UITabBar? The trickiest part is I don't want the first "Test"
tab/button to be selected automatically.
I think you're missing the point of UITabBarController. Its job is to let the user select one of several different views, and it manages the view controllers corresponding to those views. One of the views will always be selected -- it really doesn't make sense to have no tab selected. If you want the "tabs" to do something other than select a view, you should use something else, such as UIToolbar or perhaps UISegmentedControl.
Can I replace the UINavigationController with some other control to let the user click on a "Start/Stop" button (displayed on the top)
when in the "test view controller"?.
I had a hard time grokking what you're trying to do with the navigation controller, so it's hard to say whether or not you can replace it. You should understand, though, that UINavigationController is a view controller, not a control. If you're just talking about the navigation bar that's provided by the navigation controller, then sure, you can display that or not depending on your preference.
Is there a click event on the tabs in the UITabBar for each of the tabs?
The tab bar delegate should implement the UITabBarDelegate protocol, which includes – tabBarController:didSelectViewController:.
I wanted to do everything from code (except adding controls) to
ViewControllers. It looks confusing to me to use IB to do the same
thing. Is this is a bad approach?
Depends on who you ask. Most experienced Objective-C programmers use IB when it's appropriate, i.e. just about any time you need to define a relatively static user interface.
Some people prefer not to use IB, but it seems to me that most of those folks never really took the time to learn how to use IB. You should do whichever you prefer.
I'd say that avoiding a useful tool because you don't understand it might be reasonable in the short term, but is a poor approach over the long term. When you're just learning to program on a whole new platform, it's quite reasonable to limit the number of things you need to know. IB really isn't complicated, though, and it's very useful. If you don't use it right now, make a note to yourself to spend some time working with it in the future.
Hihi all,
I am trying to make use of tabbar control in my iphone application, I have a few enquiries regarding the control.
If i create a tabbar template project, in my application delegate, it loads all the 5 tab controllers during the launch of the application, will this cause any inefficiency of the memory usage?
Can I actually drag the tabbar control into each of my screen, and manually switch between screens with [self presentedViewController..] and [self dismissModalViewControllerAnimated...] methods?
What is the most efficient way of using tabbar in iphone app?
Thanks in advance!
:)
Even though I'm not sure what 'most efficient' means in your context, I'll try to explain 3. with explaining what I usually do when it comes to typical tabbar apps:
I don't go with the sample project, because there's so much magic (to me) in all that IB stuff (and I had hard experiences in trying, to combine tabbar controllers and navigation controllers).
I just set up a simple project, get rid of all IB stuff and do something like that in the app delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSMutableArray *cons = [[NSMutableArray alloc ]init];
viewController = [[UITabBarController alloc] init];
int i = 0;
UIViewController *firstController = [[SomeViewViewControllerClazz alloc] init];
firstController = [[UITabBarItem alloc]initWithTitle:#"Een" image:nil tag:i];
[cons addObject:firstController];
[firstController release];
i++;
UIViewController *secondController = [[AnotherViewControllerClazz alloc] init];
secondController = [[UITabBarItem alloc]initWithTitle:#"Twej" image:nil tag:i];
[cons addObject:secondController];
[secondController release];
i++;
UIViewController *thirdController = [[WhateverViewControllerClazz alloc] init];
thirdController = [[UITabBarItem alloc]initWithTitle:#"Drej" image:nil tag:i];
[cons addObject:thirdController];
[thirdController release];
i++;
viewController.viewControllers = cons;
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
That way I've maximum freedom to do whatever I want with the controllers but also have the built in power of tabbars.
1.: That way I never had memory issues even though I load controllers right at the beginning.
2.: If the tabbar idea fits your app, use it as iOs provides it.
The answer of your enquiries are:
No, this will not cause any inefficiency of the memory usage. But you should release tab bar controller
You may be do this, But it is not good practice and when you call presentedViewController tab will be vanished (sorry for inappropriate term).
The most efficient way of using tabbar in iphone app is take a tabbar controller and add that tabBar view.
I'm fairly new to Objective-C and iPhone programming so I apologize if this is a newbie question. I have a simple application that needs to go from one view, to another. The first view is a UIViewController. I set up the xib file in IB (i.e. dragged some buttons onto the window) and hooked up all the buttons (which all work). I then created another xib file and class (also a UIViewController) and hooked them up. When a button is pressed in the first view I want to load the second view. Here's the code that is supposed to be pushing the view:
-(IBAction)createAccount:(id)sender{
CreateAccountViewController*acctView = [[CreateAccountViewController alloc] initWithNibName:#"CreateAccount" bundle:nil];
[self.navigationController pushViewController:acctView animated:YES];
[acctView release];
}
But this does nothing. When I put print statements in the createAccount method those are printed (I can click the button any number of times and it never crashes) but the acctView is never pushed. When I print out the value of self.navigationController it returns null. It's even stranger because if I present the acctView modally then it works.
-(IBAction)createAccount:(id)sender{
CreateAccountViewController*acctView = [[CreateAccountViewController alloc] initWithNibName:#"CreateAccount" bundle:nil];
[self presentModalViewController:acctView animated:YES];
[acctView release];
}
This works just fine, but I don't want to use the view modally. I'm completely lost here. In the past couple of hours I've come across a lot of posts saying to do something with a UINavigationController and hook that up to my view, but how do I do that? Any help is greatly appreciated! Thanks.
It seems you haven't created a UINavigationController for your app.
Best thing would be starting from scratch with a new Xcode project, taking care of choosing a Navigation Based application. In this way you will get almost everything already set up for you.
If you don't like this approach, you can create programmatically your UINavigationController. Here you find a tutorial for doing that.
If you prefer more straight-to-the-point instructions, here they are:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
MainPageDialog *overviewViewController = [[MainPageDialog alloc] initWithNibName:#"MainPage" bundle:nil];
self.navigation = [[[UINavigationController alloc] initWithRootController:overviewViewController] autorelease];
[overviewViewController release];
[window addSubview:[navigation view]];
[self.window makeKeyAndVisible];
return YES;
}
whereby self.navigation is a retained property in your appDelegate.
EDIT:
This answer was quite old, therefore an update:
If you are using ARC, you should be using a strong (vs. retain) property and you would not need the autorelease;
if you target iOS > 4.0 (which is also implied by the above point), you can use the rootViewController property in UIWindow and say:
MainPageDialog *overviewViewController = [[MainPageDialog alloc] initWithNibName:#"MainPage" bundle:nil];
self.window.rootViewController = [[[UINavigationController alloc] initWithRootController:overviewViewController] autorelease];
[overviewViewController release];
[window addSubview:[self.window.rootViewController view]];
[self.window makeKeyAndVisible];
without the need for any navigation property.
I would like to clear a view before an application is switched away from, to change the launch image so that the next time the app is entered it will not display some insecure data.
iOS 4 provides applicationDidEnterBackground and applicationWillResignActive...however, neither of these seem to be able to prevent the screenshot from being taken before I have a chance to clear the view.
-applicationDidEnterBackground does get called before the screenshot. Turns out I was simply hiding my view improperly.
A simple way to clear the view was to set the hidden property on my UIView.
Just to add a snippet of code for a fast solution to this problem using a full background image declared on the initialization and hiding it.
You can do a more sofisticated hide of the particular contents of each view by registering to the notification, and in the views hide the particular views (labels) you want to hide.
Another solution is to check which viewcontroller is showing and switch between differente screenshots of the view of this viewcontroller without the data shown.
The easiest way:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIImageView *backgroundView_ = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Default.png"]];
self.backgroundView = backgroundView_;
[backgroundView_ release];
// Add other controllers views
// ...
[self.window bringSubviewToFront:self.backgroundView];
self.backgroundView.hidden = YES;
[self.window makeKeyAndVisible];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
self.backgroundView.hidden = YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
self.backgroundView.hidden = NO;
}
I'm having a problem making a universal app... In the application delegate I set up the main navigation for ipad and iphone:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
window = [[UIWindow alloc] initWithFrame:[ [UIScreen mainScreen] bounds]];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// The device is an iPad running iPhone 3.2 or later.
[self putSplitView];
} else {
[self putTabBar];
}
[window makeKeyAndVisible];
return YES;
}
- (void)putSplitView {
RootiPadViewController *rootiPadViewController = [[RootiPadViewController alloc] init];
UISplitViewController *splitController = [[UISplitViewController alloc] init];
splitController.viewControllers = [NSArray
arrayWithObjects:rootiPadViewController.seccionesView,
rootiPadViewController.noticiasView,
nil];
[window addSubview:splitController.view];
}
- (void)putTabBar {
TabBarController *tabBar = [[TabBarController alloc] init];
[window addSubview:tabBar.view];
}
RootiPadViewController is in charge of loading data an generating the panes for the splitView, so that its initialization incorporates a modalView with a loader, such that:
#implementation RootiPadViewController
#synthesize seccionesView, noticiasView;
- (id)init {
if ((self = [super init])) {
SeccionesVC_iPad *sec = [[SeccionesVC_iPad alloc] init];
NoticiasVC_iPad *not = [[NoticiasVC_iPad alloc] init];
self.noticiasView = not;
self.seccionesView = sec;
Init *initVC = [[Init alloc] init];
[self presentModalViewController:initVC animated:YES];
}
return self;
}
The code compiles without warnings, but for some reason the loadView method of initVC is never called and the modal view doesn't appear...
Any ideas why this might be happening?
thanks for your help!
Antonio
I know this is last year's question, but while I think I found the cause, I'm still trying to figure out a good non-hack solution for dealing with this.
Assuming you're working for iPad:
Upon initialization, splitViewController Master's viewDidLoad is called first, then the Detail's viewDidLoad.
If you attempt to put a modal window initializer in the Master's viewDidLoad, nothing seems to happen: This is because the Detail's viewDidLoad has executed after your modal view's viewDidLoad, resulting in your modal view being hidden away.
Breakpointing the modal view class, I see it enter initWithNibName in the modal view. I don't use ARC and here I assume your modal view doesn't dealloc until the program quits - The modal view is still there, but there's no way to get to it.
In iPhone:
Disregard this - because there is NO splitViewController for the iPhone. In fact, the default Universal splitViewController project treats the Master and Detail view as separate pages. So at application init, all you have to worry about is the Master viewDidLoad.
This is why, in a Universal project, pushing a modal view in viewDidLoad works as intended in the iPhone emulator, but NEVER in the iPad emulator.
Note that this only applies during the viewDidLoad stage; if you push a modal view AFTER viewDidLoad into the Master window, the modal view works as intended.
Maybe you should present your modal ViewController from the RootViewController 'ViewDidLoad' method, instead of the 'init' method... Not sure the view hierarchy is created that soon