So I have a functional search app that searches through our company directory. Right now the launch screen goes right too the table with a toolbar to search. I want to modify the interface to launch to a google-esque view with just a simple search bar. I have created a new view and viewController but when I try to add it to the window, it says "View is not a member of struct or union". Here is what I am trying to do:
[window addSubview:launchController.view]; //THIS IS THE LINE
[window makeKeyAndVisible];
There was formerly another view in there, but I just tried to substitute the views out. For example: I formerly had another view named "toolbarSearchView" load and that worked. They are both subclasses of UIViewController. Does anyone have an idea of what may be causing this behavior? Thanks!
check if the syntax [launchController view] works. If not, then perhaps launchController isn't a subclass UIViewController.
Or perhaps you declared it as UIViewController launchController; instead of UIViewController* launchController;
Related
I'm sure this has been asked countless times, and I've seen similar questions though the answer still eludes me.
I have an application with multiple view controllers and as a good view controller does its own task. However I find myself stuck in that I can't switch from one view controller to another. I've seen many people say "use a navigation controller" but this isn't what I want to use due to the unwanted view elements that are part and parcel to view controller.
I've done the following and have had limited success. The view controller is switched but the view does not load and I get an empty view instead:
- (IBAction)showLogin:(id)sender
{
PPLoginViewController *login = [[PPLoginViewController alloc] initWithNibName:#"PPLoginViewController" bundle:nil];
PPAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
appDelegate.window.rootViewController = login;
[self.view insertSubview:login.view atIndex:0];
}
Using UINavigationController as a rootViewController is a good tone of creating iOS application.
As i understand unwanted view elements is a navigationBar? You can just hide it manually, setting:
[self.navigationController setNavigationBarHidden:YES];
And about your case, if you want to change you current viewController(targeting iOS 6), you can just present new one:
[self presentViewController:login animated:YES completion:nil];
or add child (Here is nice example to add and remove a child):
[self addChildViewController:login];
Why to set UINavigationController as a root?
1) First of all it makes your application visible viewcontrollers to be well structured. (Especially it is needed on iPhone). You can always get the stack and pop (or move) to any viewController you want.
2) Why I make always make navigation as a root one, because it makes the application more supportable, so to it will cost not so many code changes to add some features to the app.
If you create one (root) viewcontroller with a lot of children, or which presents other viewcontrolls, it will make your code really difficult to support, and make something like gode-object.
Listen to George, UINavigationController is the way to go. Your reasons for not wanting to use it are not valid.
However, the reason your code doesn't work might have to do with the unnecessary line after setting the rootViewController to the login vc.
Per Apple's documentation, setting rootViewController automatically sets the window's view to the view controller's view.
Fairly new to iPhone app development, so this might be really obvious (if so, apologies in advance!)
I'm building an app which has a tab bar. However, when the app first runs and 'launch screen' is shown with 3 UIButtons - each of these buttons points at a view of one of the tabs. What I need to do is:
Close the existing view
Open the selected view
Set the highlighted tab accordingly
This sounds like it should be quite easy, but a few hours of Googling has found nothing!
Thanks for your help,
Kev
Additional:
Sorry - I am using a tabBarController... But instead of immediately launching the tab bar views I'm using the code below to launch the home menu instead.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
homeViewController *splashView = [[homeViewController alloc] initWithNibName:#"homeView" bundle:nil];
[window addSubview:splashView.view];
// [window addSubview:tabBarController.view];
[window makeKeyAndVisible];
return YES;
}
On the home menu there are UIButtons which need to link to individual tabs... Hope this clarifies...
Cheers!
Oh. Then it gets a bit more complex. What you want to do is basically this:
Add a method to your AppDelegate - (void)showTabBarWithSelectedTab:(NSUInteger)tabIndex. In this method, use tabBarController.selectedIndex to select the correct index, then remove homeViewController's view from the window and add tabBarController's view instead.
In homeViewController, have actions for the buttons that calls the newly created AppDelegate method with the correct tab index.
Generally I would say that this adds a bit too much logic to the AppDelegate. Ideally you'd implement this in a new view controller, surrounding and managing both homeViewController and tabBarController. However, having a UITabbarController inside of another view controller isn't officially supported - although you can get it to work anyway.
it's a bit hard to fully understand your question, but it sounds like you should be using UITabBarController instead of the stand-alone view UITabbar. This is essential reading! Good luck
I have a window within an iPhone application, which is displayed modally to allow the user to enter their settings for a web service upon 'first run'.
The text fields have helper text set, and when you tap them the keyboard shows and allows you to enter text.
Unfortunately the text fields do not clear the helper text, show the edit caret or show the text being entered (as in the screenshot below).
Any suggestions?
The window is being displayed with [self presentModalViewController:<controller_name> animated:YES];, which may or may not be the cause of this issue - when I run the UI via the Interface Builder 'test' application the text boxes respond like normal.
Clear when editing begins has been set for both fields.
Thanks in advance!
Edited: More information
After the info Bart Gottschalk provided I thought I should add some more information. First, the application is a Navigation Based Application.
Secondly, the test app Bart recommended worked fine, so that takes the modal window and the view out of the equation.
Third, I was presenting the modal view when the -(void)viewWillAppear... delegate method was being called - which may very well be the wrong place... however I'm not 100% sure if I should be presenting the modal view from within the didFinishLaunchingWithOptions of the App Delegate...
(this is happening on Simulator and iPhone 3.1.3)
In Interface Builder did you check the box for "Clear When Editing Begins"? With that checked the text field should clear any value once the use taps to edit which is the behavior I think you're looking for.
You can also set the same property programatically using clearsOnBeginEditing if that is convenient in your code.
My guess is that you've done this and it's not behaving as you expect. Just checking on this as a first step in helping you debug.
Also, does this happen in both the Simulator and on a testing device?
Bart
Edited Below...
This seems strange. Let's strip away everything but the basics of presenting a modal view when the application starts and see what happens.
I've recreated the most basic app (that I know of) to test presenting a modal view controller at launch and verify that field editing works fine. What happens for you when you do the same/similar in a new project?
Here is what I'm doing:
1) Create a new view-based app in Xcode called "ModalViewTest"
2) Create a new UIViewController with xib called ModalViewController
3) In ModalViewController.h add a method
-(IBAction)closeModalView;
4) In ModalViewController.m add the method implementation as
-(IBAction)closeModalView {
[self dismissModalViewControllerAnimated:YES];
}
5) In the ModalViewController.xib create two text fields and set the placeholder text for each to abcd1234 and confirm that "Clear When Editing Begins" is checked.
6) In the ModalViewController.xib add a button "Close" and set Touch Up Inside to fire "closeModalView"
7) In the application delegate (ModalViewTestAppDelegate) add the following import
#import "ModalViewController.h"
8) In the application delegate (ModalViewTestAppDelegate) applicationDidFinishLaunching add the following after the line containing [window makeKeyAndVisible];
ModalViewController *modalViewController = [[ModalViewController alloc] initWithNibName:#"ModalViewController" bundle:nil];
[viewController presentModalViewController:modalViewController animated:YES];
9) Save everything
10) Build and Run this new app
Does editing of the text fields work as expected? If yes, what is different about how you are building and presenting your modalView? If no, then we'll need to dig further to determine what is going on in your environment.
Second Edit Below...
When creating a navigation-based application I did the following to present the modal view at application start. Does this work for you in both your test app as well as your real app?
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
ModalViewController *modalViewController = [[ModalViewController alloc] initWithNibName:#"ModalViewController" bundle:nil];
[navigationController presentModalViewController:modalViewController animated:YES];
}
Well, I just figured it out, but honestly without the persistence and awesome help from Bart it would have taken much longer and been much more frustrating.
It turns out the problem was that I was using a Window instead of a View in the XIB file. This was why when showing the modal view within the Navigation controller it wouldn't display properly (i.e. only a white screen) and why the UITextField would not work properly when showing the view from the RootViewController.
So, to recap - modal views should have UIView, not UIWindow in the XIB/NIB File.
Thanks for your help Bart!
I have the same problem but in iOS7 only. I solved it by changing the tint color of textField to blue in the Storyboard
I found a strange behavior, and would like to be explained what assertion I am making that is wrong.
In an AppDelegate class of a freshly created WindowBased project, I am adding a UIViewController to the window.
I can do it two different ways:
- with an IBOutlet. In IB, I simply instanced an UIViewController, set its class to TestViewController and connected it (scenario A of the code).
- creating the UIViewController with code (scenario B).
- (void)applicationDidFinishLaunching:(UIApplication *)application {
#define USE_IBOUTLET YES // Comment this line to switch to scenario B
#ifdef USE_IBOUTLET
// Scenario A
[window addSubview:theTestViewController.view];
[window makeKeyAndVisible];
#endif
#ifndef USE_IBOUTLET
// Scenario B
TestViewController *theTestViewControllerProgrammatically;
theTestViewControllerProgrammatically = [[TestViewController alloc] initWithNibName:nil bundle:nil];
// According to Apple: "It is a good idea to set the view's frame before adding it to a window.", so let's do it
[theTestViewControllerProgrammatically.view setFrame:[[UIScreen mainScreen] applicationFrame]];
[window addSubview:theTestViewControllerProgrammatically.view];
[window makeKeyAndVisible];
#endif
}
As I did not do any customization of the object in IB, I should have the same behavior in both scenario.
Scenario A, using the IBOutlet works as expected.
But the scenario B has the following problems:
- The view is not at the right position (20 pixels to high, and covered by the status bar).
- The view doesn't resize properly (for example, try to toggle the In Call Status bar)
Why?
Zip archive of the project here if you want to reproduce the problem: http://dl.dropbox.com/u/1899122/code/ProtoWindowBasedStrangeness.zip
This is going to sound really silly after my long-winded answers, but the problem you're having is simple to fix (programatically).
This line:
[theTestViewController.view setFrame:[[UIScreen mainScreen] applicationFrame]];
Should actually be:
[theTestViewControllerProgrammaticaly setFrame:[[UIScreen mainScreen] applicationFrame]];
You were setting the frame for the VC set by IB, not by the one you created programatically.
Anyway - it's worth noting that all my comments still apply! There are still a few things you'll have to do programmatically if you don't use IB's controller objects (for example, setting up the navigation bar items)
Paul
I have been having a very similar problem to you in that I noticed VC objects are not all created equal! The problem I'm having is setting the navigation bar items, I just can't seem to do it when File's Owner is a view controller object that I instantiate programatically. It only works if I unarchive IB's controller objects.
I downloaded your project and had a play around with it, and it got me thinking some more about what might be going on. I think I can provide a reasonable answer, but not sure if there is a simple solution...
What I believe is going on is that Apple have created these controller objects in IB that are slightly more specialised. One suggestion this might be true is that IB VC objects have an attribute you can set that has no direct corresponding property for a UIViewController class that I can see, so IB's controller objects may have some additional functionality that non-IB UIViewController subclasses can't take advantage of. Given that objects in an .xib are complete 'freeze-dried' objects, Apple may have included all kinds of private attributes we can't see or use in their IB versions of them - this may have some effect on how the objects are initialised.
For example, in your MainWindow.xib, select the IB VC object and you can set attributes on it from the Inspector Palette, such as "Resize View From NIB". If you un-check this and re-run your app, you'll see the VC appear exactly as it does in scenario B. As you can't check this item when from the File's Owner attributes (even though it is as a UIViewController), you're unable to take advantage of whatever is being done by the view controller to give you the behaviour you want.
The result of this is that when you use TestViewController.xib to initialise your VC object in code, none of the IB specific attributes of a VC are set, therefore a bog-standard UIViewController is created, and so things like the "Resize View From NIB" attribute and setting up the navigation items have to be implemented yourself.
I've not yet found a way to take advantage of the functionality that IB's view controllers have when I instantiate them using initWithNibName:bundle:nibBundle (I'm guessing it's all private stuff we can't access), but hopefully this might have given you a starting point...
Of course, I could be completely wrong and someone will make me look like a complete idiot!
Paul
Probably in case B that view is not aware of the presence of a status bar. You need to resize it accordingly and adjust its position to take the status bar into account. That is done by changing the frame (size) and bounds (location) properties of a UIView.
I have the following object structure:
UITabBarController
UINavigationController
UITableViewController
It used to work, but then I added the UITabBarController into the mix and made a bunch of other large changes and somewhere in between it stopped.
So far I have:
created a new project with that structure, and that seems to work OK.
checked that there's only one view with scrollsToTop
tried adding a new UITableViewController directly under UITabBarController... still doesn't work.
One thing that might be of use is that -scrollViewShouldScrollToTop: isn't even being called, even though the table view controller's tableView.delegate is set to the controller.
Just came across this problem myself.
If, like me, you started from the tab bar template Apple provides, then you have to add the following line to applicationDidFinishLaunching: in your app delegate:
[window makeKeyAndVisible];
This one line is what fixed it for me.
I added following line to UITableViewController.
[self.navigationController.parentViewController.view.window makeKeyAndVisible];