if statement issue in drawRect - ios

Yes, yes. Shame on me. I am trying to draw in UIView and my code is:
NSString *str;
if(kmObj.metal!=#"" && kmObj.metalName2!=#"" && kmObj.metalname3!=#"")
{
str=[NSString stringWithFormat:#"%# + %# + %#",kmObj.metal,kmObj.metalName2,kmObj.metalname3];
}
if(kmObj.metal!=#"" && kmObj.metalName2!=#"" && kmObj.metalname3==#"")
{
str=[NSString stringWithFormat:#"%# + %#",kmObj.metal,kmObj.metalName2];
}
if(kmObj.metal!=#"" && kmObj.metalName2==#"" && kmObj.metalname3==#"")
{
str=[NSString stringWithFormat:#"%#",kmObj.metal];
}
[str drawAtPoint:CGPointMake(10.0,234.0)
forWidth:200
withFont:[UIFont systemFontOfSize:20.0]
minFontSize:20.0
actualFontSize:NULL
lineBreakMode:UILineBreakModeTailTruncation
baselineAdjustment:UIBaselineAdjustmentAlignBaselines];
So, this code suppose to check if the Object contains more than one metal name record. If so, than it has to format string to form: Au+Ag+Cu ... My problem is that in output draw I can't get rid of the + signs where I don't need them. Is there something wrong in my if statement?

Instead of if (string != #""), use ![string isEqualToString:#""] or perhaps ([string length] > 0). You need to make sure you are performing a value comparison, not a pointer comparison.
Anyway, I would write code like this:
NSString *outputString = #"";
if ([firstString length] > 0) {
outputString = [outputString stringByAppendingString:firstString];
}
if ([secondString length] > 0) {
outputString = [outputString stringByAppendingFormat:#" + %#", secondString];
}
if ([thirdString length] > 0) {
outputString = [outputString stringByAppendingFormat:#" + %#", thirdString];
}
With this technique, you check each string individually, and only include a plus sign when you know another valid string will follow it.

String comparisons should take the form: [stringA isEqualToString:stringB]
From the docs: When you know both objects are strings, this method is a faster way to check equality than isEqual:
Plus, == for strings is weird anyways - they are non-primitives and you're wanting a value comparison.
Also, you should take into account the possibility of having nil and/or [NSNull null] values (depending on where these values are sourced). Your current test of whether or not they are equal to empty strings doesn't take this into account.

Did you mean that you don't want the "+" sign? Then don't put it in your NSString.
So instead of
str = [NSString stringWithFormat:#"%# + %# + %#",kmObj.metal,kmObj.metalName2,kmObj.metalname3];
do
str = [NSString stringWithFormat:#"%# %# %#",kmObj.metal,kmObj.metalName2,kmObj.metalname3];
also use [kmObj.metal isEqualToString:#""] for your string comparison

Related

How can i check string contains unknown character?

I am calling webservice in the response i am getting the string.
When i print the string in NSLog it return empty string and When i check the length it returns 1.
So my problem is that how can i check the string is empty or not.
#define CHECK_NA_STRING(str) (str == (id)[NSNull null] || [str length] == 0)?#"N/A":str
NSLog(#"%#",CHECK_NA_STRING([dict objectForKey:#"ADDRESS_A"])); // nothing empty string
NSLog(#"%d",[CHECK_NA_STRING([dict objectForKey:#"ADDRESS_A"]) length]); // return 1
So how can i check that string is empty or not?
Thanks.
So the string is just a space? Then it will still have a length of 1.
Try:
NSString* string = ...;
if([string isKindOfClass:[NSString class]])
{
NSCharacterSet* invertedWhitespaceSet = [[NSCharacterSet whitespaceAndNewlineCharacterSet] invertedSet];
const NSRange nonEmptyCharacterRange = [string rangeOfCharacterFromSet:invertedWhitespaceSet options:NSCaseInsensitiveSearch];
if(nonEmptyCharacterRange.location == NSNotFound)
{
// Empty invalid string
}
else
{
// Non-empty valid string
}
}
The string is not considered empty if it contains a binary zero (null character). For instance, try this code:
#define CHECK_NA_STRING(str) (str == (id)[NSNull null] || [str length] == 0)?#"N/A":str
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:#"\0" forKey:#"ADDRESS_A"];
NSLog(#"%#",CHECK_NA_STRING([dict objectForKey:#"ADDRESS_A"])); // nothing empty string
NSLog(#"%d",[CHECK_NA_STRING([dict objectForKey:#"ADDRESS_A"]) length]); // return 1
Nothing will print for the first NSLOG, but the second will print a "1". Indeed the string is one character long; it just messes up your NSLOG.
You probably want to test for some valid range of responses, or some invalid range. Perhaps, you could use a regular expression.

Pull first name and last initial from string

I have an NSString that contains a users full name. Some names are in the standard first and last formation (Kyle Begeman) and others are just a single name (TechCrunch).
How would I grab the first name as is and then the first initial of the last name, and if there is only one name, just grab the whole name?
Basically I want the above to be turned into Kyle B. or just TechCrunch depending on the name.
NSString *username = #"Kyle Begeman"
NSString *otherUserName = #"TechCrunch"
converted to
#"Kyle B"
// No conversion because it is a single word name
#"TechCrunch"
Using substringToIndex is how I can grab the first letter in the whole string, and I know there is a way to separate the string by #" " whitespace into an array but I can figure out how to easily produce the result the way it needs to be.
Any help would be great!
(NSString*)firstNameWithInitial:(NSString*)userName {
NSArray *array = [userName componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
array = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF != ''"]];
NSString *firstName = [array objectAtIndex:0];
NSString finalNameString;
if ([array count] > 1) {
NSString *lastNameInitial = [[array objectAtIndex:1] substringToIndex:1];
finalNameString = [firstName stringByAppendingString:[NSString stringWithFormat:#" %#", lastNameInitial]];
else {
finalNameString = firstName;
}
return finalNameString;
}
This function should return what you need. Note that you can modify this to work with people who have more than 2 names, by checking the number of objects in the array.
Find a position pos of the first space in the string. If there is no space, or if the space is the last character of the string, then return the entire string; otherwise, return substring in the range from zero to pos+1, inclusive:
NSRange range = [str rangeOfString:#" "];
if (range.location == NSNotFound || range.location == str.length-1) {
return str;
} else {
return [str substringToIndex:range.location+1];
}
You could use NSScanner to find substrings.
NSString *name = #"Some name";
NSString *firstName;
NSString *lastName;
NSScanner *scanner = [NSScanner scannerWithString:name];
[scanner scanUpToString:#" " intoString:&firstName]; // Scan all characters up to the first space
[scanner scanUpToString:#"" intoString:&lastName]; // Scan remaining characters
if (lastName != nil) {
// It was no space and lastName is empty
} else {
// There was at least one space and lastName contains a string
}

How to pad strings to a fixed width with NSMutableString?

I'm trying to write a string to a text file. That text file will then be read by another program. That second program is expecting the different "fields" in the text file to be a fixed width. Therefore, when I write the text file with my app, I will need to add spaces between my actual data to get everything to line up correctly. How do I get these spaces added?
So far, I've tried writing a function that takes a source string and a target length as input. If the target is longer than the source, it just appends " ". Code for this routine is below:
- (NSString *) makeStringFrom:(NSString *)source withLength:(NSInteger)length
{
// Method to add spaces to the end of a string to get it to a certain length
if ([source length] > length)
{
// String is too long - throw warning and send it back
NSLog(#"Warning - string is already longer than length supplied. Returning source string");
return source;
}
else if ([source length] == length)
{
// String is already correct length, so just send it back
return source;
}
else
{
// String is too short, need to add spaces
NSMutableString *newString = [[NSMutableString alloc] initWithString:source];
NSLog(#"newString initial length = %d",[newString length]);
for (int current = [source length]; current < length; current ++)
{
[newString stringByAppendingString:#" "];
NSLog(#"hit");
}
NSLog(#"target length = %d. newString length = %d",length,[newString length]);
return newString;
}
}
This apparently doesn't work. The length of the string I'm getting back in the return isn't changing any from the length of the supplied string, even when the NSLog(#"hit"); runs multiple times.
There's a stringByPaddingToLength:withString:startingAtIndex: method on NSString that does just this.
You did a silly mistake here
[newString stringByAppendingString:#" "];
This returns a new string, and it doesnot effect the caller object. You need to store it
newString=[newString stringByAppendingString:#" "];
or simply
[newString appendString:#" "];
You want to change:
[newString stringByAppendingString:#" "];
into:
newString = [newString stringByAppendingString:#" "];

iOS can't check if object is null

So I have the following code:
- (IBAction)doSomething
{
if (txtName.text != (id)[NSNull null] || txtName.text.length != 0 ) {
NSString *msg = [[NSString alloc] initWithFormat:#"Hello, %#", txtName.text];
[lblMessage setText:msg];
}
}
txtName is an UITextField, what I'm doing wrong? I'm trying to display some text only when the user types something in the box.
Best Regards,
Text in a text field is a NSString instance or nil value, it is never equal to the instance of NSNull class (which is not the same as nil). So as 1st comparison is always true then the whole if-condition evaluates to true and message appears.
You could correct your if condition to
if (txtName.text != nil && txtName.text.length != 0 )
or, as sending length message to the nil will return 0 anyway just have
if (txtName.text.length != 0 )
although I usually use the 1st option with 2 comparisons
if (txtName.text != (id)[NSNull null] || txtName.text.length != 0 ) {
Read it as "If the text is null or the length is not 0"
txtName.text is never nil (you can just compare against nil for a null check, by the way) - the text box always holds some text, even if it's empty. So the first disjunct is always true, and the box will always appear.
I got the same problem like you. This problem relates to NSNull class. And here is my code to check object is null.
NSString* text;
if([text isKindOfClass:[NSNull class]])
{
//do something here if that object is null
}
Hope this can help.
#define SAFESTRING(str) ISVALIDSTRING(str) ? str : #""
#define ISVALIDSTRING(str) (str != nil && [str isKindOfClass:[NSNull class]] == NO)
#define VALIDSTRING_PREDICATE [NSPredicate predicateWithBlock:^(id evaluatedObject, NSDictionary *bindings) {return (BOOL)ISVALIDSTRING(evaluatedObject);}]
SAFESTRING(PASS_OBJECT OR STRING);
Solution found! ![txtName.text isEqualToString:#""]
- (IBAction)doSomething
{
if (![txtName.text isEqualToString:#""]){
NSString *msg = [[NSString alloc] initWithFormat:#"Hello, %#", txtName.text];
[lblMessage setText:msg];
}
}
Please try this:
when value of myObj is nil or < null>
if([myObj isEqual:[NSNull class]] || !myObj) {
// your code
}

How do I test if a string is empty in Objective-C?

How do I test if an NSString is empty in Objective-C?
You can check if [string length] == 0. This will check if it's a valid but empty string (#"") as well as if it's nil, since calling length on nil will also return 0.
Marc's answer is correct. But I'll take this opportunity to include a pointer to Wil Shipley's generalized isEmpty, which he shared on his blog:
static inline BOOL IsEmpty(id thing) {
return thing == nil
|| ([thing respondsToSelector:#selector(length)]
&& [(NSData *)thing length] == 0)
|| ([thing respondsToSelector:#selector(count)]
&& [(NSArray *)thing count] == 0);
}
The first approach is valid, but doesn't work if your string has blank spaces (#" "). So you must clear this white spaces before testing it.
This code clear all the blank spaces on both sides of the string:
[stringObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet] ];
One good idea is create one macro, so you don't have to type this monster line:
#define allTrim( object ) [object stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet] ]
Now you can use:
NSString *emptyString = #" ";
if ( [allTrim( emptyString ) length] == 0 ) NSLog(#"Is empty!");
One of the best solution I ever seen (better than Matt G's one) is this improved inline function I picked up on some Git Hub repo (Wil Shipley's one, but I can't find the link) :
// Check if the "thing" passed is empty
static inline BOOL isEmpty(id thing) {
return thing == nil
|| [thing isKindOfClass:[NSNull class]]
|| ([thing respondsToSelector:#selector(length)]
&& [(NSData *)thing length] == 0)
|| ([thing respondsToSelector:#selector(count)]
&& [(NSArray *)thing count] == 0);
}
You should better use this category:
#implementation NSString (Empty)
- (BOOL) isWhitespace{
return ([[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]length] == 0);
}
#end
Another option is to check if it is equal to #"" with isEqualToString: like so:
if ([myString isEqualToString:#""]) {
NSLog(#"myString IS empty!");
} else {
NSLog(#"myString IS NOT empty, it is: %#", myString);
}
I put this:
#implementation NSObject (AdditionalMethod)
-(BOOL) isNotEmpty
{
return !(self == nil
|| [self isKindOfClass:[NSNull class]]
|| ([self respondsToSelector:#selector(length)]
&& [(NSData *)self length] == 0)
|| ([self respondsToSelector:#selector(count)]
&& [(NSArray *)self count] == 0));
};
#end
The problem is that if self is nil, this function is never called. It'll return false, which is desired.
Just pass your string to following method:
+(BOOL)isEmpty:(NSString *)str
{
if(str.length==0 || [str isKindOfClass:[NSNull class]] || [str isEqualToString:#""]||[str isEqualToString:NULL]||[str isEqualToString:#"(null)"]||str==nil || [str isEqualToString:#"<null>"]){
return YES;
}
return NO;
}
May be this answer is the duplicate of already given answers, but i did few modification and changes in the order of checking the conditions. Please refer the below code:
+(BOOL)isStringEmpty:(NSString *)str {
if(str == nil || [str isKindOfClass:[NSNull class]] || str.length==0) {
return YES;
}
return NO;
}
Swift Version
Even though this is an Objective C question, I needed to use NSString in Swift so I will also include an answer here.
let myNSString: NSString = ""
if myNSString.length == 0 {
print("String is empty.")
}
Or if NSString is an Optional:
var myOptionalNSString: NSString? = nil
if myOptionalNSString == nil || myOptionalNSString!.length == 0 {
print("String is empty.")
}
// or alternatively...
if let myString = myOptionalNSString {
if myString.length != 0 {
print("String is not empty.")
}
}
The normal Swift String version is
let myString: String = ""
if myString.isEmpty {
print("String is empty.")
}
See also: Check empty string in Swift?
Just use one of the if else conditions as shown below:
Method 1:
if ([yourString isEqualToString:#""]) {
// yourString is empty.
} else {
// yourString has some text on it.
}
Method 2:
if ([yourString length] == 0) {
// Empty yourString
} else {
// yourString is not empty
}
Simply Check your string length
if (!yourString.length)
{
//your code
}
a message to NIL will return nil or 0, so no need to test for nil :).
Happy coding ...
You can check either your string is empty or not my using this method:
+(BOOL) isEmptyString : (NSString *)string
{
if([string length] == 0 || [string isKindOfClass:[NSNull class]] ||
[string isEqualToString:#""]||[string isEqualToString:NULL] ||
string == nil)
{
return YES; //IF String Is An Empty String
}
return NO;
}
Best practice is to make a shared class say UtilityClass and ad this method so that you would be able to use this method by just calling it through out your application.
You have 2 methods to check whether the string is empty or not:
Let's suppose your string name is NSString *strIsEmpty.
Method 1:
if(strIsEmpty.length==0)
{
//String is empty
}
else
{
//String is not empty
}
Method 2:
if([strIsEmpty isEqualToString:#""])
{
//String is empty
}
else
{
//String is not empty
}
Choose any of the above method and get to know whether string is empty or not.
It is working as charm for me
If the NSString is s
if ([s isKindOfClass:[NSNull class]] || s == nil || [s isEqualToString:#""]) {
NSLog(#"s is empty");
} else {
NSLog(#"s containing %#", s);
}
So aside from the basic concept of checking for a string length less than 1, it is important to consider context deeply.
Languages human or computer or otherwise might have different definitions of empty strings and within those same languages, additional context may further change the meaning.
Let's say empty string means "a string which does not contain any characters significant in the current context".
This could mean visually, as in color and background color are same in an attributed string. Effectively empty.
This could mean empty of meaningful characters. All dots or all dashes or all underscores might be considered empty.
Further, empty of meaningful significant characters could mean a string that has no characters the reader understands.
They could be characters in a language or characterSet defined as meaningless to the reader. We could define it a little differently to say the string forms no known words in a given language.
We could say empty is a function of the percentage of negative space in the glyphs rendered.
Even a sequence of non printable characters with no general visual representation is not truly empty. Control characters come to mind. Especially the low ASCII range (I'm surprised nobody mentioned those as they hose lots of systems and are not whitespace as they normally have no glyphs and no visual metrics). Yet the string length is not zero.
Conclusion.
Length alone is not the only measure here.
Contextual set membership is also pretty important.
Character Set membership is a very important common additional measure.
Meaningful sequences are also a fairly common one. ( think SETI or crypto or captchas )
Additional more abstract context sets also exist.
So think carefully before assuming a string is only empty based on length or whitespace.
Very useful post, to add NSDictionary support as well one small change
static inline BOOL isEmpty(id thing) {
return thing == nil
|| [thing isKindOfClass:[NSNull class]]
|| ([thing respondsToSelector:#selector(length)]
&& ![thing respondsToSelector:#selector(count)]
&& [(NSData *)thing length] == 0)
|| ([thing respondsToSelector:#selector(count)]
&& [thing count] == 0);
}
- (BOOL)isEmpty:(NSString *)string{
if ((NSNull *) string == [NSNull null]) {
return YES;
}
if (string == nil) {
return YES;
}
if ([string length] == 0) {
return YES;
}
if ([[string stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0) {
return YES;
}
if([[string stringByStrippingWhitespace] isEqualToString:#""]){
return YES;
}
return NO;
}
The best way is to use the category.
You can check the following function. Which has all the conditions to check.
-(BOOL)isNullString:(NSString *)aStr{
if([(NSNull *)aStr isKindOfClass:[NSNull class]]){
return YES;
}
if ((NSNull *)aStr == [NSNull null]) {
return YES;
}
if ([aStr isKindOfClass:[NSNull class]]){
return YES;
}
if(![[aStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]){
return YES;
}
return NO;
}
The best way in any case is to check the length of the given string.For this if your string is myString then the code is:
int len = [myString length];
if(len == 0){
NSLog(#"String is empty");
}
else{
NSLog(#"String is : %#", myString);
}
if (string.length == 0) stringIsEmpty;
check this :
if ([yourString isEqualToString:#""])
{
NsLog(#"Blank String");
}
Or
if ([yourString length] == 0)
{
NsLog(#"Blank String");
}
Hope this will help.
You can easily check if string is empty with this:
if ([yourstring isEqualToString:#""]) {
// execute your action here if string is empty
}
I have checked an empty string using below code :
//Check if we have any search terms in the search dictionary.
if( (strMyString.text==(id) [NSNull null] || [strMyString.text length]==0
|| strMyString.text isEqual:#"")) {
[AlertView showAlert:#"Please enter a valid string"];
}
Its as simple as if([myString isEqual:#""]) or if([myString isEqualToString:#""])
//Different validations:
NSString * inputStr = #"Hey ";
//Check length
[inputStr length]
//Coming from server, check if its NSNull
[inputStr isEqual:[NSNull null]] ? nil : inputStr
//For validation in allowed character set
-(BOOL)validateString:(NSString*)inputStr
{
BOOL isValid = NO;
if(!([inputStr length]>0))
{
return isValid;
}
NSMutableCharacterSet *allowedSet = [NSMutableCharacterSet characterSetWithCharactersInString:#".-"];
[allowedSet formUnionWithCharacterSet:[NSCharacterSet decimalDigitCharacterSet]];
if ([inputStr rangeOfCharacterFromSet:[allowedSet invertedSet]].location == NSNotFound)
{
// contains only decimal set and '-' and '.'
}
else
{
// invalid
isValid = NO;
}
return isValid;
}
You can have an empty string in two ways:
1) #"" // Does not contain space
2) #" " // Contain Space
Technically both the strings are empty. We can write both the things just by using ONE Condition
if ([firstNameTF.text stringByReplacingOccurrencesOfString:#" " withString:#""].length==0)
{
NSLog(#"Empty String");
}
else
{
NSLog(#"String contains some value");
}
Try the following
NSString *stringToCheck = #"";
if ([stringToCheck isEqualToString:#""])
{
NSLog(#"String Empty");
}
else
{
NSLog(#"String Not Empty");
}
Based on multiple answers I have created a ready to use category combining #iDevAmit and #user238824 answers.
Specifically it goes in the following order
Check for null/nil
Check if if string is empty using it's length count.
Check if string is white spaces.
Header
//
// NSString+Empty.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
#interface NSString (Empty)
- (BOOL)isEmptyOrWhiteSpacesOrNil;
#end
NS_ASSUME_NONNULL_END
Implementation
//
// NSString+Empty.m
#import "NSString+Empty.h"
#implementation NSString (Empty)
- (BOOL) isWhitespace{
return ([[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]length] == 0);
}
- (BOOL)isEmptyOrWhiteSpacesOrNil {
if(self == nil || [self isKindOfClass:[NSNull class]] || self.length==0 || [self isWhitespace] == YES) {
return YES;
}
return NO;
}
#end
/*
Credits
1. https://stackoverflow.com/a/24506942/7551807
2. https://stackoverflow.com/a/1963273/7551807
*/
Usage:
of-course the function will never be triggered if your string is null. Case one is there just for extra security. I advice checking for nullability before attempting to use this method.
if (myString) {
if [myString isEmptyOrWhiteSpacesOrNil] {
// String is empty
}
} else {
// String is null
}
if(str.length == 0 || [str isKindOfClass: [NSNull class]]){
NSLog(#"String is empty");
}
else{
NSLog(#"String is not empty");
}

Resources