Custom iPhone KeyBoard for SDK 4 (iOS4 OS) - iphone

Old SDK solution:
- (void)modifyKeyboard:(NSNotification *)notification
{
UIView *firstResponder = [[[UIApplication sharedApplication] keyWindow] performSelector:#selector(firstResponder)];
for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows])
for (UIView *keyboard in [keyboardWindow subviews])
if([[keyboard description] hasPrefix:#"<UIKeyboard"] == YES)
{
MyFancyKeyboardView *customKeyboard = [[MyFancyKeyboardView alloc] initWithFrame: CGRectMake(0, 0, keyboard.frame.size.width, keyboard.frame.size.height);
[keyboard addSubview: customKeyboard];
[customKeyboard release];
}
}
Following the above method, I now find that the iOS4 is different. It will not work. I am sure this is due to differences in naming subviews (or the sort). Does anyone know how to get around this same problem, for the iphone SDK 4?

You can have a look at this post:
http://www.neoos.ch/news/46-development/54-uikeyboardtypenumberpad-and-the-missing-return-key
It resolves the issue and works for all version of the SDK

Yes. iOS 4 supports custom input views—you can swap your own MyFancyKeyboardView in for any UIResponder-inheriting class (e.g. UITextField and UITextView)'s keyboard by setting the responder's inputView property.

The 4.1 SDK now has a UIKeyboardTypeDecimalPad which is what you're trying to do, right?

for ios 5, it seems that doesn't work. but when I change the code like this :
change UIKeyboard to UIPeripheralHostView
it works. I hope it's useful for some other developer.

Related

Status Bar Still Showing

I am getting REALLY frustrated!!
I have tried every living possibility to get rid of the UIStatusBar at the top of my app...
I have tried:
Setting Status Bar to "None" in IB
Running [[UIApplication sharedApplication] setStatusBarHidden:YES]; on application launch AND in each scene.
Going to the .plist and changing the value for Status Bar Hidden at Startup: YES
Setting that same value on the home page for the target
Setting - (BOOL)prefersStatusBarHidden
{
return YES;
} in the app delegate
Literally none of this works... It still shows up on all of my views, and it is SUPER frustrating
Thanks again :)
Side note: I'm in xcode 5, developer beta iOS 7 beta 6, but this also happens on my old ios6 and xcode 4 apps
Please try this
//viewDidload
if ([self respondsToSelector:#selector(setNeedsStatusBarAppearanceUpdate)]) {
// iOS 7
[self prefersStatusBarHidden];
[self performSelector:#selector(setNeedsStatusBarAppearanceUpdate)];
} else {
// iOS 6
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
}
// Add this Method
- (BOOL)prefersStatusBarHidden
{
return YES;
}
This code has been taken from this link
What I usually do is add two key-value properties to the Info.plist file.
The properties source code is:
You need to add a method to the view controller, and not to the app delegate as you write.
- (BOOL)prefersStatusBarHidden
{
return YES;
}
As something occured to me!!
for anyone else ,,
Make sure you are modifying the info.plist in the right *TARGET* :/
plus the accepted answer.

Embed youtube video and autoplay on iOS 6 don't work [duplicate]

This question already has answers here:
Can you autoplay HTML5 videos on the iPad?
(7 answers)
Closed 9 years ago.
I'm trying to embed youtube video and autoplay it on my app. The code is not working on iOS6, however it runs on older iOS 5 perfectly.
I do it in this way:
-(IBAction)playVideo:(id)sender {
myWebView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 400)];
myWebView.delegate = self;
[myWebView setAllowsInlineMediaPlayback:YES];
myWebView.mediaPlaybackRequiresUserAction=NO;
[myWebView loadHTMLString:[NSString stringWithFormat:#"<embed id=\"yt\" src=\"%#\" type=\"application/x-shockwave-flash\" width=\"300\" height=\"300\"></embed>", #"http://www.youtube.com/watch?v=TbsXUJITa40"] baseURL:nil];
}
- (UIButton *)findButtonInView:(UIView *)view {
UIButton *button = nil;
if ([view isMemberOfClass:[UIButton class]]) {
return (UIButton *)view;
}
if (view.subviews && [view.subviews count] > 0) {
for (UIView *subview in view.subviews) {
button = [self findButtonInView:subview];
if (button) return button;
}
}
return button;
}
-(void)webViewDidFinishLoad:(UIWebView *)webView {
UIButton *b = [self findButtonInView:webView];
[b sendActionsForControlEvents:UIControlEventTouchUpInside];
}
So- when the webview is loaded, it finds automatically the uibutton and the video starts. I can't understand, why in iOS 6 this method doesn't work anymore. It loads the video, but nothing appears...
Anyone can help me? I'm going crazy to try to solve it...
You need to use JS command. This link should help.
I hope it's not too late for an answer, but it plain simply is not possible in iOS. Like Apple states on it's documentation: https://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/AudioandVideoTagBasics/AudioandVideoTagBasics.html
To prevent unsolicited downloads over cellular networks at the user’s expense, embedded media cannot be played automatically in Safari on iOS—the user always initiates playback. A controller is automatically supplied on iPhone or iPod touch once playback in initiated, but for iPad you must either set the controls attribute or provide a controller using JavaScript.
Please pay attention that the documentation linked above is for Safari in general, not iOS-specific. To me, this was confusing on the first read until I noticed that.
So unfortunately no, for the moment this will not work on iOS.

How to change the orientation of the app without changing the device orientation in iphone app

I want to change the orientation of the app without changing the device orientation in iphone app.
I want to change my view from portraid mode to landscap mode programmatically.
And also want to know that will this be accepted by the apple store or not ?
Thanks
Now I got the solution from other that is as follow
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
when you add this line at that time one warning appear and for remove this warning just add bellow code on you implementation file..
#interface UIDevice (MyPrivateNameThatAppleWouldNeverUseGoesHere)
- (void) setOrientation:(UIInterfaceOrientation)orientation;
#end
and after that in bellow method just write this code if required..
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
But now want to know is this accepted by apple app store or not ?
thanks
use this line for programmatically change orientation...
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
and also when you add this line at that time one warning appear and for remove this warning just add bellow code on you implementation file..
#interface UIDevice (MyPrivateNameThatAppleWouldNeverUseGoesHere)
- (void) setOrientation:(UIInterfaceOrientation)orientation;
#end
and after that in bellow method just write this code if required..
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
// return NO;
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
i hope this help you..
:)
Add a class variable
Bool isInLandsCapeOrientation;
in viewDidLoad
set this flag to
isInLandsCapeOrientation = false;
Add the following function
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (!isInLandsCapeOrientation) {
return (UIInterfaceOrientationIsPortrait(interfaceOrientation));
}else {
return (UIInterfaceOrientationIsLandscape(interfaceOrientation));
}
}
To changing orientation from portrait to landscape, let it happens on a button action
- (IBAction)changeOrientationButtonPressed:(UIButton *)sender
{
isInLandsCapeOrientation = true;
UIViewController *viewController = [[UIViewController alloc] init];
[self presentModalViewController:viewController animated:NO];
[self dismissModalViewControllerAnimated:NO];
}
This works fine for me.
To change Orientation portraid mode to landscap mode use this code
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
use this code for programmatically change orientation...
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
If you want to change the particular view only in landscape..then u can try the following in its viewDidLoad
float angle = M_PI / 2;
CGAffineTransform transform = CGAffineTransformMakeRotation(angle);
[ [self.view] setTransform:transform];
The documentation describes the orientation property as being read-only, so if it works, I'm not sure you can rely on it working in the future (unless Apple does the smart thing and changes this; forcing orientation changes, regardless of how the user is currently holding their device, is such an obvious functional need).
As an alternative, the following code inserted in viewDidLoad will successfully (and somewhat curiously) force orientation (assuming you've already modified you shouldAutorotateToInterfaceOrientation ):
if (UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]))
{
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];
}
Clearly, this does it if the user is currently holding their device in portrait orientation (and thus presumably your shouldAutorotateToInterfaceOrientation is set up for landscape only and this routine will shift it to landscape if the user's holding their device in portrait mode). You'd simply swap the UIDeviceOrientationIsPortrait with UIDeviceOrientationIsLandscape if your shouldAutorotateToInterfaceOirentation is set up for portrait only.
For some reason, removing the view from the main window and then re-adding it forces it to query shouldAutorotateToInterfaceOrientation and set the orientation correctly. Given that this isn't an Apple approved approach, maybe one should refrain from using it, but it works for me. Your mileage may vary. But this also refers to other techniques, too. Check
SO discussion

iOS: How to access the `UIKeyboard`?

I want to get a pointer reference to UIKeyboard *keyboard to the keyboard on screen so that I can add a transparent subview to it, covering it completely, to achieve the effect of disabling the UIKeyboard without hiding it.
In doing this, can I assume that there's only one UIKeyboard on the screen at a time? I.e., is it a singleton? Where's the method [UIKeyboard sharedInstance]. Brownie points if you implement that method via a category. Or, even more brownie points if you convince me why it's a bad idea to assume only one keyboard and give me a better solution.
Try this:
// my func
- (void) findKeyboard {
// Locate non-UIWindow.
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual:[UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
// Locate UIKeyboard.
UIView *foundKeyboard = nil;
for (UIView *possibleKeyboard in [keyboardWindow subviews]) {
// iOS 4 sticks the UIKeyboard inside a UIPeripheralHostView.
if ([[possibleKeyboard description] hasPrefix:#"<UIPeripheralHostView"]) {
possibleKeyboard = [[possibleKeyboard subviews] objectAtIndex:0];
}
if ([[possibleKeyboard description] hasPrefix:#"<UIKeyboard"]) {
foundKeyboard = possibleKeyboard;
break;
}
}
}
How about using -[UIApplication beginIgnoringInteractionEvents]?
Also, another trick to get the view containing the keyboard is to initialize a dummy view with CGRectZero and set it as the inputAccessoryView of your UITextField or UITextView. Then, get its superview. Still, such shenanigans is private/undocumented, but I've heard of apps doing that and getting accepted anyhow. I mean, how else would Instagram be able to make their comment keyboard interactive (dismiss on swipe) like the Messages keyboard?
I found that developerdoug's answer wasn't working on iOS 7, but by modifying things slightly I managed to get access to what I needed. Here's the code I used:
-(UIView*)findKeyboard
{
UIView *keyboard = nil;
for (UIWindow* window in [UIApplication sharedApplication].windows)
{
for (UIView *possibleKeyboard in window.subviews)
{
if ([[possibleKeyboard description] hasPrefix:#"<UIPeripheralHostView"])
{
keyboard = possibleKeyboard;
break;
}
}
}
return keyboard;
}
From what I could make out, in iOS 7 the keyboard is composed of a UIPeripheralHostView containing two subviews: a UIKBInputBackdropView (which provides the blur effect on whatever's underneath the keyboard) and a UIKeyboardAutomatic (which provides the character keys). Manipulating the UIPeripheralHostView seems to be equivalent to manipulating the entire keyboard.
Discaimer: I have no idea whether Apple will accept an app that uses this technique, nor whether it will still work in future SDKs.
Be aware, Apple has made it clear that applications which modify private view hierarchies without explicit approval beforehand will be rejected. Take a look in the Apple Developer Forums for various developers' experience on the issue.
If you're just trying to disable the keyboard (prevent it from receiving touches), you might try adding a transparent UIView that is the full size of the screen for the current orientation. If you add it as a subview of the main window, it might work. Apple hasn't made any public method of disabling the keyboard that I'm aware of - you might want to use one of your support incidents with Apple, maybe they will let you in on the solution.
For an app I am currently developing I am using a really quick and easy method:
Add this in the header file:
// Add in interface
UIWindow * _window;
// Add as property
#property (strong, nonatomic) IBOutlet UIView * _keyboard;
Then add this code in the bottom of the keyboardWillShow function:
-(void) keyboardWillShow: (NSNotification *) notification {
.... // other keyboard will show code //
_window = [UIApplication sharedApplication].windows.lastObject;
[NSTimer scheduledTimerWithTimeInterval:0.05
target:self
selector:#selector(allocateKeyboard)
userInfo:nil
repeats:NO];
}
This code look for when the keyboard is raised and then allocates the current window. I have then added a timer to allocate the keyboard as there were some issues when allocated immediately.
- (void)allocateKeyboard {
if (!_keyboard) {
if (_window.subviews.count) {
// The keyboard is always the 0th subview
_keyboard = _window.subviews[0];
}
}
}
We now have the keyboard allocated which gives you direct "access" to the keyboard as the question asks.
Hope this helps
Under iOS 8 it appears you have to jump down the chain more than in the past. The following works for me to get the keyboard, although with custom keyboards available and such I wouldn't rely on this working unless you're running in a controlled environment.
- (UIView *)findKeyboard {
for (UIWindow* window in [UIApplication sharedApplication].windows) {
UIView *inputSetContainer = [self viewWithPrefix:#"<UIInputSetContainerView" inView:window];
if (inputSetContainer) {
UIView *inputSetHost = [self viewWithPrefix:#"<UIInputSetHostView" inView:inputSetContainer];
if (inputSetHost) {
UIView *kbinputbackdrop = [self viewWithPrefix:#"<_UIKBCompatInput" inView:inputSetHost];
if (kbinputbackdrop) {
UIView *theKeyboard = [self viewWithPrefix:#"<UIKeyboard" inView:kbinputbackdrop];
return theKeyboard;
}
}
}
}
return nil;
}
- (UIView *)viewWithPrefix:(NSString *)prefix inView:(UIView *)view {
for (UIView *subview in view.subviews) {
if ([[subview description] hasPrefix:prefix]) {
return subview;
}
}
return nil;
}

- UIWindow setRootViewController: equivalent in pre 4.0

I started iphone development with 4.0 sdk. I am trying to make my app compatible with 3.2. I realized that -[UIWindow setRootViewController:] is added to the sdk in version 4.0. So instead of it, what should I use in pre 4.0 releases? In other words, what does rootViewController property do in essence except assigning window's primary subview? If I extend UIWindow and redefine the method as below, would it be a problem in future?
- (void) setRootViewController:(UIViewController *)controller
{
if (systemVersion < 4.0)
{
while(self.subviews.count > 0)
[[self.subviews objectAtIndex:0] removeFromSuperview];
[self addSubview:controller.view];
}
else [super setRootViewController:controller];
}
We used to do this:
[window addSubview:[navigationController view]];
That is what it used to be in Apple's samples and still works ok.