For my app, I have a UIToolBar that appears above a UIWebView. What I'm attempting to do is remove both the tool-bar and the web-view from the superview when UIBarButtonItem in the tool-bar is clicked.
I've made the tool-bar and web-view properties of my ViewController like so:
#property (nonatomic, weak) UIToolbar *toolBar;
#property (nonatomic, weak) UIWebView *webView;
These views are supposed to be removed when the method below is called
// Remove the toolbar and the webview
- (void)hideToolbarAndWebView
{
[_toolBar removeFromSuperview];
[_webView removeFromSuperview];
NSLog(#"Button clicked");
}
Below is where I'm first creating the bar-button item, and assigning the action to be the hideToolbarAndWebView method:
// Create a bar button and add it to the toolbar. Action is to dismiss the tool-bar and thew web-view.
UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithTitle:#"Close" style:UIBarButtonItemStylePlain target:self action:#selector(hideToolbarAndWebView)];
I know that the bar-button is successfully calling the hideToolbarAndWebView method through logging, but the views are not being removed from the superview. How do I fix this?
EDIT Below is the code where the tool-bar is created. It's inside a method called showToolbarthat is called from the AppDelegate.
// Create a toolbar
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:self.view.bounds];
toolBar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
// Default height is 44 points, but seems to close to the status bar
toolBar.frame = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds),64);
toolBar.barStyle = UIBarStyleBlackTranslucent;
[self.view addSubview:toolBar];
Below is the code that creates the web-view, and calls the above showToolbarmethod:
// Create a web view that displays the update info, and save settings for current version
SWWebViewController *webViewController = [[SWWebViewController alloc] init];
NSString *url=#"http://google.com";
webViewController.URL = url;
webViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self.navigationController presentViewController:webViewController animated:YES completion:nil];
[webViewController showToolbar];
Thanks to #Midhun MP, I realized what I was doing wrong. Instead of trying to use properties, I needed to set toolBar and webView to be global variables:
UIToolbar *toolBar;
UIWebView *webView;
And instead of creating toolBar and webView like so:
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:self.view.bounds];
SWWebViewController *webViewController = [[SWWebViewController alloc] init];
Since the variables were now created, I now only needed to assign them like so:
toolBar = [[UIToolbar alloc] initWithFrame:self.view.bounds];
webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
Then, when I called hideToolbarAndWebView, the toolBar and webView were both removed from the superview.
Related
Have tried [[self jotNotes] resignFirstResponder]; , have tried [self endEditing:YES];
So I have my NoteViewController, which inherits UIViewController, and tries to implement the delegate like so
#interface NOTEController : UIViewController <UITextViewDelegate>
#end
#implementation NOTEController
-(id)init {
self = [super init];
if (self) {
// self.delegate = self; //doesnt let me set this, so i assume i do not do that here
NOTEControllerView * mainView = [[NOTEControllerView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.view = mainView; //just a plain custom uiview subclass its boring and not special
}
return self;
}
#end
and then in the mainView, i have a bunch of sub-views that are basically a square with a UITextView inside.
the squares class is like this, and they're the ones im trying to dismiss the keyboard from, heres where i set the delegate, the dismissKB method, and the UITextView code. Currently, it will log my keyboard method when pressing the done button, but the keyboard is still present. Would really appreciate if anyone could help me understand why
#interface NOTESubview : UIView <UITextFieldDelegate>
#property (nonatomic, weak) id<UITextFieldDelegate> delegate;
-(UITextView *)jotNotes;
#end
#implementation NOTESubview
-(id)initWithFrame:(CGRect)arg1 {
self = [super initWithFrame:arg1];
if (self) {
self.delegate = self;
[self addSubview:[self jotNotes]];
}
return self;
}
-(UITextView *)jotNotes {
UITextView * jotNotes = [[UITextView alloc] initWithFrame:CGRectMake(0, self.frame.size.height/5.7, self.frame.size.width, self.frame.size.height - self.frame.size.height/5.7)];
UIToolbar* keyboardTextViewBar = [[UIToolbar alloc] init];
keyboardTextViewBar.barStyle = UIBarStyleDefault;
[keyboardTextViewBar sizeToFit];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStylePlain target:self
action:#selector(dismissKB:)];
[keyboardTextViewBar setItems:[NSArray arrayWithObjects:flexSpace, doneButton, nil]];
jotNotes.inputAccessoryView = keyboardTextViewBar;
jotNotes.delegate = self.delegate;
return jotNotes;
}
-(void)dismissKB:(UIBarButtonItem *)sender {
//this will log, so im not sure why it wont resign the board no matter what i try
NSLog(#"keyboard attempted to dismiss by %#", sender);
[[self jotNotes] resignFirstResponder];
}
I suspect that when the dismissKB method is called, its actually not the one who is currently the first responder.
However, there's a trick where you can just "dismiss the keyboard" from anywhere in your app. You might wanna give it a try:
[[[[UIApplication sharedApplication] delegate] window] endEditing:YES];
Add the following line where you are trying to dismiss the keyboard:
[self endEditing:YES];
I have two buttons on my navbar. One on the left and one on the right. The button on the left works but the one on the right does not work. If I swap the buttons, recompile and load the issue persist with the right button regardless of which button is in the right spot of the bar.
Also while the left button works as soon as I try to use the right button the left button stops working too.
How do I make the right button work? Below is the code.
UINavigationBar *NavBar = [[UINavigationBar alloc] init];
[NavBar sizeToFit];
[self.view addSubview:NavBar];
UIBarButtonItem *cmdBack = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(cmdBackClicked:)];
UIBarButtonItem *cmdAddDevice = [[UIBarButtonItem alloc] initWithTitle:#"Add Device"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(cmdAddDeviceClicked:)];
UINavigationItem *NavBarItems = [[UINavigationItem alloc] initWithTitle:#"Settings"];
NavBarItems.leftBarButtonItem = cmdBack;
NavBarItems.rightBarButtonItem = cmdAddDevice;
NavBar.items = [NSArray arrayWithObjects:NavBarItems, nil];
The functions for the buttons are these
- (void) cmdBackClicked:(id)sender
{
[self.view removeFromSuperview];
}
- (void) cmdAddDeviceClicked:(id)sender
{
vcAddDevice *ViewAddDevice = [[vcAddDevice alloc] initWithNibName:#"vcAddDevice" bundle:nil];
[ViewAddDevice SetEditDeviceMode:[NSString stringWithFormat:#"No"]];
[self.view addSubview:ViewAddDevice.view];
}
In the .h file I have this.
#import <UIKit/UIKit.h>
#import "vcAddDevice.h"
#interface ViewControllerSettings : UIViewController<vcAddDeviceControllerDelegate, UITableViewDelegate, UITableViewDataSource>
- (IBAction) cmdBackClicked:(id) sender;
- (IBAction) cmdAddDeviceClicked:(id) sender;
#end
I have a button I have created programmatically within a view controller. Once the button is pressed I want it to to use a method to create the popover programmatically.
The button which is created in the ViewDidLoad in my view controller.m
UIView *moreFundInfoView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 540, 620)];
[self.view addSubview:moreFundInfoView];
[moreFundInfoView setBackgroundColor:[UIColor RMBColor:#"b"]];
btnContact = [UIButton buttonWithType:(UIButtonTypeRoundedRect)];
[btnContact setFrame:CGRectMake(390, 575, contactButton.width, contactButton.height)];
btnContact.hidden = NO;
[btnContact setTitle:#"Contact" forState:(UIControlStateNormal)];
[moreFundInfoView addSubview:btnContact];
[btnContact addTarget:self action:#selector(showContactDetails:) forControlEvents:UIControlEventTouchUpInside];
Then I have the method I use when the button is pressed.
-(void) showContactDetails: (id) sender
{
UIViewController *popoverContent = [[UIViewController alloc]init];
UIView *popoverView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 200, 300)];
[popoverView setBackgroundColor:[UIColor RMBColor:#"b"]];
popoverContent.view = popoverView;
popoverContent.contentSizeForViewInPopover = CGSizeMake(200, 300);
UIPopoverController *contactPopover =[[UIPopoverController alloc] initWithContentViewController:popoverContent];
[contactPopover presentPopoverFromRect:btnContact.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES ];
[contactPopover setDelegate:self];
}
What am I missing here? Cause it runs fine, but as soon as I click the button the app crashes. I think it is a delegate issue, but I am not sure. Any advice would be appreciated.
I think this code will help you. You are certainly missing delegate methods
ViewController *viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navigationController];
popover.delegate = self;
popover.popoverContentSize = CGSizeMake(644, 425); //your custom size.
[popover presentPopoverFromRect:button.frame inView:self.view permittedArrowDirections: UIPopoverArrowDirectionLeft | UIPopoverArrowDirectionUp animated:YES];
Just make sure you are not forgetting UIPopover Delegate methods or else application will definitely crash. It is mandatory.
UIViewController *controller = [[UIViewController alloc] init];
[view removeFromSuperview]; //view is a view which is displayed in a popover
controller.view = view;
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:controller];
popover.delegate = self;
[popover presentPopoverFromRect:button.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
All I had to do was change the property from "retain" to "strong" in the .h file and it works, stopped the app from crashing.
Yes, changing property for "retain" to "strong" makes you to hold your picker view object.
I think the problem with your code was, UIPopoverController object gets deallocated automatically when method finishes.
making strong property gets you to strongly point an object.
I am trying to create UIViewController programmatically for ModalView presentation on the main window of the application and in this UIViewController on top i have is Navigation bar with done button to dismiss the view and below the navigation bar it has UITextView.
So my question is that the UITextview which i want to create below the navigation bar will come in the ViewdidLoad Method or i m doing right to show separate medthod to setup textview .
In the Infoviewcontroller.h file have following code:
#import <UIKit/UIKit.h>
#interface Infoviewcontroller : UIViewController <UITextViewDelegate>{
UITextView *textView;
}
#property (nonatomic, retain) UITextView *textView;
#property (nonatomic, assign) UINavigationBar *navBar;
#end
Then in the infoviewcontroller.m file have the following code:
#import "Infoviewcontroller.h"
#implementation Infoviewcontroller
#synthesize textView;
#synthesize navBar;
-(void)dealloc{
[textView release];
[navBar release];
[super dealloc];
}
-(void)setupTextView {
self.textView = [[[UITextView alloc] initWithFrame:self.view.frame] autorelease];
self.textView.textColor = [UIColor redColor];
self.textView.font = [UIFont fontWithName:#"System Bold" size:13];
self.textView.delegate = self;
self.textView.backgroundColor = [UIColor whiteColor];
self.textView.textAlignment = UITextAlignmentCenter;
self.textView.text = #"This is UITextView\nThis is UITextView\nThis is UITextView\nThis is UITextView";
[self.view addSubview: self.textView];
}
- (void)viewDidLoad {
[super viewDidLoad];
navBar = [[UINavigationBar alloc] init];
UINavigationItem *navItem = [[[UINavigationItem alloc] initWithTitle:#"ModalViewControllerTest"] autorelease];
UIBarButtonItem *done = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissView:)] autorelease];
navItem.rightBarButtonItem = done;
navBar.items = [NSArray arrayWithObject:navItem];
[self.view addSubview:navBar];
}
Regarding creation of UINavigationBar programmatically, I found following blog post helpful http://cps.liridesce.com/?p=100. Example overrides loadView rather than viewDidLoad method, but I think in your case using viewDidLoad should have the same effect.
I would also add viewDidUnload where I would set to nil navBar and textView properties.
I'm not quite sure why you need separate setupTextView method, unless you are calling it from different places of your UIViewController. I would just keep everything together in viewDidUnload.
How can I transition from one UIViewController (with bottom toolbar) to another one (without toolbar), so that while the animation is in progress, the toolbar moves away with the first view, meaning that the toolbar stays in it's initial position of the first view?
I've seen this behaviour in "Things" app.
Just to be clear, I am not looking for solutions such as hiding/showing the toolbar inside viewDidAppear.
So, this is a solution I wasn't very happy about, but at the moment it seems as the only one.
The point is to ignore the built in toolbar property of UINavigationController, create separate UIToolbar and place it inside your view controller.
// Create your bar items
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
NSArray *toolbarItems = [[NSArray alloc] initWithObjects: flexibleSpace, nil];
[flexibleSpace release], flexibleSpace = nil;
UIToolbar *customToolbar = [[UIToolbar alloc] init];
[customToolbar sizeToFit];
[customToolbar setFrame:CGRectMake(0.0, self.view.frame.size.height - self.navigationController.navigationBar.frame.size.height - customToolbar.frame.size.height, customToolbar.frame.size.width, customToolbar.frame.size.height)];
[customToolbar setItems:toolbarItems];
[[self view] addSubview:customToolbar];
[customToolbar release], customToolbar = nil;
[toolbarItems release], toolbarItems = nil;
This way the toolbar will slide away with it's view, causing no animation issue such as "white rectangles" or late appearing toolbar when placed in viewDidAppear...
It sounds like you want:
- ( void )viewWillAppear: (BOOL)animated
{
NSArray *items = ... UIBarButtonItem array...;
[ super viewWillAppear: animated ];
[ self setToolbarItems: items animated: animated ];
....
}