When trying to type in a textfield after first character keyboard automatically gets dismissed, I have not implemented any textfield delegates, except shouldChangeCharacterInRange and in this method there is no resignFirstResponder or endEditing and there is not disabled textFields.
if ([theTextField isEqual:_userName]) {
MAX_DIGITS = 15;
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789-._"];
for (int i = 0; i < [string length]; i++) {
unichar c = [string characterAtIndex:i];
if (![myCharSet characterIsMember:c]) {
return NO;
} else {
return [theTextField.text stringByReplacingCharactersInRange:range withString:string].length <= MAX_DIGITS;
}
}
}
retutn YES:
Related
I want to show my long text in a UILabel. But, My design having small size of frame for that UILabel. So, i want to truncate my long text like this[see below]:
Ex:
UILabel Text: "I want to show my long text in a UILabel"
Recent Result: [Using lineBreakMode:]
I want to s........a UILabel
I want to s.....
I want to s
Expected Result: "I want to...."
[Note: I want truncation after the word which can fit within their label frame.]
I hope that you can sense about my expected result. Sorry for my English!.
I am not sure whether there is API for this. If you are not getting answers. You can use the below logic to achieve This is not optimum logic.
-(NSString *) textThatFits:(NSString *) originalText font:(UIFont *) font
{
NSArray *array = [originalText componentsSeparatedByString:#" "];
NSString *stringThatFits;
for (int i = 0 ; i < [array count]; i++)
{
NSString *tempString = [stringThatFits stringByAppendingFormat:#" %#", array[i]];
CGRect boundingRect = [tempString boundingRectWithSize:CGSizeMake(999, 999)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:font}
context:nil];
if (boundingRect.size.width < self.yourLabel.width) {
return stringThatFits;
}
else
{
stringThatFits = tempString;
}
}
return stringThatFits;
}
According to the OP excepted result and the #Naveen logic, I develop the code which works but with some restriction.
Restriction:
Sometimes, extending that label width by adding 10.0 value.
don't give any spaces at begin and end of label text.
Design:
Controls: A UIButton, UITextField, UILabel
Type your text in the UITextField.
Do Action to display your excepted result in the UILabel.
Code:
-(IBAction)actionDisplayTextWithTruncate:(id)sender{
lblFinalResult.frame=CGRectMake(60, 345, 55, 21);
NSString *strGivenText, *strFuncResult, *stringThatFits;
int spaceCount;
//Custom Truncate Function
strGivenText=txtFldGivenText.text;
arrForGivenText_Words = [strGivenText componentsSeparatedByString:#" "];
stringThatFits=#"";
strFuncResult=#"";
for (int i = 0 ; i < [arrForGivenText_Words count]; i++)
{
/* must follow #" %#" - a space before %# */
NSString *tempString = [stringThatFits stringByAppendingFormat:#" %#", arrForGivenText_Words[i]];
CGRect boundingRect = [tempString boundingRectWithSize:CGSizeMake(999, 999) options:NSStringDrawingTruncatesLastVisibleLine attributes:#{NSFontAttributeName:lblFinalResult.font} context:nil];
if (boundingRect.size.width > lblFinalResult.frame.size.width) //Breakpoint1
{
if(i==0){
[lblFinalResult setText:#"..."];
return;
}
else{
for (int j = 0 ; j < i; j++)
{
strFuncResult = [strFuncResult stringByAppendingFormat:#"%# ",arrForGivenText_Words[j]];
NSLog(#"Present_a1: %#", strFuncResult);
}
strFuncResult = [strFuncResult substringToIndex:strFuncResult.length-(strFuncResult.length>0)];
lblFinalResult.frame= CGRectMake(lblFinalResult.frame.origin.x, lblFinalResult.frame.origin.y, lblFinalResult.frame.size.width+10, lblFinalResult.frame.size.height);
strFuncResult=[strFuncResult stringByAppendingString:#"..."];
[lblFinalResult setText:strFuncResult];
return;
}
}
else{
stringThatFits = tempString;
NSLog(#"Present_a2: %#", stringThatFits);
}
}
[lblFinalResult setText:stringThatFits];
}
I'm trying to check if a string is palindrome or not using objective c. I'm new to programming without any experience in other programming languages so bear with me please. I get stuck at my if condition I want it to say that if the first position in the string is equal to the last one the string is a palindrome.
What im a doing wrong?
int main (int argc, const char * argv[])
{
NSString *p = #"121" ;
BOOL palindrome = TRUE;
for (int i = 0 ; i<p.length/2+1 ; i++)
{
if (p[i] != p [p.Length - i - 1])
palindrome = false;
}
return (0);
}
You're trying to use an NSString as an NSArray (or probably, like a C string), which won't work. Instead, you need to use the NSString method characterAtIndex: to get the character to test.
Apart from the unbalanced braces, accessing a character from NSString is more complicated than using array notation. You need to use the method characterAtIndex: You can optimise your code, by breaking out of the loop if a palindrome is impossible and taking the length call outside of the for loop.
NSString *p = #"121";
NSInteger length = p.length;
NSInteger halfLength = (length / 2);
BOOL isPalindrome = YES;
for (int i = 0; i < halfLength; i++) {
if ([p characterAtIndex:i] != [p characterAtIndex:length - i - 1]) {
isPalindrome = NO;
break;
}
}
It may be desirable to check case insensitively. To do this, make the string be all lowercase before looping, using the lowercaseString method.
As pointed out by Nikolai in the comments, this would only work for strings containing 'normal' unicode characters, which is often not true — such as when using UTF8 for foreign languages. If this is a possibility, use the following code instead, which checks composed character sequences rather than individual characters.
NSString *p = #"121";
NSInteger length = p.length;
NSInteger halfLength = length / 2;
__block BOOL isPalindrome = YES;
[p enumerateSubstringsInRange:NSMakeRange(0, halfLength) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
NSRange otherRange = [p rangeOfComposedCharacterSequenceAtIndex:length - enclosingRange.location - 1];
if (![substring isEqualToString:[p substringWithRange:otherRange]]) {
isPalindrome = NO;
*stop = YES;
}
}];
var str: NSString = "123321"
var length = str.length
var isPalindrome = true
for index in 0...length/2{
if(str.characterAtIndex(index) != str.characterAtIndex(length-1 - index)){
print("\(index )not palindrome")
isPalindrome = false
break
}
}
print("is palindrome: \(isPalindrome)")
As it seems there's no answer yet that handles composed character sequences correctly I'm adding my two cents:
NSString *testString = #"\u00E0 a\u0300"; // "à à"
NSMutableArray *logicalCharacters = [NSMutableArray array];
[testString enumerateSubstringsInRange:(NSRange){0, [testString length]}
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop)
{
[logicalCharacters addObject:substring];
}];
NSUInteger count = [logicalCharacters count];
BOOL isPalindrome = YES;
for (NSUInteger idx = 0; idx < count / 2; ++idx) {
NSString *a = logicalCharacters[idx];
NSString *b = logicalCharacters[count - idx - 1];
if ([a localizedCaseInsensitiveCompare:b] != NSOrderedSame) {
isPalindrome = NO;
break;
}
}
NSLog(#"isPalindrome: %d", isPalindrome);
This splits the string into an array of logical characters (elements of a string that a normal user would call a "character").
#import Foundation;
BOOL isPalindrome(NSString * str)
{
if (!str || str.length == 0) return NO;
if (str.length == 1) return YES;
for(unsigned i = 0; i < str.length / 2; ++i)
if ([str characterAtIndex:i] != [str characterAtIndex:str.length - i - 1]) return NO;
return YES;
}
int main() {
#autoreleasepool {
NSLog(#"%s", isPalindrome(#"applelppa") ? "YES" : "NO");
} return 0;
}
Recursive
- (BOOL)isPaliRec:(NSString*)str :(int)start :(int)end{
if(start >= end)
return YES;
else if([str characterAtIndex:start] != [str characterAtIndex:end])
return NO;
else
return [self isPaliRec:str :++start :--end];
}
Non Recursive
- (BOOL)isPali:(NSString*)str{
for (int i=0; i<str.length/2; i++)
if([str characterAtIndex:i] != [str characterAtIndex:(str.length-i-1)])
return NO;
return YES;
}
you can call:
NSString *str = #"arara";
[self isPaliRec:str :0 :(int)str.length-1];
[self isPali:str];
Swift 3:
// Recursive
func isPaliRec(str: String, start: Int = 0, end: Int = str.characters.count-1) -> Bool {
if start >= end {
return true
} else if str[str.index(str.startIndex, offsetBy: start)] != str[str.index(str.startIndex, offsetBy: end)] {
return false
} else {
return isPaliRec(str: str, start: start+1, end: end-1)
}
}
// Non Recursive
func isPali(str: String) -> Bool {
for i in 0..<str.characters.count/2 {
let endIndex = str.characters.count-i-1
if str[str.index(str.startIndex, offsetBy: i)] != str[str.index(str.startIndex, offsetBy: endIndex)] {
return false
}
}
return true
}
// Using
let str = "arara"
isPaliRec(str: str)
isPali(str: str)
Also, you can use swift 3 methods like a string extension... It's more elegant. extension sample
NSString *str=self.txtFld.text;
int count=str.length-1;
for (int i=0; i<count; i++) {
char firstChar=[str characterAtIndex:i];
char lastChar=[str characterAtIndex:count-i];
NSLog(#"first=%c and last=%c",firstChar,lastChar);
if (firstChar !=lastChar) {
break;
}
else
NSLog(#"Pailndrome");
}
We can also do this using NSRange like this...
enter code NSString *fullname=#"123321";
NSRange rangeforFirst=NSMakeRange(0, 1);
NSRange rangeforlast=NSMakeRange(fullname.length-1, 1);
BOOL ispalindrome;
for (int i=0; i<fullname.length; i++) {
if (![[fullname substringWithRange:rangeforFirst] isEqualToString:[fullname substringWithRange:rangeforlast]]) {
NSLog(#"not match");
ispalindrome=NO;
return;
}
i++;
rangeforFirst=NSMakeRange(i, 1);
rangeforlast=NSMakeRange(fullname.length-i-1, 1);
}
NSLog(#"no is %#",(ispalindrome) ? #"matched" :#"not matched");
NSString *str1 = #"racecar";
NSMutableString *str2 = [[NSMutableString alloc] init];
NSInteger strLength = [str1 length]-1;
for (NSInteger i=strLength; i>=0; i--)
{
[str2 appendString:[NSString stringWithFormat:#"%C",[str1 characterAtIndex:i]]];
}
if ([str1 isEqual:str2])
{
NSLog(#"str %# is palindrome",str1);
}
-(BOOL)checkPalindromeNumber:(int)number{
int originalNumber,reversedNumber = 0,remainder;
originalNumber=number;
while (number!=0) {
remainder=number%10;
reversedNumber=(reversedNumber*10)+remainder;
number=number/10;
}
if (reversedNumber==originalNumber) {
NSLog(#"%d is Palindrome Number",originalNumber);
return YES;
}
else{
NSLog(#"%d is Not Palindrome Number",originalNumber);
return NO;
}
}
I have UITextfield that is set to show only 1 character upon initialization, however I use constraints to make the field be able to expand as needed.
My constraint:
#"H:[txtField(<=80)]-14-|
When I set the textField via the text attribute it resizes perfectly, however when I try and enter it in via the keyboard the best I can get is to use sizeToFit inside the shouldChangeCharactersInRange...which kind of works but instead of the dollar amount moving inward to the left on the iphone it moves outward to the right and off the screen.
How would I make it move inward to the left?
I ended up using this little bit I found on StackOverflow in the
shouldChangeCharactersInRange
double currentValue;
NSString *str;
if(![textField.text length]){
str = #"$ 0.00";
}else{
str = textField.text;
}
currentValue = [[str substringFromIndex:1] doubleValue];
double cents = round(currentValue * 100.0f);
if ([string length]) {
for (size_t i = 0; i < [string length]; i++) {
unichar c = [string characterAtIndex:i];
if (isnumber(c)) {
cents *= 10;
cents += c - '0';
}
}
} else {
// back Space
cents = floor(cents / 10);
}
textField.text = [NSString stringWithFormat:#"%.2f", cents / 100.0f];
//Add this line
[textField setText:[NSString stringWithFormat:#"$%#",[textField text]]];
return NO;
i have written the following code to check anagram want to know is this perfect & is there any better way to implement the same in objective C
-(BOOL) findAnagram :(NSString *) string1 :(NSString *) string2
{
int len = string1.length;
if (len != string2.length)
{
return false;
}
for (int i=0; i < len; i++)
{
int h = 0;
int q = 0;
for (int k = 0; k < len ; k ++)
{
if ([string1 characterAtIndex:i] == [string1 characterAtIndex:k])
{
h++;
}
if ([string1 characterAtIndex:i] == [string2 characterAtIndex:k])
{
q++;
}
}
if (h!=q)
{
return false;
}
}
return TRUE;
}
A better performing version than yours, which is a O(n ^ 2) algorithm, is a O(n) algorithm:
BOOL anagrams(NSString *a, NSString *b)
{
if (a.length != b.length)
return NO;
NSCountedSet *aSet = [[NSCountedSet alloc] init];
NSCountedSet *bSet = [[NSCountedSet alloc] init];
for (int i = 0; i < a.length; i++)
{
[aSet addObject:#([a characterAtIndex:i])];
[bSet addObject:#([b characterAtIndex:i])];
}
return [aSet isEqual:bSet];
}
You want to know if two strings contain exactly the same characters? Easiest way would probably be to sort both of them and compare the sorted version.
Another way would be to count the number of appearances of each letter (how many As, how many Bs, and so forth), then compare those counts.
(Note: The second way is just a variation of the first one, it's one efficient way to sort a string)
It looks fine to me. But the code style is slightly odd. I would write it like this:
- (BOOL)isStringAnagram:(NSString *)string1 ofString:(NSString *)string2 {
int len = string1.length;
if (len != string2.length) {
return NO;
}
for (int i=0; i < len; i++) {
int h = 0;
int q = 0;
for (int k = 0; k < len; k++) {
if ([string1 characterAtIndex:i] == [string1 characterAtIndex:k]) {
h++;
}
if ([string1 characterAtIndex:i] == [string2 characterAtIndex:k]) {
q++;
}
}
if (h != q) {
return NO;
}
}
return YES;
}
The main issue I have is with the method name. While it's possible to have parameters that have nothing before them in the name, it is not advisable. i.e. you had findAnagram:: as the name whereas I've used isStringAnagram:ofString:.
This is an implementation on #zmbq suggestion of sorting and comparing.
You should consider the requirements of deleting spaces and being case insensitive.
- (BOOL)isAnagram:(NSString *)leftString and:(NSString *)rightString {
NSString *trimmedLeft = [[leftString stringByReplacingOccurrencesOfString:#" " withString:#""] lowercaseString];
NSString *trimmedRight = [[rightString stringByReplacingOccurrencesOfString:#" " withString:#""] lowercaseString];
return [[self stringToCharArraySorted:trimmedLeft] isEqual:[self stringToCharArraySorted:trimmedRight]];
}
- (NSArray *)stringToCharArraySorted:(NSString *)string {
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int i = 0 ; i < string.length ; i++) {
[array addObject:#([string characterAtIndex:i])];
}
return [[array sortedArrayUsingSelector:#selector(compare:)] copy];
}
called like this
BOOL isAnagram = [self isAnagram:#"A BC" and:#"cba"];
Check the following method which check Anagram strings.
-(BOOL)checkAnagramString:(NSString*)string1 WithAnotherString:(NSString*)string2{
NSCountedSet *countSet1=[[NSCountedSet alloc]init];
NSCountedSet *countSet2=[[NSCountedSet alloc]init];
if (string1.length!=string2.length) {
NSLog(#"NOT ANAGRAM String");
return NO;
}
for (int i=0; i<string1.length; i++) {
[countSet1 addObject:#([string1 characterAtIndex:i])];
[countSet2 addObject:#([string2 characterAtIndex:i])];
}
if ([countSet1 isEqual:countSet2]) {
NSLog(#"ANAGRAM String");
return YES;
} else {
NSLog(#"NOT ANAGRAM String");
return NO;
}
}
Another run of the mill algorithm:
- (BOOL) testForAnagramWithStrings:(NSString *)stringA andStringB: (NSString *)stringB{
stringA = [stringA lowercaseString];
stringB = [stringB lowercaseString];
int counter = 0;
for (int i=0; i< stringA.length; i++){
for (int j=0; j<stringB.length;j++){
if ([stringA characterAtIndex:i]==[stringB characterAtIndex:j]){
counter++;
}
}
}
if (counter!= stringA.length){
return false;
}
return true;
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Iphone UITextField only integer
I want to place a text field that only accepts numbers (0-9, doesn't even need decimals), but even using the "Number Pad" entry option I still get a keyboard with various symbols on it. Is there a better control for this, is there a better control for what I'm doing, or do I just have to validate input manually?
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
/* for backspace */
if([string length]==0){
return YES;
}
/* limit to only numeric characters */
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:#"0123456789"];
for (int i = 0; i < [string length]; i++) {
unichar c = [string characterAtIndex:i];
if ([myCharSet characterIsMember:c]) {
return YES;
}
}
return NO;
}
The code is somehow incorrect, should be
/* limit to only numeric characters */
NSCharacterSet* numberCharSet = [NSCharacterSet characterSetWithCharactersInString:#"0123456789"];
for (int i = 0; i < [string length]; ++i)
{
unichar c = [string characterAtIndex:i];
if (![numberCharSet characterIsMember:c])
{
return NO;
}
}
return YES;
The following code will allow you to only input numbers as well as limit the amount of characters that can be used.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
/* limit to only numeric characters */
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:#"0123456789"];
for (int i = 0; i < [string length]; i++) {
unichar c = [string characterAtIndex:i];
if ([myCharSet characterIsMember:c]) {
return YES;
}
}
/* limit the users input to only 9 characters */
NSUInteger newLength = [customTextField.text length] + [string length] - range.length;
return (newLength > 9) ? NO : YES;
}