How to Separate Emojis Entered (Through Default Keyboard) on Textfield

How to separate emojis entered (through default keyboard) on textfield

Update for Swift 4 (Xcode 9)

As of Swift 4 (tested with Xcode 9 beta) a "Emoji ZWJ Sequence" is
treated as a single Character as mandated by the Unicode 9 standard:

let str = "‍‍‍br>print(str.count) // 2
print(Array(str)) // ["‍‍‍, "]

Also String is a collection of its characters (again), so we can
call str.count to get the length, and Array(str) to get all
characters as an array.


(Old answer for Swift 3 and earlier)

This is only a partial answer which may help in this particular case.

"‍‍‍ is indeed a combination of four separate characters:

let str = "‍‍‍ //
print(Array(str.characters))

// Output: ["‍", "‍", "‍", ", "]

which are glued together with U+200D (ZERO WIDTH JOINER):

for c in str.unicodeScalars {
print(String(c.value, radix: 16))
}

/* Output:
1f468
200d
1f468
200d
1f467
200d
1f467
1f60d
*/

Enumerating the string with the .ByComposedCharacterSequences
options combines these characters correctly:

var chars : [String] = []
str.enumerateSubstringsInRange(str.characters.indices, options: .ByComposedCharacterSequences) {
(substring, _, _, _) -> () in
chars.append(substring!)
}
print(chars)

// Output: ["‍‍‍, "]

But there are other cases where this does not work,
e.g. the "flags" which are a sequence of "Regional Indicator
characters" (compare Swift countElements() return incorrect value when count flag emoji). With

let str = "br>

the result of the above loop is

[", "]

which is not the desired result.

The full rules are defined in "3 Grapheme Cluster Boundaries"
in the "Standard Annex #29 UNICODE TEXT SEGMENTATION" in the
Unicode standard.

Block Emoji from being inserted into text field

Based on @CoryCoolguy's suggestion one solution is to remove characters from the text field after they're entered by checking the contents of the field.

This solution uses a regex validator to locate any characters that are not part of a valid set, then replace them with a blank character.

textbox.addEventListener( "input", event => {
textbox.value = textbox.value.replace( /[^a-zA-Z0-9 ]/gm, '');
}, false);

textbox.addEventListener( "paste", event => {
textbox.value = textbox.value.replace( /[^a-zA-Z0-9 ]/gm, '');
}, false);

Using the input event, each time a character is typed or inserted via the Windows Emoji panel the value of the text box is scanned and any characters not matching the regex is removed.

Adding a paste event listener will monitor anything pasted from the clipboard and will allow the contents to be pasted before removing any unwanted characters. This means that if there's a mix of valid and non-valid character in the clipboard, then the valid ones will still get pasted.

Offset UITextField - Emoji-layout

Thanks guys for your help, i have found the answer:
I was using this line :

if let keyboardSize = (notifcation.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size{

I changed to the key-value of notifcation.userInfo to UIKeyboardFrameEndUserInfoKey, and that fixed the issue.

Limit keyboard to Emoji

Keyboard types can be set in Interface Builder or programmatically using this guide:

typedef enum {
UIKeyboardTypeDefault, // Default type for the current input method.
UIKeyboardTypeASCIICapable, // Displays a keyboard which can enter ASCII characters, non-ASCII keyboards remain active
UIKeyboardTypeNumbersAndPunctuation, // Numbers and assorted punctuation.
UIKeyboardTypeURL, // A type optimized for URL entry (shows . / .com prominently).
UIKeyboardTypeNumberPad, // A number pad (0-9). Suitable for PIN entry.
UIKeyboardTypePhonePad, // A phone pad (1-9, *, 0, #, with letters under the numbers).
UIKeyboardTypeNamePhonePad, // A type optimized for entering a person's name or phone number.
UIKeyboardTypeEmailAddress, // A type optimized for multiple email address entry (shows space @ . prominently).

UIKeyboardTypeAlphabet = UIKeyboardTypeASCIICapable, // Deprecated

} UIKeyboardType;

The Emoji Keyboard is set as a separate Language keyboard and therefore cannot be set programmatically. It is set by the user in the settings app.

I guess, even though it is cumbersome, you could either alert your user or have an help file inside your app to say that to have the best experience with your app they would need to enable that.

Also be aware that I believe Apple now rejects apps that create their own custom Emoji keyboard because it is a part of the main OS now.

How to disable iOS 8 emoji keyboard?

Try this:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if ([textField isFirstResponder])
{
if ([[[textField textInputMode] primaryLanguage] isEqualToString:@"emoji"] || ![[textField textInputMode] primaryLanguage])
{
return NO;
}
}
return YES;
}

for more info see here.

EDIT :

You can hide emoji from Keyboard using this code:

txtField.keyboardType=UIKeyboardTypeASCIICapable;

EDIT :

Hide emoji selection from keyboard using Interface builder.

Sample Image

How to extract emojis from a string?

The Set of Emoji characters

First of all we need a Set containing the unicode values representing the emoji.

Disclaimer

For this answer I am using the range of Emoticons (1F601-1F64F) and Dingbats (2702-27B0) to show you the solution. However keep in mind that you should add further ranges depending on your needs.

Extending Character

Now we need a way to calculate the Unicode Scalar Code Point of a Character. For this I am using the solution provided here.

extension Character {
private var unicodeScalarCodePoint: Int {
let characterString = String(self)
let scalars = characterString.unicodeScalars
return Int(scalars[scalars.startIndex].value)
}
}

Extending String

This extension does allow you to extract the emoji characters from a String.

extension String {
var emojis:[Character] {
let emojiRanges = [0x1F601...0x1F64F, 0x2702...0x27B0]
let emojiSet = Set(emojiRanges.flatten())
return self.characters.filter { emojiSet.contains($0.unicodeScalarCodePoint) }
}
}

Testing

let sentence = " hello world br>sentence.emojis // [", "]


Related Topics



Leave a reply



Submit