Showing Emoji with string in textfield in swift - ios

I am new to swift development. I need to show the emoji inside the text field and labels.
I also need to send them to server because Application is multi-platform.

On Xcode version 7.2.1+, you can use the below shortcut to show the symbols panels and insert the emoji:
Shortcut: (press the below three keys together)
Ctrl + Command + Space

You can declare a string variable with text and an emoji inside using its unicode number (1F603 is unicode number for an open faced smiley), like so:
let str : String = "Smiley \u{1F603}"
Then with your UITextField/UILabel, set the .text attribute to be the string.
yourTextField.text = str
//or for a UILabel.
yourLabel.text = str

textField.text=#"๐Ÿ˜€";
for above Emoji --- put the focus at place of emoji in UITextField and go to
Edit > Emoji & Symbols in Xcode 7.3
and select what ever emoji you want.
OR
Set Unicode values directly in code:
var string: String = "I want to visit เคฎเฅเค‚เคฌเคˆ. ๐Ÿ˜Š"
var character: Character = "๐ŸŒ"
Use hexadecimal to set values
var string: String = "\u{61}\u{5927}\u{1F34E}\u{3C0}"
var character: Character = "\u{65}\u{301}"

Related

Insert line break for UILabel text when a specific character is found

I have a UILabel that dynamically gets updated every time I click a button, the data will be fetched from firebase and displayed on the uilabel.I am able to display the text as shown below. I would like to insert a line break when a specific delimiter(say '.' PERIOD) is encountered in the text. I have looked into many solutions about UIlabel line break but couldn't find one what exactly I am looking for, every solution deals with static text that we provide in the storyboard itself. Any help will be appreciated. Thank you.
)
Created an outlet for the label and have taken a string which has three sentences separated by ".". The content in the image attached will be this string. Try using replacingOccurences() function as given below.
#IBOutlet weak var trialLabel: UILabel!
var string = "This is a trial text.Let us jump to a new line when the full stop is encountered.Hope it helps."
string = string.replacingOccurrences(of: ".", with: ".\n")
trialLabel.text = string
Check https://developer.apple.com/documentation/foundation/nsstring/1412937-replacingoccurrences for further reference. Happy Coding!!
You can achieve this with the attributed text property of UILabel. Try to find and replace the character with html line break and then assign this text to the UILabel attributed text.
You can replace string by
let str = "This is the string to be replaced by a new string"
let replacedStr = str.replacingOccurrences(of: "string", with: "str")
use below code
// HTML Tag Remove Method
extension String{
func removeHtmlFromString(inPutString: String) -> String{
return inPutString.replacingOccurrences(of: ".", with: ".\n", options: .regularExpression, range: nil)
}
}
let str = "Lorem Ipsum is simply dummy text.Lorem Ipsum has been the industry's standard dummy text ever since the 1500."
let postDiscription = str!.removeHtmlFromString(inPutString: str!)
You can add a \n in the text string to where you want to create a line break.

UILabel won't display specific String variable in Swift

