Get Instance of iOS Keyboard Without First Responder - ios

My application uses Cordova so a number of functions are performed in the webview.
There is an object in one of my webviews that brings up the keyboard.
All the documentation and SO answers on changing the keyboard involve setting the values of the first responder. My problem is, on the native side, I do not have the first responder.
So my question is:
Can I get access to the keyboard object without the first responder, and if so how?
Swift/Obj-c answers welcome

You can use UIReturnKeyType for native controls, but unfortunately there is no way to control the return key for text fields within a webview. You might be able to figure out some sort of hacky solution though.
One idea is to manually modify the keyboard views. There's an Apache plugin that uses this to hide the form accessory bar on keyboards. You can see how they do it here. You would have to find the return key's view instead of the form bar though. Of course this isn't supported and is likely to break at some point.
Another option might be to use swizzling to modify UIWebView to use the UIReturnKeyType you want. You'd have to look into dumping the headers to find a possible starting point. This option also has the potential to break along with a chance Apple rejects your app.

Related

Want to text input in custom keyboard extension

I'm making ios keyboard extension and it contains view which has a TextField, but I realized this view is keyboard itself...
To input text in this TextField, what is the best solution?
That's all I can come up with at the moment(I don't know it's possible or not)
Call native keyboard and get a callback on complete input. (It looks impossible)
Use some awesome keyboard library that can be imported to view. (It looks the best solution, or do I need make keyboard scratch...?)
Move container app and back on complete to input. (It's not preferred, because I want complete all on keyboard)
Probably, it's a very rare case, hope someone helps...
thanks!

Customising the Decimal pad in my app

Swift...
So I've got an existing app and I'm working on its appearance. The current task is customising the decimal pad that pops up when the user hits a textField.
I've looked around on how to make it but it always seems that you have to go into the iPhone/ipad settings and add the custom keyboard.
eg. This StackOverFlow Question
and they all seem to point to this same tutorial..
iOS 8: Creating a Custom Keyboard
My problem is that I don't want the user to have to go into settings.
So the question is....IS THIS POSSIBLE?
The following pic is what I want to use. I have made this in an XIB file through adding a target keyboard which makes the new folder with KeyboardViewController.swift , info.plist and NumPad.xib. Though i think I'm on the wrong track, can someone point me the right way please.
Also anyone know the exact dimensions this view should be.. assuming what I'm asking is in fact possible. Let me know if I'm not being clear enough!
NumPad.xib(pic)
Many many thanks,
Steve
SOLUTION: Thanks to Andrea for correcting my search keywords. It led me to this Stack Question which hopefully sends some others to the correct end of the internet that have mistakes custom keyboard with custom input views!
Sure it is possible without going into settings, but they are called custom input views.
You should look into inputViews here what Apple says about them Custom views for data input.
Basically when the user press a text field instead of loading the usual keyboard it loads an inputView that you specify, pay attention that custom keyboard term is misleading. If you google for tutorial you'll find most probably link like the ones that you found.
For a practical example check this tutorial or this, is a little bit old, but the principle are still the same

Actual difference between UIAccessibilityLayoutChangedNotification and UIAccessibilityScreenChangedNotification?

I’m trying to ascertain what exactly happens differently when posting a UIAccessibilityLayoutChangedNotification, and a UIAccessibilityScreenChangedNotification. From what I can see, I can use them interchangeably everywhere and nothing different happens.
The Apple documentation simply says to use LayoutChanged when (for example) an element has been hidden or shown, and to use ScreenChanged if the entire screen changes, but I’m interested in what THEY do when I provide this information, and what I should see differently when using one or the other.
Can anyone give a clear explanation of implementation differences between the two?
These two notifications are for dynamic content on views, and communicating these changes to VoiceOver for screenreader users. There is little difference between these two notifications, except for their default behavior, and the silly little "boop beep" for ScreenChange notifications.
In both instances, the argument
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, arg);
Represents a string to be read out, or an on screen element, which VoiceOver will shift its focus to. In the event of dramatic context changes, it is important to send focus to a place that makes sense, or announce that such changes have taken place. Either approach is acceptable from an accessibility point of view, though I prefer approaches that involve the least amount of change possible. In the event of simple layout changes, it is almost always best just to announce the context change, and leave focus where it was. Though sometimes, the element that caused the context change is hidden, and then it is clearly necessary to direct voiceover to highlight new content, because the default behavior in this case is undefined, or perhaps deterministic, but determined by a framework that knows absolutely nothing about your app!
The difference between the two events, given that they both do exactly the same thing, is in their default behavior. If you supply nil to the UIAccessibilityLayoutChangedNotification it is as if you have done nothing. If you supply a nil argument to the UIAccessibilityScreenChangedNotification it will send focus to the first UIObject in your view hierarchy that is marked as an accessibilityElement, once all view hierarchy changes and drawings are complete.
UIAccessibilityLayoutChangedNotification
A good use case example for UIAccessibilityLayoutChangedNotification is for dynamic forms. You want to let users know that, based on decisions they've made in the form, new options are available. For example, if in a form you select that you are a Veteran, additional areas of the form may pop up to provide more input, but these areas may have been hidden to other users who did not care about them. So you could shift focus to these elements after user interaction:
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, firstNewFormElement);
Which would shift focus to the provided element, and announce it's accessibilityLabel.
Or just tell them that the new form elements are there:
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, #"Veterans form elements available");
Which would leave focus where it is, but VoiceOver would announce "Veterans form elements available".
Note: This particular behavior is bugged on my iPad (8.1.2).
Or finally you could do this:
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);
Which does absolutely nothing :). Seriously, I don't even think the a11y framework backend cares. This particular line of code is a complete waste!
UIAccessibilityScreenChangedNotification
A good use case example for the UIAccessibilityScreenChangedNotification is customized tabbed browsing situations. When the entire screen, with the exception of your navigation area, changes. You want to let voiceover know that essentially the entire screen changed, but NOT to focus the first element (your first tab) but to focus the first content element.
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, firstNonGlobalNavElement);
Which would play the "boop beep" sound and then shift focus to just beneath your global navigation bar. Or you could do this:
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, #"You're on a new tab");
Which would wait for the new tab to load, play the "beep boop" sound, announce "You're on a new tab" in voiceover, then shift focus to the first element on the screen, then announce the accessibilityLabel for that element. (PHEW! That's a lot! This is jarring for screen reader users. Avoid this scenario, unless absolutely necessary).
And finally you can of course do this:
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);
Which is equivalent to:
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, firstA11yElement);
Both of which will play the "beep boop" sound, shift VoiceOver focus to the first element on the screen, and then announce it.
Finally
In a comment somebody mentioned caching, and I occasionally comment in my answer about things the A11y Backend may or may not care about. While it is certainly possible that there is some backend magic happening, I don't believe in either of these circumstances, the back end cares at all. The reason I say this is because:
If you've ever used the UIAccessibilityContainer protocol, you can watch as your container of views gets queried. There is no caching going on. Even the accessibilityElementCount property gets pinged each time VoiceOver changes focus to a new AccessibilityElement within your container. Then it goes through the process of checking which element it is on, asking for the next element, and so on. It is designed at its core to handle dynamic situations. If you were to insert a new element into your container after interaction, it would still go through all of these queries and be just fine about it! Furthermore, if you override the properties of the UIAccessibility protocol, in order to provide dynamic hints and labels, you can also see that these functions get called every time! As such, I believe that the A11y Framework backend gleans ABSOLUTELY ZERO information from these notifications. The only information VoiceOver needs to do its job is it's currently focused Accessibility Element, and this elements Accessibility Container. The notifications are simply there for you to make your app more usable for VoiceOver users.
Imagine if this weren't the case how many times Safari would post these notifications!!!! :)
These particular statements can only be confirmed by someone with backend knowledge of the framework, who works with the code, and should be viewed as conjecture. It could be the case that this is highly version/implementation dependent. Definitely open to discussion on these points! The rest of this post is pretty concrete.
For Your Reference
Most of this comes from experience working with the frameworks, but here is a useful reference if you wish to dig further.
https://developer.apple.com/documentation/uikit/accessibility/uiaccessibility
https://developer.apple.com/documentation/uikit/uiaccessibilitylayoutchangednotification
https://developer.apple.com/documentation/uikit/uiaccessibilityscreenchangednotification
And finally, an open source repo of the silly little app I put together to test all this stuff.
https://github.com/chriscm2006/IOS-A11y-Api-Test
UIAccessibilityScreenChangedNotification is to indicate that the whole screen has changed and VoiceOver should reset.
UIAccessibilityLayoutChangedNotification is to indicate that one or more, but not all, elements on the screen have changed.
when your UI changes dramatically. Usually when a user moves into a different part of your app (navigates to a different screen). VoiceOver notifies the user with a tone, and it clears its caches and does other preparations to deal with a new set of accessibility data. It alerts VoiceOver that the screen has changed and there may be new elements on the screen so VoiceOver will rebuild it's index of accessibility elements.
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);
If some part of your UI changes, but the user hasn’t necessarily jumped to an entirely different part of your app. (Example: in the iTunes Store app, tapping on the price label ($0.99, etc.) next to a song changes it to a “Buy” button.) This notification tells VoiceOver to re-read the current state of all accessible items that are on-screen, and by doing this it figures out what has changed and informs the user of those changes. It alerts VoiceOver that the layout has changed and that it's current index is out of date because the items on the screen have reordered themselves.
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);

