I'm creating a generic reusable UIViewController component that people can add to their applications. It requires a navigation bar at the top where it will add some buttons.
I can easily create a navigationBar and add the buttons, but if the developer using my component is adding the view as part of an existing navigation structure, they might end up with 2 navigation bars.
In other words, if my view is loaded with:
[self.navigationController pushViewController:controller animated:YES];
then it should not add a navigationbar and use what's already there. If the view is loaded with:
[self presentModalViewController:controller animated:YES];
then it should add its own navbar.
Without requiring the developer that uses my controller to do something like a useNavBar:YES, is there a way to do this automatically?
Something like a [self isRunningInsideANavigationController] or [self hasNavigationBar] would do.
You could use self.navigationController for that purpose. It will return nil or the navigationController.
Related
New to iOS dev. Kindly correct me if i am wrong?
I have a UIWindow, and rootviewcontroller is :
#interface ViewController : UIViewController
{
IBOutlet UIButton *but;
}
#property (nonatomic, strong) UIButton *but;
-(IBAction) butButtonPressed;
#end
ie: If i make this Viewcontroller as a root view controller, the UIView that is available in the ViewController is displayed. Understood.
I have created a new class inherited from UIViewController, and along with its .xib file.
So xib file name is : view1.xib,
My Objective is to display this view when the button is pressed.
Now i have created a button and button press invokes butButtonPressed. Inside of butButtonPressed, i did the following.
myViewController *vcontroler = [[ViewController alloc] initWithNibName:#"view1" bundle:nil];
[self.view.window addSubview:vcontroler.view];
Application crashes. What am i doing wrong ? Kindly point out.
This...
[self.view.window addSubview:vcontroler.view];
...is a really bad strategy (and I seriously wish I knew where people are finding it as a way of showing views). If you create a view controller, you should use it rather than just treating it as a temporary container that you can rip views out of.
If you want vcontroler to look like a child of your first controller (and you have a UINavigationController), use pushViewController:animated:. Otherwise you can show it as modal with presentModalViewController:animated:.
If you only want to add a view to the existing display, put the view in ViewController's hierarchy and show/hide it.
If you absolutely must have it as a sub-controller of ViewController then you need to keep a reference to it and manage its lifecycle inside the owning controller.
I have seen scattered information related to this subject across stackoverflow and other sites, but nothing comprehensive. I've wasted hours upon hours trying to get this to work to no avail. However, I see in this post on stackoverflow (http://stackoverflow.com/questions/7909906/extracting-nibs-xibs-from-storyboards-ios), but nothing with step by step details.
I have only a single view controller (HomeViewController) in my storyboard, and it is extended from a navigation controller.
Can someone please help me identify exactly what all needs to happen to make this work?
Please correct me, add to, etc to make these steps correct:
Create a new XIB (say, HomeViewController.xib)
Copy all items from the storyboard's view controller into this xib
Set the Class type for the view controller to be HomeViewController class.
Hook up all of the IBOutlets and IBActions.
?? - Should I make the xib contain a navigation controller which contains the UIViewController, or should I set the File's Owner to the HomeViewController class??
Add new Window property in the AppDelegate class.
Create a new MainWindow.xib. What setup needs to happen here? (a) File's Owner to UIApplication; (b) Drag new Object to the "Objects" panel and set it's class to my AppDelegate class; (c) Drag new Window to the "Objects" panel; (d) Connect the IBOutlet for the AppDelegate Window property to this new window object.
Go to the project settings (click on the project in the Project Navigation tab, select the target), and clear the "Main Storyboard" field and set the Main Interface to what? HomeViewController? Or Main Window?
Make the change in the AppDelegate class as shown below:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
//self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
This is all I know to do, but it still doesn't work. What am I missing?
In my app i have one UIViewController and there are many UIView which i want to load on particular action (for instance BTN Tap) so how can i achieve this programatically .
if any one has solution please let me know.
Thnx in advance
you can bind all the views using IBOutlet like suppose you have view1 and view2 and one default view. Now you want to display view1 on btnTap then you can do like this [self.view addSubview:view1]; make sure to bind the view using IBOutlet
You can use the addSubview method of UIView, like this:
[controller.view addSubview:subview];
where controller is your UIViewController (of course, if you are putting that code inside of it, your controller is self).
In my windows based applicaton, after login screen and registration page I added navigation controller for next two views. After pressing button present on second navigation window,again i want normal view controller and not navigation. But Its giving me navigation window with back button which takes me to second navigation window.
Can anyone plz tell me the solution??
You have a couple choices: you can truly eliminate the Navigation Controller entirely and replace it with another UIViewController (more complicated), or you can just push a new UIViewController that will not have a navigation bar/back button, and use that as the effective "root" view controller of your application from there on out. Without the navigation bar, your view controller will look like a "normal" view controller.
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBar.hidden = YES;
...
}
Does any one have an idea how to access the UIScroller class , which is the default subview of UIWebView ?
I want to handle the touches, zooming , panning and scrolling features inside the webview .
Thanks..
I know this thread is old but if anyone comes across it there's a new way.
As of iOS 5 UIWebView now has a property called scrollView which you can't replace but you can set the properties of it. Most people just want to disable zooming/bouncing/scrolling all together which can be done by setting the properties of the scrollView for example if webview is a UIWebView:
webview.scrollView.bounces = NO; //Disables webview from bouncing
webview.scrollView.minimumZoomScale = webview.scrollView.maximumZoomScale = 1.0; //Forces zoom to be at 1 (can be whatever you fancy) and disables zooming
webview.scrollView.bouncesZoom = NO; //Disables bouncing when zooming exceeds minimum or maximum zoom
I suppose you could set the delegate for the scrollView if you want more control, though to be on the safe side you might want to store the original delegate and call its methods appropriately in your custom delegate.
Handling the touches would be more difficult since you can't replace the scrollView to provide your own handlers. Best you could do is add some gesture recognizers as part of the UIView and try to handle them there, but I think UIWebView will still receive the events. Alternatively in iOS 5 they let you access the gesture recognizers directly on UIScrollView.
You can find this by going like this:
[webview objectAtIndex:0]
That should be where it is. If not, put this in your code somewhere and run the program to search for the index of the UIScroller, and replace the 0 above with that index:-
for (UIView *subview in [webView subviews]){
NSLog(#"subviews of webView : %#", [[subview class] description]);
}