I have an array containing string type values, and one value of a string contains the symbol & and another the symbol ^. So when it's time for them to be shown the UILabel remains blank.
let myString = arrayStrings[0] // The value is "M&M" or "(0C)^3"
myLabel.text = myString //UILabel remains blank
On the other hand, when I hardcode the string, the UILabel displays it.
myLabel.text = "M&M" //UILabel displays it normally
What can I do?
Just realised that when I print the Array I have the following result:
print("Array: \(arrayStrings)" // Array: ["\0M&M\0", "\0(0C)^3\0"]
"\0" doesn't exist to the rest Strings of the array
Thank you!
\0 means string termination in programming. So your String "\0M&M\0" means that this string is terminated on index 0, and then again later. So when you assign this string to your label, your label is displaying empty string.
To tweak it, do this and you will see the difference. Your problem is not related to & or ^
myLabel.text = "M&M\0 Hey I have lots of stuff here but the string is already terminated"
So in this situation, you need to find out why \0 exists in your string. You can possibly remove them by regex or string replace.

"Cannot Increment endIndex" because of emoji

I have a function that finds the current word a user has selected in a UITextView. However, if I call this function when an emoji is in the UITextView.text property, I see a crash. I believe this is because of the different character counts in String vs NSString.
How do I properly convert this?
func currentWord() -> String {
let cursorPosition = selectedRange.location
let separationCharacters = NSCharacterSet(charactersInString: " ")
// crash occurs here
let beginRange = Range(text.startIndex.advancedBy(0) ..< text.startIndex.advancedBy(cursorPosition))
let endRange = Range(text.startIndex.advancedBy(cursorPosition) ..< text.startIndex.advancedBy(text.characters.count))
let beginPhrase = text.substringWithRange(beginRange)
let endPhrase = text.substringWithRange(endRange)
let beginWords = beginPhrase.componentsSeparatedByCharactersInSet(separationCharacters)
let endWords = endPhrase.componentsSeparatedByCharactersInSet(separationCharacters)
return beginWords.last! + endWords.first!
}
I believe this is because of the different character counts in String vs NSString
You're right about that. You are shifting back and forth between using NSRange (Cocoa) and Range (Swift) โ€” and they work differently. And NSString (Cocoa) and String (Swift) have different ideas of where the character boundaries are. You need to be consistent.
Once you've used selectedRange in the first line, you are in the Cocoa world of NSRange. You need to stay consistently in the Cocoa world. Don't use any Swift Ranges! Don't use any Swift characters!
Form your beginRange entirely using NSRange โ€” for example, call NSMakeRange. Don't use characters.count; stay in the NSString world and use the string's length (in Swift, that is its utf16.count). Then all will be well.

How to select text in a field taking into account special characters?

I'm replacing the selected text in a textView with the new one. To accomplish this, I'm using this code based on this answer of beyowulf. All works well, the replaced text becomes selected, the problem arises when in the text there is one ore more special characters (like emoji etc). In this case the selected text misses one ore more characters at the end of the selection.
mainTextField.replaceRange((theRange), withText: newStr) // replace old text with the new one
selectNewText(theRange, newStr: newStr) // select the new text
func selectNewText(theRange: UITextRange, newStr: String) {
let newStrLength = newStr.characters.count // let's see how long is the string
mainTextField.selectedTextRange = mainTextField.textRangeFromPosition(theRange.start, toPosition: mainTextField.positionFromPosition(theRange.start, offset: newStrLength)!)
mainTextField.becomeFirstResponder()
}
OK, after I read the answers and comments to this question, I fixed this problem by replacing this statement (which returns the "human-perceptible" number of characters):
let newStrLength = newStr.characters.count
With this one:
let newStrLength = newStr.utf16.count
PS
By the way, here is some test I done with different implementations:
let str = "Abc๐Ÿ˜ฌ"
let count = str.characters.count
print(count) // 4
let count2 = str.utf16.count
print(count2) // 5
let count3 = str.utf8.count
print(count3) // 7

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

I entered a two emojis in textfield ๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ˜, here I'm getting total number of 5 characters length whereas 4 characters for first emoji and 1 character for second. Looks like apple has combined 4 emojis to form a one.
I'm looking for the swift code where I can separate each of emojis separately, suppose by taking the above example I should be getting 2 strings/character separately for each emoji.
Can any one help me to solve this, I've tried many things like regex separation or componentsSeparatedByString or characterSet. but unfortunately ended up with negative.
Thanks in advance.
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 = "๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ˜"
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 = "๐Ÿ‡ฉ๐Ÿ‡ช"
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.
You can use this code example or this pod.
To use it in Swift, import the category into the YourProject_Bridging_Header
#import "NSString+EMOEmoji.h"
Then you can check the range for every emoji in your String:
let example: NSString = "๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ˜" // your string
let ranges: NSArray = example.emo_emojiRanges() // ranges of the emojis
for value in ranges {
let range:NSRange = (value as! NSValue).rangeValue
print(example.substringWithRange(range))
}
// Output: ["๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง", "๐Ÿ˜"]
I created an small example project with the code above.
For further reading, this interesting article from Instagram.

Resources