iOS keylogger for jailbroken devices

I want to know how to implement a keylogger for iOS jailbroken iPhones and prevent being logged by others.
1. Implementing a keylogger in iOS (jailbreak)
I have thought of two ways to do this,
First way:
I hook _endedEditing method of class UITextField and save the text of the textfield somewhere. The advantage of this way is it's easy and it's not depending on what you typed. So if you have copied some text in the textfield, you would know that too. The problem is It's not called for text boxes in html webpages like google search bar or some programs that there keyboard doesn't hide.
Second way:
I should hook the keyboard buttons press method and save there labels. The keystrokes should be slit every time the keyboard hides. There is a problem here for me: First of all I can't find the right method of the right class to hook. I've found UIKeyboardButton that inherits from UIButton but when I hook any method of that it's not called, I don't know why!
So how can I implement a keylogger for iOS?
2. Preventing an app being keylogged by a third party app/tweak
Now the second part of my question; There is a keylogger in cydia named iKeyMonitor that logs keystrokes and it's good at its job. The suprising thing here is that it can't log whatever is typed in iFile app! I even have tested this with the first way I mentioned above and I can't receive any text when I type anything in iFile. How does iFile do this and how can we do the same thing for our app?

The Correct Way to do Custom Keyboards in iOS?

I am looking to implement a custom toolbar that sits above my keyboard for a text field with some custom values. I've found a ton of tutorials online but this question is for asking what's the best way to do this.
This tutorial here http://blog.carbonfive.com/2012/03/12/customizing-the-ios-keyboard/ provides the most common way I can see across many tutorials, with creating a new subclass of UIView and using delegates to get that information across.
That's the commonality. However, I came across this tutorial which in the view controller itself just creates the toolbar, assigns it to the textField inputAccessory and it's good to go. In fact, I tried out the code and without any effort, I have now a custom keyboard.
http://easyplace.wordpress.com/2013/03/29/adding-custom-buttons-to-ios-keyboard/
This just seems a bit too easy to me though and I'd think the proper, Apple recommended way would be to create that UIView subclass and use delegates so that the view controller with the text fields acts as that delegate.
I'm specifically targeting iOS 7 in my app.
What are people's thoughts on this? If the second easier link is supported and is likely to pass Apple's guidelines, it's a good starting point but if delegates are the way to go, I'd rather look into that from the start.
Your thoughts will be appreciated.
There is no 'Apple Approved' way to do this, and its hard to believe anything you do here would get your app rejected. The custom keyboard you reference in your post has the iOS6 look and will appear outdated in an iOS6 app. I'll mention some iOS7 suggestions shortly, but the constant danger of mimicking what the System looks like today is guaranteed to look outdated later. In Mac/Cocoa development, Apple use to say at the WWDC that if you did something custom, make it look custom, don't take a standard Apple widget and try to duplicate it. But that advice is mostly ignored.
For iOS 7, you can create buttons that appear just like the system ones do (not pressed), but of course when someone presses them, they won't act like system buttons (i.e. animate up and "balloon" out.
I'm currently using a fantastic add-on keyboard, my fork of KOKeyboard (which uses the buttons above). This is such a cool addition. While the buttons look like iPad buttons, each one has 5 keys in it. By dragging to a corner you select one of the four, and tapping in the middle gives you that key. This might be overkill for your app, but it really helped me with mine. It looks like this:
(the Key / Value is in the under laying view.) The center control lets you move the cursor - its like a joy stick - and can be used to both move and select text. Amazing class, I wish I'd invented it!
Also, for any solution, you want to use a UIToolbar as the view holding the keys, for the reason that it supports blur of the view it overlays, just like the keyboard does. You can use the UIToolbar with no bar button items in it (if you want), and just add subviews. This is a "trick" I learned here, as there is no other way to get blur!
David's KOKeyboard (er…, the one he used - see David's comment below) looks nice. I suspect that he is using the official Apple mechanism:
inputAccessoryView
Typically, you'd set that value on a UITextView, but it can be any class that allows itself to become the first responder.
The provided view will be placed above the default apple keyboard.
It is correct that there is no official mechanism (and it is suggested against) to modify any system provided keyboard. You can add to it, as above. You can also entirely replace it for with your own mechanism. Apply will forgo the keyboard setting on your view and use a custom input mechanism if you set
inputView
set it to any view - Apple will still manage its appearance and dismissal as it does the custom keyboards.
Edit: Of course, iOS 8.x added significant access to keyboards. (not mentioned here)

Resources