AtTag mentions ios - ios

I am using STTweet label for display atTag mentions. My problem is want to mention last name along with mention. How can i do that?
Below post my code
__block CommentsTableViewCell *hashtag=self;
labelCommenter_Comment.detectionBlock = ^(STTweetHotWord hotWord, NSString *string, NSString *protocol, NSRange range)
{
if ([string hasPrefix:#"#"] && [string length] > 1)
{
string = [string substringFromIndex:1];
[hashtag hashTagDelegateCalling:string];
}
else if ([string hasPrefix:#"#"] && [string length] > 1)
{
string = [string substringFromIndex:1];
NSMutableString *atString = [NSMutableString stringWithFormat:#"%#",string];
[arrayExp enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
if ([[obj valueForKey:#"userName"] isEqualToString:atString]) {
NSString *hashLinkValue = [obj valueForKey:#"hashLink"];
[hashtag atTheRateDelegateCalling:hashLinkValue];
}
}];
}
};

Related

validate the phone number and email in same text filed in objective c

Any one help to solve this issues I am new for the development
I need to login with phone number as well as email id with same textfield how could I achieve that hereby I have to set the 10 digit limit for phone number as well as US like (838)-(838)-3333 format phone number ..and email id with same text filed ..how do I validate that user enter phone number or email..any one help me to solve the issues
thanks in advance
here is my code
if (!([self.usernameTextField.text validEmail] || [self.usernameTextField.text validateMobile])){
[self ShowAlert:#"Please enter a valid email address/phonenumber"];
}
- (BOOL)validEmail {
NSString *emailRegex = #"[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", emailRegex];
BOOL isValid = [emailTest evaluateWithObject:self];
return isValid;
}
- (BOOL)validateMobile {
NSString *ACCEPTABLE_CHARECTERS = #" 0123456789+-";
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:ACCEPTABLE_CHARECTERS] invertedSet];
NSString *filtered = [[self componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:#""];
// NSString* formattedNumber = [Contact formatPhoneNumber:phoneNumber codeLength:3 segmentLength:4];
return [self isEqualToString:filtered];
}
here I add my answer and customize yourself based on your Need.
step-1
connect the textfield and invoke the delegate on your current class, for e.g
#interface ViewController ()<UITextFieldDelegate>
#property (strong, nonatomic) IBOutlet UITextField *currentTextfield;
#end
step-2
get the first char on textfield delegate shouldChangeCharactersInRange and check whether it is number (phone number) or string (email)
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)textEntered
{
NSString *resultingString = [textField.text stringByReplacingCharactersInRange: range withString: textEntered];
NSString *abnRegex = #"[A-Za-z]+";
NSPredicate *abnTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", abnRegex];
if (([abnTest evaluateWithObject:resultingString] || resultingString.length == 0)) {
NSLog(#"its email");
}
else
{
NSLog(#"its phone number");
}
return YES;
}
step-3
if it is phone number then arrange the letters based on (838)-(838)-3333 format
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)textEntered
{
NSString *resultingString = [textField.text stringByReplacingCharactersInRange: range withString: textEntered];
NSString *abnRegex = #"[A-Za-z]+";
NSPredicate *abnTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", abnRegex];
if (([abnTest evaluateWithObject:resultingString] || resultingString.length == 0)) {
NSLog(#"its email");
}
else
{
NSLog(#"its phone number");
//(838)-(838)-3333
if (range.length == 1) {
// Delete button was hit.. so tell the method to delete the last char.
textField.text = [self formatPhoneNumber:resultingString deleteLastChar:YES];
} else {
textField.text = [self formatPhoneNumber:resultingString deleteLastChar:NO ];
}
return false;
}
return YES;
}
-(NSString*) formatPhoneNumber:(NSString*) simpleNumber deleteLastChar:(BOOL)deleteLastChar {
if(simpleNumber.length==0) return #"";
// use regex to remove non-digits(including spaces) so we are left with just the numbers
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"[\\s-\\(\\)]" options:NSRegularExpressionCaseInsensitive error:&error];
simpleNumber = [regex stringByReplacingMatchesInString:simpleNumber options:0 range:NSMakeRange(0, [simpleNumber length]) withTemplate:#""];
// check if the number is to long
if(simpleNumber.length>10) {
// remove last extra chars.
simpleNumber = [simpleNumber substringToIndex:10];
}
if(deleteLastChar) {
// should we delete the last digit?
simpleNumber = [simpleNumber substringToIndex:[simpleNumber length] - 1];
}
// 123 456 7890
// format the number.. if it's less then 7 digits.. then use this regex.
if(simpleNumber.length<7)
simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:#"(\\d{3})(\\d+)"
withString:#"($1)-($2)"
options:NSRegularExpressionSearch
range:NSMakeRange(0, [simpleNumber length])];
else // else do this one..
simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:#"(\\d{3})(\\d{3})(\\d+)"
withString:#"($1)-($2)-$3"
options:NSRegularExpressionSearch
range:NSMakeRange(0, [simpleNumber length])];
return simpleNumber;
}
step-4
finally validate your email or phone number on button action if it is the valid or not.
NSString *emailRegEx = #"[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", emailRegEx];
NSString *phoneRegex = #" (((\d{3}) ?)-((\d{3}) ?))?-\d{4}";
NSPredicate *phoneTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", phoneRegex];
if([emailTest evaluateWithObject:currentTextfield.text] == NO && [phoneTest evaluateWithObject:currentTextfield.text] == NO)
{
NSLog(#"Please enter a valid email address/phonenumber");
}
else
{
//login successful
}
Use this method it will be helpfull more and save your valuable time.
-(BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range replacementString:
(NSString *)string{
if (textField == _userIdTF){
NSString *totalString = [NSString stringWithFormat:#"%#%#",_userIdTF.text,string];
NSString *prefix;
if ([totalString length] == 1){
[[NSUserDefaults standardUserDefaults]removeObjectForKey:#"checkValue"];
}
if ([totalString length] >= 1){
prefix = [totalString substringToIndex:1];
NSLog(#"first letter %#",prefix);
if ([prefix isEqualToString:#"1"] || [prefix isEqualToString:#"2"] || [prefix isEqualToString:#"2"] || [prefix isEqualToString:#"0"] || [prefix isEqualToString:#"3"]|| [prefix isEqualToString:#"4"] || [prefix isEqualToString:#"5"] || [prefix isEqualToString:#"6"] || [prefix isEqualToString:#"7"] || [prefix isEqualToString:#"8"] || [prefix isEqualToString:#"9"]){
[[NSUserDefaults standardUserDefaults]setObject:#"1" forKey:#"checkValue"];
NSLog(#"checkvalu %#",[[NSUserDefaults standardUserDefaults]objectForKey:#"checkValue"]);
}else{
}
}
NSString *checkValue = [[NSUserDefaults standardUserDefaults]objectForKey:#"checkValue"];
NSLog(#"checkvalu %#",checkValue);
if ( [checkValue isEqual: #"1"] ) {
if ([totalString containsString:#"05"]) {
[totalString stringByReplacingOccurrencesOfString:totalString withString:#"+966"];
NSLog(#"phone number");
_userIdTF.text = [totalString stringByReplacingOccurrencesOfString:totalString withString:#"+966"];
}
}else{
prefix = totalString;
}
NSUInteger newLength = [textField.text length] + [string
length] - range.length;
if ([self.userIdTF.text containsString:#"+"]){
NSLog(#"number ppad");
NSString *acceptedCharsters = #"0123456789";
NSCharacterSet *cs = [[NSCharacterSet
characterSetWithCharactersInString:acceptedCharsters]
invertedSet];
NSString *filtered = [[string
componentsSeparatedByCharactersInSet:cs]
componentsJoinedByString:#""];
return [string isEqualToString:filtered];
}else{
}
return (newLength > 50) ? NO : YES;
}
else{
return YES;
}
}

UITextFieldInstance.text class is different in iOS 10.3.x between DEBUG and RELEASE

Seems marked text in UITextField will cause a bug only occurs in iOS 10.3.x Release build. And I found [UITextFieldInstance.text class] is different in different situations.
iOS 10.3.x
DEBUG: __NSCFString
RELEASE: NSTaggedPointerString
other version
always __NSCFString
Some of my code here:
- (void)changeTitle:(id)sender {
UITextField* textField = sender;
NSString* passStr;
__block NSUInteger count = 0;
__block NSRange range = NSMakeRange(0, textField.text.length);
[textField.text enumerateSubstringsInRange:NSMakeRange(0, textField.text.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
unichar uc;
[substring getBytes:&uc maxLength:4 usedLength:NULL encoding:NSUTF32LittleEndianStringEncoding options:0 range:NSMakeRange(0, substring.length) remainingRange:NULL];
if (uc >= 0x2e80 && uc < 0xa000) {
count += 2;
} else {
count++;
}
if (count == MAX_CHARACTORS) {
range = NSMakeRange(0, substringRange.location + substringRange.length);
*stop = YES;
} else if (count > MAX_CHARACTORS) {
range = NSMakeRange(0, substringRange.location);
*stop = YES;
}
}];
passStr = [textField.text substringWithRange:range];
if (!textField.markedTextRange) {
textField.text = passStr;
}
self.sketchViewModel.signatureTitle = passStr;
[self updateSignatureTitle];
}
It is [textField.text enumerateSubstringsInRange:NSMakeRange(0, textField.text.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) { ... }] where crashes the app.
NSMakeRange(0, textField.text.length) will throw exception EXC_BAD_ACCESS KERN_INVALID_ADDRESS, which means the range is out of bounds. So I guess it's because the text's class is different and which causes different behavior.
Anyone have the same problem?

NSString append WhiteSpace for every 4 Character

I have a string like #"1234123412341234", i need to append space between every 4 chars like.
#"1234 1234 1234 1234"
i.e, I need a NSString like Visa Card Type. I have tried like this but i didn't get my result.
-(void)resetCardNumberAsVisa:(NSString*)aNumber
{
NSMutableString *s = [aNumber mutableCopy];
for(int p=0; p<[s length]; p++)
{
if(p%4==0)
{
[s insertString:#" " atIndex:p];
}
}
NSLog(#"%#",s);
}
Here's a unicode aware implementation as a category on NSString:
#interface NSString (NRStringFormatting)
- (NSString *)stringByFormattingAsCreditCardNumber;
#end
#implementation NSString (NRStringFormatting)
- (NSString *)stringByFormattingAsCreditCardNumber
{
NSMutableString *result = [NSMutableString string];
__block NSInteger count = -1;
[self enumerateSubstringsInRange:(NSRange){0, [self length]}
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
if ([substring rangeOfCharacterFromSet:[NSCharacterSet whitespaceCharacterSet]].location != NSNotFound)
return;
count += 1;
if (count == 4) {
[result appendString:#" "];
count = 0;
}
[result appendString:substring];
}];
return result;
}
#end
Try it with this test string:
NSString *string = #"ab 😗😌 132487 387 e e e ";
NSLog(#"%#", [string stringByFormattingAsCreditCardNumber]);
The method works with non-BMP characters (i.e. emoji) and handles existing white space.
Your code is pretty close, however a better semantic for the method is to return a new NSString for any given input string:
-(NSString *)formatStringAsVisa:(NSString*)aNumber
{
NSMutableString *newStr = [NSMutableString new];
for (NSUInteger i = 0; i < [aNumber length]; i++)
{
if (i > 0 && i % 4 == 0)
[newStr appendString:#" "];
unichar c = [aNumber characterAtIndex:i];
[newStr appendString:[[NSString alloc] initWithCharacters:&c length:1]];
}
return newStr;
}
You should do like this:
- (NSString *)resetCardNumberAsVisa:(NSString*)originalString {
NSMutableString *resultString = [NSMutableString string];
for(int i = 0; i<[originalString length]/4; i++)
{
NSUInteger fromIndex = i * 4;
NSUInteger len = [originalString length] - fromIndex;
if (len > 4) {
len = 4;
}
[resultString appendFormat:#"%# ",[originalString substringWithRange:NSMakeRange(fromIndex, len)]];
}
return resultString;
}
UPDATE:
You code will be right on the first inserting space charactor:
This is your originalString:
Text: 123412341234
Location: 012345678901
Base on your code, on the first you insert space character, you will insert at "1" (with location is 4)
And after that, your string is:
Text: 1234 12341234
Location: 0123456789012
So, you see it, now you have to insert second space charater at location is 9 (9%4 != 0)
Hope you can fix your code by yourself!
The code snippet from here do what do you want:
- (NSString *)insertSpacesEveryFourDigitsIntoString:(NSString *)string
andPreserveCursorPosition:(NSUInteger *)cursorPosition
{
NSMutableString *stringWithAddedSpaces = [NSMutableString new];
NSUInteger cursorPositionInSpacelessString = *cursorPosition;
for (NSUInteger i=0; i<[string length]; i++) {
if ((i>0) && ((i % 4) == 0)) {
[stringWithAddedSpaces appendString:#" "];
if (i < cursorPositionInSpacelessString) {
(*cursorPosition)++;
}
}
unichar characterToAdd = [string characterAtIndex:i];
NSString *stringToAdd =
[NSString stringWithCharacters:&characterToAdd length:1];
[stringWithAddedSpaces appendString:stringToAdd];
}
return stringWithAddedSpaces;
}
swift3 based on Droppy
func codeFormat(_ code: String) -> String {
let newStr = NSMutableString()
for i in 0..<code.characters.count {
if (i > 0 && i % 4 == 0){
newStr.append(" ")
}
var c = (code as NSString).character(at: i)
newStr.append(NSString(characters: &c, length: 1) as String)
}
return newStr as String
}
Please make sure that your string length should times by 4.
This solution will insert on the right hand side first.
- (NSString*) fillWhiteGapWithString:(NSString*)source
{
NSInteger dl = 4;
NSMutableString* result = [NSMutableString stringWithString:source];
for(NSInteger cnt = result.length - dl ; cnt > 0 ; cnt -= dl)
{
[result insertString:#" " atIndex:cnt];
}
return result;
}

Replace using regular expression with replacement function

In objective-c (for ios) I want to achieve the same as I can in AS3:
var test:String = "Abba";
var reg:RegExp = /(a)|(b)/g;
var replacement:Function = function (...args):String
{
var $1:String = args[1];//matched 'a'
var $2:String = args[2];//matched 'b'
if($1)
{
//replace a with -
return "-";
}
if ($2)
{
//replace b with +
return "+";
}
return null;
}
var result:String = test.replace(reg, replacement);//A++-
trace(test, result);//Abba A++-
In other words I would like to have ability to identify which capturing group was matched and replace it accordingly, I'm looking for examples on enumerateMatchesInString: but can't find anything that can solve my problem.
enumerateMatchesInString: calls a block with an NSTextCheckingResult for each match,
and rangeAtIndex:idx gives the range of a captured subgroup:
NSString *string = #"Abba";
NSString *pattern = #"(a)|(b)";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:0
error:NULL];
NSMutableString *newString = [string mutableCopy];
[regex enumerateMatchesInString:string options:0 range:NSMakeRange(0, [string length])
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSRange r1 = [result rangeAtIndex:1];
if (r1.location != NSNotFound) {
[newString replaceCharactersInRange:r1 withString:#"-"];
}
NSRange r2 = [result rangeAtIndex:2];
if (r2.location != NSNotFound) {
[newString replaceCharactersInRange:r2 withString:#"+"];
}
}];
NSLog(#"%#", newString);
// Output: A++-
If the replacement strings have not the same length as the original strings, then it
gets slightly more complicated, because you have to keep track of the length changes
in the resulting string:
NSMutableString *newString = [string mutableCopy];
__block int offset = 0;
[regex enumerateMatchesInString:string options:0 range:NSMakeRange(0, [string length])
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSRange r1 = [result rangeAtIndex:1];
if (r1.location != NSNotFound) {
r1.location += offset;
NSString *repl = #"---";
[newString replaceCharactersInRange:r1 withString:repl];
offset += [repl length] - r1.length;
}
NSRange r2 = [result rangeAtIndex:2];
if (r2.location != NSNotFound) {
r2.location += offset;
NSString *repl = #"++";
[newString replaceCharactersInRange:r2 withString:repl];
offset += [repl length] - r2.length;
}
}];
NSLog(#"%#", newString);
// Output: A++++---

Index of a character from the NSString in iOS

I have an NSString for example "This is my question".I want to find all the indices of the character/substring "i" ie In this case If index starts from 0,then I want 2,5,16 as my answer.
The other answer is a bit of an overkill. Why don't you simply iterate over the characters like this:
NSString *x = #"This is my question";
for (NSUInteger i=0;i<[x length];i++)
{
if ([x characterAtIndex:i]=='i')
{
NSLog(#"found: %d", i);
}
}
It outputs exactly your positions:
found: 2
found: 5
found: 16
I'd like suggest my solution. It is like this:
NSString* str = #"This is my question";
NSArray* arr = [str componentsSeparatedByString: #"i"];
NSMutableArray* marr = [NSMutableArray arr];
NSInteger cnt = 0;
for (NSInteger i = 0; i < ([arr count]); i++)
{
NSString* s = [arr objectAtIndex: i];
cnt += [s length];
[marr addObject: [NSNumber numberWithInt: cnt]];
cnt += [#"i" length];
}
NSLog(#"%#", [marr description]);
On console:
2
5
16
I don't know is there any built-in functions available for doing this. You can use this method:
- (NSMutableArray *)indexOfCharacter:(char)c inString:(NSString*)string
{
NSMutableArray *returnArray = [[NSMutableArray alloc] init];
for(int i=0;i<string.length;i++)
{
if(c == [string characterAtIndex:i])
{
[returnArray addObject:[NSNumber numberWithInt:i]];
}
}
return returnArray;
}
Using NSRange and loop and with some string manipulation you can easily do it.
NSString *string = #"This is my question";
NSString *substring = #"i";
NSRange searchRange = NSMakeRange(0,string.length);
NSRange foundRange;
while (searchRange.location < string.length)
{
searchRange.length = string.length-searchRange.location;
foundRange = [string rangeOfString:substring options:nil range:searchRange];
if (foundRange.location != NSNotFound)
{
// found an occurrence of the char
searchRange.location = foundRange.location+foundRange.length;
NSLog(#"Location of '%#' is %d",substring,searchRange.location-1);
}
}
EDIT
Using NSRegularExpression and NSRange you can do like this.
NSString *string = #"This is my question";
NSString *substring = #"i";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:substring
options:0
error:NULL];
[regex enumerateMatchesInString:string options:0 range:NSMakeRange(0, [string length])
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSRange range = [result range];
NSLog(#"Location of '%#' is %d",substring, range.location);
}];
output is
Location of 'i' is 2
Location of 'i' is 5
Location of 'i' is 16
This is my attempt at a no loop code of getting what you want. I coded this blind, meaning not-tested etc. Its basically a recursive function, but I think it gets you the general idea.
- (NSArray *)getAllEyes:(NSString *)s index:(int)index) {
if (!s || s.length <= 0 || index >= s.length) return [NSArray new];
NSRange *r = [s rangeOfString(#"i") options:NSLiteralSearch range:NSMakeRange(index, s.length - index)];
if (r.location == NSNotFound) {
return [NSArray new];
} else {
NSMutableArray *array = [NSMutableArray new];
[array addObject:#(r.location)];
[array addObjectsFromArray:[self getAllEyes:s index:r.location + 1]];
return array;
}
}
// usage:
NSArray *allEyes = [self getAllEyes:#""];
for (NSNumber *n in allEyes) {
NSLog(#"i = %#", n);
}

Resources