How to display hyphen in uilabel? - ios

How to display hyphen with UILabel like this, - A I origine - , Here I use the string appending method. I get this type of output - À l'origine de la guerre -. But I want display hyphen before the starting point of text and display hyphen after 10 charatcers.
I was searched but i can't get valied source. kindly give any suggestion if you know.
NSString *tempStr = #" - ";
tempStr = [tempStr stringByAppendingString:NSLocalizedString(#"OriginallyWar", #"")];
tempStr = [tempStr stringByAppendingString:#" -"];
[headingLabel setText:tempStr];
[headingLabel setFont:MRSEAVES_BOLD(17)];

Use NSMutableString and insert characters,
[yourString insertString:#"-" atIndex:10];

if you are using StoryBoard directly set it to the text property on Attribute inspector. Put 10 empty spaces after the end of character and the -.

You may try this code
NSString *inputString = #"OriginallyWarDFdfsdfdDFSDfdsfdsfDFdsfadsfawerdsaf";
NSMutableString *localizedInputString = [NSMutableString stringWithString:NSLocalizedString(inputString, #"")];
int numberOfCharacters = localizedInputString.length;
int numberOf10s = (numberOfCharacters/10 + 1);
int numberOfCharactersToBeInserted = 0;
for (int i = 1; i < numberOf10s; i++) {
int characterIndex = (i * 10) + numberOfCharactersToBeInserted;
if (i == (numberOf10s - 1) && numberOfCharacters % 10 == 0) {
[localizedInputString insertString:#" -" atIndex:characterIndex];
numberOfCharactersToBeInserted = 2 * i;
} else {
[localizedInputString insertString:#" - " atIndex:characterIndex];
numberOfCharactersToBeInserted = 3 * i;
}
}
if (numberOfCharacters == 0) {
[localizedInputString insertString:#"-" atIndex:0];
} else {
[localizedInputString insertString:#"- " atIndex:0];
}
NSLog(#"localizedInputString : %#", localizedInputString);

try using NSMutableString
NSString *tempStr = #" - ";
tempStr = [tempStr stringByAppendingString:NSLocalizedString(#"OriginallyWar", #"")];
NSMutableString *tempStrMutable=[[NSMutableString alloc]initWithString:tempStr];
[tempStrMutable insertString:#"-" atIndex:10];
[headingLabel setText:tempStrMutable];

Related

Trim last two lines of an attributed string

How do I remove the last two lines of this NSAttributedString?
NSString *exampleString = #"line 1\nline 2\nline 3\nline 4"
NSAttributedString *as = [NSAttributedString alloc] int];
[as setString:exampleString];
[self removeLastTwoLinesOfAttributedString:as];
NSLog(#"%#",as);
-(void)removeLastTwoLinesOfAttributedString:(NSAttributedString *)string {
//some code here
}
I'd like to end up with #"line 1\nline 2" in this example. Thanks
You could do something like this :
-(NSAttributedString *) removeLastTwoLinesOfAttributedString:(NSAttributedString *aString) {
NSRange range = [aString.string rangeOfString:#"\n" options:NSBackwardsSearch];
range = [aString.string rangeOfString:#"\n" options:NSBackwardsSearch range:NSMakeRange(0, range.location)];
return [aString attributedSubstringFromRange:NSMakeRange(0, range.location)];
}
int main (int argc, const char * argv[])
{
NSString *exampleString = #"line 1\nline 2\nline 3\nline 4";
NSAttributedString *as = [[NSAttributedString alloc] initWithString:exampleString];
as = [self removeLastTwoLinesOfAttributedString:as];
NSLog(#"%#",as);
return 0;
}
Output
line 1
line 2
I would suggest as the best solution:
-(NSAttributedString *)removeLastTwoLinesOfAttributedString:(NSAttributedString *)aString {
if (aString.length == 0) {
return aString
}
NSString *string = [aString string];
unsigned numberOfLines, index, stringLength = [string length];
NSRange rangeOfLastTwoLines = NSMakeRange(aString.length - 1, 0);
for (index = stringLength-1, numberOfLines = 0; index >= 0 && numberOfLines < 2; numberOfLines++) {
NSRange rangeOfLine = [string lineRangeForRange:NSMakeRange(index, 0)];
rangeOfLastTwoLines = NSUnionRange(rangeOfLastTwoLines, rangeOfLine);
index -= rangeOfLine.length;
}
return [aString attributedSubstringFromRange:NSMakeRange(0, rangeOfLastTwoLines.location)];
}
This has the benefit of working with any newline character not just "\n" and it uses the preferred by Apple method for detecting lines see this
Also it will not break if the last two lines are less than 2
If you're using Swift you can do this, if you're using Objective-C you should look at the other answers.
You can drop the last two lines of a String like this
string.components(separatedBy: "\n").dropLast(2).joined(separator: "\n")
To do it to an attributed string just access the string property, remove the last two lines, and create an attributed string with the trimmed string and all the same attributes.

Transform punctuations form half width to full width

I have a sentence below:
我今天去买菜,买了一个西瓜,花了1.2元,买了一个土豆,花了3.78元。还买了一个无花果,花了45.89,怎么办呢?好贵呀!贵的我不知道再买什么了。
The punctuations in it are half width. How to change them to fullwidth, like the following:
我今天去买菜,买了一个西瓜,花了1.2元,买了一个土豆,花了3.78元。还买了一个无花果,花了45.89,怎么办呢?好贵呀!贵的我不知道再买什么了。
Some punctuations to consider (not exhaustive):
, to ,
? to ?
! to !
"" to “”
; to ;
First, define the CharacterSet from which you want to transform your characters. So if you want only punctuation, the set could be CharacterSet.punctuationCharacters or CharacterSet.alphanumerics.inverted.
Then map each character from this set to its HalfwidthFullwidth transformation.
Swift 3 and 4
extension String {
func transformingHalfwidthFullwidth(from aSet: CharacterSet) -> String {
return String(characters.map {
if String($0).rangeOfCharacter(from: aSet) != nil {
let string = NSMutableString(string: String($0))
CFStringTransform(string, nil, kCFStringTransformFullwidthHalfwidth, true)
return String(string).characters.first!
} else {
return $0
}
})
}
}
Usage
let string = ",?!\"\";abc012図書館 助け 足場が痛い 多くの涙"
let result = string.transformingHalfwidthFullwidth(from: CharacterSet.alphanumerics.inverted)
// it prints: ,?!"";abc012図書館 助け 足場が痛い 多くの涙
print(result)
Objective-C
#implementation NSString (HalfwidthFullwidth)
- (NSString *)transformingHalfwidthFullwidth:(nonnull NSCharacterSet *)aSet {
NSUInteger len = self.length;
unichar buffer[len + 1];
[self getCharacters:buffer range:NSMakeRange(0, len)];
for (int i = 0; i < len; i++) {
unichar c = buffer[i];
NSMutableString *s = [[NSMutableString alloc] initWithCharacters:&c length:1];
NSRange r = [s rangeOfCharacterFromSet:aSet];
if (r.location != NSNotFound) {
CFStringTransform((CFMutableStringRef)s, nil, kCFStringTransformFullwidthHalfwidth, true);
[s getCharacters:buffer + i range:NSMakeRange(0, 1)];
}
}
return [NSString stringWithCharacters:buffer length:len];
}
#end
Usage
NSString *string = #",?!\"\";abc012図書館 助け 足場が痛い 多くの涙";
NSString *result = [string transformingHalfwidthFullwidth:NSCharacterSet.alphanumericCharacterSet.invertedSet];
// it prints: ,?!"";abc012図書館 助け 足場が痛い 多くの涙
NSLog(result);
you can use CFStringTransform like :
Objective C :
NSString *string = #" ? \"\"!我今天去买菜,买了一个西瓜,花了1.2元,买了一个土豆,花了3.78元。还买了一个无花果,花了45.89,怎么办呢?好贵呀!贵的我不知道再买什么了";
NSMutableString *convertedString = [string mutableCopy];
CFStringTransform((CFMutableStringRef)convertedString, NULL, kCFStringTransformFullwidthHalfwidth, true);
NSLog(#"%#",convertedString);
Swift 3.0 :
let string = NSMutableString( string: " ? \"\"!我今天去买菜,买了一个西瓜,花了1.2元,买了一个土豆,花了3.78元。还买了一个无花果,花了45.89,怎么办呢?好贵呀!贵的我不知道再买什么了" )
CFStringTransform( string, nil, kCFStringTransformFullwidthHalfwidth, true )
print(string)

Unicode Hex Character code in NSString not displaying

I have Unicode Hex Character Code &#x1f682 that I receive from a server request, and I want to convert it to the Steam Locomotive emoji in my UILabel. I have read many other posts on the issue, but none of the solutions seem to work.
I have read posts about decoding HTML entities or setting the NSString as a UFT8 string, but none of those work.
NSString *unicode = #"Train &#x1f682";
self.label.text = [unicode stringByDecodingHTMLEntities]; <---- Doesn't work
Tried this:
NSString *train = #"Train &#x1f682";
self.label.text = [NSString stringWithUTF8String:[train UTF8String]]; <---- Doesn't work
Any ideas on how to convert this so I can see the emoji in my UILabel?
Note: This is different from the other questions about unicode characters, as this format has not been addressed and a solution proposed.
I got it working using the following:
- (void)viewDidLoad {
[super viewDidLoad];
self.label.text = [self convertHexUnicodeString:#"This is a train &#x1f682 I like trains! &#x1f682"];
}
- (NSString *)convertHexUnicodeString:(NSString *)unicodeText {
NSScanner *myScanner;
NSString *text = nil;
myScanner = [NSScanner scannerWithString:unicodeText];
while ([myScanner isAtEnd] == NO) {
[myScanner scanUpToString:#"&#x" intoString:NULL] ;
[myScanner scanUpToString:#" " intoString:&text] ;
unicodeText = [unicodeText stringByReplacingOccurrencesOfString:[NSString stringWithFormat:#"%#", text] withString:[self replaceHexUnicode:text]];
}
unicodeText = [unicodeText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
return unicodeText;
}
- (NSString *)replaceHexUnicode:(NSString *)text {
text = [text substringFromIndex:3];
unsigned unicodeInt = 0;
[[NSScanner scannerWithString:text] scanHexInt:&unicodeInt];
char chars[4];
int len = 4;
chars[0] = (unicodeInt >> 24) & (1 << 24) - 1;
chars[1] = (unicodeInt >> 16) & (1 << 16) - 1;
chars[2] = (unicodeInt >> 8) & (1 << 8) - 1;
chars[3] = unicodeInt & (1 << 8) - 1;
return [[NSString alloc] initWithBytes:chars length:len encoding:NSUTF32StringEncoding];
}

Find substring range of NSString with unicode characters

If I have a string like this.
NSString *string = #"😀1😀3😀5😀7😀"
To get a substring like #"3😀5" you have to account for the fact the smiley face character take two bytes.
NSString *substring = [string substringWithRange:NSMakeRange(5, 4)];
Is there a way to get the same substring by using the actual character index so NSMakeRange(3, 3) in this case?
Thanks to #Joe's link I was able to create a solution that works.
This still seems like a lot of work for just trying to create a substring at unicode character ranges for an NSString. Please post if you have a simpler solution.
#implementation NSString (UTF)
- (NSString *)substringWithRangeOfComposedCharacterSequences:(NSRange)range
{
NSUInteger codeUnit = 0;
NSRange result;
NSUInteger start = range.location;
NSUInteger i = 0;
while(i <= start)
{
result = [self rangeOfComposedCharacterSequenceAtIndex:codeUnit];
codeUnit += result.length;
i++;
}
NSRange substringRange;
substringRange.location = result.location;
NSUInteger end = range.location + range.length;
while(i <= end)
{
result = [self rangeOfComposedCharacterSequenceAtIndex:codeUnit];
codeUnit += result.length;
i++;
}
substringRange.length = result.location - substringRange.location;
return [self substringWithRange:substringRange];
}
#end
Example:
NSString *string = #"😀1😀3😀5😀7😀";
NSString *result = [string substringWithRangeOfComposedCharacterSequences:NSMakeRange(3, 3)];
NSLog(#"%#", result); // 3😀5
Make a swift extension of NSString and use new swift String struct. Has a beautifull String.Index that uses glyphs for counting characters and range selecting. Very usefull is cases like yours with emojis envolved

Backward with custom string

I used a string array for emoticons like this:
NSArray *emoticons = #[#"[smile]",#"[cry]",#"[happy]" ...]
then in a UITextView displaying a string like this:
I'm so happy now [happy] now [smile]
When I click a backward or delete button, if the last word is in emoticons, I want a whole emoticon string be deleted, not the last one character only.
Any idea?
Try this,
NSString *string = self.textView.text;
__block NSString *deleteWord = nil;
__block NSRange rangeOfWord;
[string enumerateSubstringsInRange:NSMakeRange(0, self.textView.selectedRange.location + self.textView.selectedRange.length) options:NSStringEnumerationByWords | NSStringEnumerationReverse usingBlock:^(NSString *substring, NSRange subrange, NSRange enclosingRange, BOOL *stop) {
deleteWord = substring;
rangeOfWord = enclosingRange;
*stop = YES;
}];
if ([emoticons containsObject:deleteWord]) {
string = [string stringByReplacingCharactersInRange:rangeOfWord withString:#""];
self.textView.text = string;
self.textView.selectedRange = NSMakeRange(rangeOfWord.location, 0);
}
You might achieve something like this with the UITextViewDelegate method textView:shouldChangeTextInRange:replacementText: checking what is about to be deleted and remove the whole [emoticon] word.
I am giving you the idea that i used.
as you do not mentioned what you used as emoticons.
but for delete logic i think you will get idea from my this code.
if ([string isEqualToString:#""]) {
NSString *lastChar = [txthiddenTextField.text substringFromIndex: [txthiddenTextField.text length] - 1];
NSLog(#"Last char:%#",lastChar);
txthiddenTextField.text = [txthiddenTextField.text substringToIndex:[txthiddenTextField.text length] - 1];
NSString *strPlaceHolder;
strPlaceHolder = txthiddenTextField.text;
if([lastChar isEqualToString:#"]"])
{
int j = 1;
for (int i = [txthiddenTextField.text length]-1; i >=0; --i)
{
NSString *lastChar = [txthiddenTextField.text substringFromIndex: [txthiddenTextField.text length] - 1];
if([lastChar isEqualToString:#"["])
{
NSLog(#"%d",j);
txthiddenTextField.text = [txthiddenTextField.text substringToIndex:[txthiddenTextField.text length] - 1];
// NSLog(#"Processing character %#",strPlaceHolder);
break;
}
txthiddenTextField.text = [txthiddenTextField.text substringToIndex:[txthiddenTextField.text length] - 1];
j = j+1;
}
}
NSLog(#"My text fild value :%#",txthiddenTextField.text);
return YES;
}
So, from here you have to check if the closing bracket is coming or not.
if closing bracket will come then up to opening bracket you have to delete.
then whole emoticon will delete.
hope this helps....

Resources