I have tried the following code from another application but it doesn't find anything. Why? How to get access to the UIWebView toolbar?
- (UIToolbar *)findVirginWebKeyboardToolbar:(UIView *)parent
{
if ([parent isKindOfClass:[UIToolbar class]]) {
UIToolbar *tb = (UIToolbar *)parent;
if ([tb.items count] == 1 && [((UIBarButtonItem *)[tb.items objectAtIndex:0]).customView isKindOfClass:[UISegmentedControl class]]) {
return tb;
}
}
for (UIView *view in parent.subviews) {
UIToolbar *tb = [self findVirginWebKeyboardToolbar:view];
if (tb) return tb;
}
return nil;
}
- (void)removeKeyboardBar {
UIView *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
keyboardWindow = testWindow;
UIToolbar *toolbar = [self findVirginWebKeyboardToolbar:keyboardWindow/*subviewWhichIsPossibleFormView*/];
if (toolbar) {
itemsArray = [NSArray arrayWithObjects:button1, button2, button3, nil];
[toolbar setItems:itemsArray];
}
}
}
With the following code you should be able to remove the toolbar that is above the keyboard.
-(void)viewWillAppear:(BOOL)animated{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
}
- (void)keyboardWillShow:(NSNotification *)note {
[self performSelector:#selector(removeBar) withObject:nil afterDelay:0];
}
- (void)removeBar {
// Locate non-UIWindow.
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual:[UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
// Locate UIWebFormView.
for (UIView *formView in [keyboardWindow subviews]) {
// iOS 5 sticks the UIWebFormView inside a UIPeripheralHostView.
if ([[formView description] rangeOfString:#"UIPeripheralHostView"].location != NSNotFound) {
for (UIView *subView in [formView subviews]) {
if ([[subView description] rangeOfString:#"UIWebFormAccessory"].location != NSNotFound) {
// remove the input accessory view
[subView removeFromSuperview];
}
else if([[subView description] rangeOfString:#"UIImageView"].location != NSNotFound){
// remove the line above the input accessory view (changing the frame)
[subView setFrame:CGRectZero];
}
}
}
}
}
Related
I am using MBProgressHud to show a loading indicator on a splash view but this does not change with device orientation. My code is:
splashView = [[UIImageView alloc] initWithFrame:self.window.frame];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
splashView.image = [UIImage imageNamed:#"DefaultPad.png"];
}
else
{
splashView.image = [UIImage imageNamed:#"Default.png"];
}
hud = [[MBProgressHUD alloc]initWithView:splashView];
[splashView addSubview:hud];
hud.userInteractionEnabled=NO;
hud.labelText = #"Loading...";
[hud show:YES];
[self.window addSubview:splashView];
[self performSelector:#selector(Load_FirstView) withObject:nil afterDelay:3];
[self.window makeKeyAndVisible];
and I have changed the line in MBProgressHud.m file from
- (void)deviceOrientationDidChange:(NSNotification *)notification {
NSLog(#"in device orientation ");
UIView *superview = self.superview;
if (!superview) {
return;
} else if ([superview isKindOfClass:[UIWindow class]]) { // here changes have done
[self setTransformForCurrentOrientation:YES];
} else {
self.bounds = self.superview.bounds;
[self setNeedsDisplay];
}
}
to:
- (void)deviceOrientationDidChange:(NSNotification *)notification {
NSLog(#"in device orientation ");
UIView *superview = self.superview;
if (!superview) {
return;
} else if ([superview isKindOfClass:[UIImageView class]]) {
[self setTransformForCurrentOrientation:YES];
} else {
self.bounds = self.superview.bounds;
[self setNeedsDisplay];
}
}
How can I get the loading indicator to rotate with device orientation?
In MBProgressHUD.m I changed
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
to
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
The orientation notification had been received, but the statusBar had not rotated yet.
Try This:-
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
//code for portrait
[hud release];
hud = [[MBProgressHUD alloc]initWithView:splashView];
}
else
{
//code for Landscape
[hud release];
hud = [[MBProgressHUD alloc]initWithView:splashView];
}
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight ||
interfaceOrientation == UIInterfaceOrientationPortrait ||
interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
if it does not work..
you can change the UIDeviceOrientationDidChangeNotification with UIApplicationDidChangeStatusBarOrientationNotificationin the source code of MBProgressHUD:-
- (id)initWithView:(UIView *)view {
// Let's check if the view is nil (this is a common error when using the windw initializer above)
if (!view) {
[NSException raise:#"MBProgressHUDViewIsNillException"
format:#"The view used in the MBProgressHUD initializer is nil."];
}
id me = [self initWithFrame:view.bounds];
// We need to take care of rotation ourselfs if we're adding the HUD to a window
if ([view isKindOfClass:[UIWindow class]]) {
[self setTransformForCurrentOrientation:NO];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(deviceOrientationDidChange:)
name:UIDeviceOrientationDidChangeNotification object:nil];
return me;
}
In the above code change UIDeviceOrientationDidChangeNotificationwith UIApplicationDidChangeStatusBarOrientationNotification.
It is just a work-around as rotation issue was always there with MBProgressHud .
I Guess MBProgressHud is giving a lo of problems , you should instead switch to svprogresshud as it handles orientations well
I have subclassed UILabel to provide a copy menu and would like to add some type of effect that makes the UILabel stand out when this menu is displayed.
Right now I am trying to add and remove a border. It works fine however if the user touches the label and then touches outside of the label the border won't disappear although the copy menu does.
After adding some NSLog's it seems like resignfirstresponder is not being called when this occurs. What happens in the responder chain when this happens and how can I get the border to disappear in this event?
Code as follows :
#implementation CopyLabel
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
if(action == #selector(copy:)) {
return YES;
}
else {
return [super canPerformAction:action withSender:sender];
}
}
- (BOOL) canBecomeFirstResponder {
return YES;
}
- (BOOL)becomeFirstResponder {
if([super becomeFirstResponder]) {
self.highlighted = YES;
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setTargetRect:self.bounds inView:self];
[menu setMenuVisible:YES animated:YES];
return YES;
}
return NO;
}
- (BOOL)resignFirstResponder {
if([super resignFirstResponder]) {
self.highlighted = NO;
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setMenuVisible:NO animated:YES];
[menu update];
NSLog(#"Resign");
return true;
}
return false;
}
- (void)copy:(id)sender {
UIPasteboard *board = [UIPasteboard generalPasteboard];
[board setString:self.text];
self.highlighted = NO;
[self resignFirstResponder];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if([self isFirstResponder]) {
[self resignFirstResponder];
}
else if([self becomeFirstResponder]) {
} else {
[self resignFirstResponder];
}
}
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
self.layer.borderColor = [UIColor blueColor].CGColor;
self.layer.borderWidth = 0.0;
if(self.highlighted) {
self.layer.borderWidth = 1.0;
}
}
#end
UIMenuController posts a UIMenuControllerDidHideMenuNotification. When you listen for that notification (using NSNotificationCenter) you can send resignFirstResponder to your Label at the right time.
Example:
- (id)init... {
...
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(editMenuHidden)
name:UIMenuControllerDidHideMenuNotification
object:nil];
...
}
- (void)dealloc {
...
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIMenuControllerDidHideMenuNotification
object:nil];
...
}
- (void)editMenuHidden {
[self resignFirstResponder];
}
...
Hi I have a big problem with iPhone 4.0 OS with this code
if([[keyboard description] hasPrefix:#"<UIKeyboard"] == YES) {
}
in condition UIKeyboard it not working. I try "UILayoutContainerView"
but it not working too.
please.
You can try this code:
- (BOOL) findKeyboard:(UIView *) superView;
{
UIView *currentView;
if ([superView.subviews count] > 0) {
for(int i = 0; i < [superView.subviews count]; i++)
{
currentView = [superView.subviews objectAtIndex:i];
NSLog(#"%#",[currentView description]);
if([[currentView description] hasPrefix:#"<UIKeyboard"] == YES)
{
NSLog(#"Find it");
return YES;
}
if ([self findKeyboard:currentView]) return YES;
}
}
return NO;
}
-(void) checkKeyBoard {
UIWindow* tempWindow;
for(int c = 0; c < [[[UIApplication sharedApplication] windows] count]; c ++)
{
tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:c];
if ([self findKeyboard:tempWindow])
NSLog(#"Finally, I found it");
}
}
- (void)keyboardWillShow:(NSNotification *)note {
[self performSelector:(#selector(checkKeyBoard)) withObject:nil afterDelay:0];
}
And you also need to add this code to function didFinishLaunchingWithOptions in AppDelegate:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
#"<UIPeripheralHostView" will work instead of #"<UIKeyboard"
Dunno why.
Can you tell me then: How to determine the keyboard type in the UIKeyboard class?
I used to use the following code to add a UIToolbar just above the UIKeyboard and being attached to it. I just switched to the iPhone OS 4 and I realized that it's not working anymore.
for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows]) {
for (UIView *keyboard in [keyboardWindow subviews]) {
//print all uiview descriptions
if([[keyboard description] hasPrefix:#"<UIKeyboard"] == YES) {
.. Some code to attach the UIToolbar
}
}
}
I realized that the code does not get into the if statement. I tried printing out all UIView descriptions just above the if and I could not see anything related to UIKeyboard. The code was working fine in OS 3.0 and 3.1. So does anyone have any idea about it?
You should try to use this below code:
- (BOOL) findKeyboard:(UIView *) superView;
{
UIView *currentView;
if ([superView.subviews count] > 0) {
for(int i = 0; i < [superView.subviews count]; i++)
{
currentView = [superView.subviews objectAtIndex:i];
NSLog(#"%#",[currentView description]);
if([[currentView description] hasPrefix:#"<UIKeyboard"] == YES)
{
NSLog(#"Find it");
//add toolbar here
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, -40, 100, 40)];
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Test button" style:UIBarButtonItemStyleBordered target:self action:#selector(buttonClicked:)];
NSArray *items = [[NSArray alloc] initWithObjects:barButtonItem, nil];
[toolbar setItems:items];
[items release];
[currentView addSubview:toolbar];
return YES;
}
if ([self findKeyboard:currentView]) return YES;
}
}
return NO;
}
-(void) checkKeyBoard {
UIWindow* tempWindow;
for(int c = 0; c < [[[UIApplication sharedApplication] windows] count]; c ++)
{
tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:c];
if ([self findKeyboard:tempWindow])
NSLog(#"Finally, I found it");
}
}
- (void)keyboardWillShow:(NSNotification *)note {
[self performSelector:(#selector(checkKeyBoard)) withObject:nil afterDelay:0];
}
And you also need to add this code to function didFinishLaunchingWithOptions in AppDelegate:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
Since you are relying on undocumented behavior, it should be no surprise that it does not work in 4.0 anymore. Use your views' inputAccessoryView property instead, which is the documented way to do this in OS 3.2+.
I want to dismiss keyboard by click dismiss button ,How to build a bar on the keyboard? like this:
(source: alexcurylo.com)
It was answered here. Basically, you send a resignFirstResponder message to the UITextView. Of course, you will put that code on your button's delegate.
Try to put following code. It might work for you.
Put following variables in your viewController.h file
UIToolbar *keyboardToolbar;
id notisender;
BOOL isAlreadyResigned;
float kx,ky,kh,kw;
Now put following code in you viewController.m file.
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated{
isAlreadyResigned=YES;
[self keyboardToolbarShouldShow];
[self keyboardToolbarShouldShow];
[super viewWillAppear:animated];
}
-(void)viewWillDisappear:(BOOL)animated{
[self keyboardToolbarShouldNotShow];
[super viewWillDisappear:animated];
}
#pragma mark keyboardWillShow methods
-(void)keyboardToolbarShouldShow {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardhide:)
name:UIKeyboardWillHideNotification
object:nil];
}
-(void)keyboardToolbarShouldNotShow {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
if(!isAlreadyResigned){
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillNotShow:)
name:UIKeyboardWillShowNotification
object:nil];
[GEEtxtMsg becomeFirstResponder];
}
}
-(void)keyboardWillShow : (NSNotification *)sender {
#try {
// NSLog(#"notification in first view");
for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows]) {
for (UIView *keyboard in [keyboardWindow subviews]) {
NSLog(#"keyboard description - %#",[keyboard description]);
if([[keyboard description] hasPrefix:#"<UIKeyboard"] == YES) {
NSValue *v = [[sender userInfo] valueForKey:UIKeyboardBoundsUserInfoKey];
CGRect kbBounds = [v CGRectValue];
if(keyboardToolbar == nil) {
keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectZero];
keyboardToolbar.barStyle=UIBarStyleBlackOpaque;
keyboardToolbar.tintColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1];
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(dismissKeyboard)];
UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
NSArray *items = [[NSArray alloc] initWithObjects:flex, barButtonItem, nil];
[keyboardToolbar setItems:items];
[items release];
}
[keyboardToolbar removeFromSuperview];
keyboardToolbar.frame = CGRectMake(0, 0, kbBounds.size.width, 45);
[keyboard addSubview:keyboardToolbar];
NSLog(#"x=%f y=%f width=%f height=%f",kbBounds.origin.x, kbBounds.origin.y, kbBounds.size.width, kbBounds.size.height);
kx=kbBounds.origin.x; ky=kbBounds.origin.y;
kh=kbBounds.size.height; kw=kbBounds.size.width;
keyboard.bounds = CGRectMake(kbBounds.origin.x, kbBounds.origin.y, kbBounds.size.width, kbBounds.size.height + 87);
isAlreadyResigned=NO;
for(UIView* subKeyboard in [keyboard subviews]) {
if([[subKeyboard description] hasPrefix:#"<UIKeyboardImpl"] == YES) {
subKeyboard.bounds = CGRectMake(kbBounds.origin.x, kbBounds.origin.y - 45, kbBounds.size.width, kbBounds.size.height);
}
}
}
}
}
} #catch (NSException * e) {
NSLog(#"Problem in keyboardWillShow:%#",e);
}
}
-(void)keyboardWillNotShow : (NSNotification *)sender {
#try {
for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows]) {
for (UIView *keyboard in [keyboardWindow subviews]) {
if([[keyboard description] hasPrefix:#"<UIKeyboard"] == YES) {
// NSValue *v = [[sender userInfo] valueForKey:UIKeyboardBoundsUserInfoKey];
// CGRect kbBounds = [v CGRectValue];
if([[keyboard subviews] containsObject:keyboardToolbar]){
[keyboardToolbar removeFromSuperview];
}
if(!isAlreadyResigned){
isAlreadyResigned=YES;
keyboard.bounds = CGRectMake(kx,ky,kw,kh);
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
for(UIView* subKeyboard in [keyboard subviews]) {
if([[subKeyboard description] hasPrefix:#"<UIKeyboardImpl"] == YES) {
subKeyboard.bounds = CGRectMake(0, 0,0, 0);
}
}
}
}
}
}
} #catch (NSException * e) {
NSLog(#"Problem in keyboardWillShow:%#",e);
}
}
-(void)dismissKeyboard {
[self resignTextFields];
}
-(void)keyboardhide:(NSNotification *)noti {
notisender = noti;
}
Here you can build a bar on a keyboard
Take static toolbar on xib and take one button and put it on toolbar, and make toolbar hidden ,now
write code in your method when you create a toolbar ,like if you want to create toolbar on textview begin editing method then,
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.26];
[tlBar setFrame:CGRectMake(0, 220, 320, 44)];
tlBar.hidden=NO;
[UIView commitAnimations];
}
And when you dismiss keyboard write this method and call this method when toolbar button pressed
-(IBAction)kbAway:(id)sender
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
[tlBar setFrame:CGRectMake(0, 480, 320, 44)];
[UIView commitAnimations];
[txtviewmessage resignFirstResponder];
[txtsubject resignFirstResponder];
[txttemplatename resignFirstResponder];
}
Hope this will help you..