Simple question on how to insert a line break using SKLabelNode class in SpriteKit. I have the following code but it does not work -
SKLabelNode *nerdText = [SKLabelNode labelNodeWithFontNamed:#"Times"];
NSString *st1 = #"Test break";
NSString *st2 = #"I want it to break";
NSString *test = [NSString stringWithFormat:#"%#,\r%#",st1,st2]; //Even tried \n
nerdText.text = test;
nerdText.fontSize = 11;
nerdText.fontColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
nerdText.position = CGPointMake(150.0, 250.0);
[self addChild:nerdText];
Please help me out!
I dont think you can, here is a "hack" way to do it
SKNode *nerdText = [SKNode node];
SKLabelNode *a = [SKLabelNode labelNodeWithFontNamed:#"Arial"];
a.fontSize = 16;
a.fontColor = [SKColor yellowColor];
SKLabelNode *b = [SKLabelNode labelNodeWithFontNamed:#"Arial"];
b.fontSize = 16;
b.fontColor = [SKColor yellowColor];
NSString *st1 = #"Line 1";
NSString *st2 = #"Line 2";
b.position = CGPointMake(b.position.x, b.position.y - 20);
a.text = st1;
b.text = st2;
[nerdText addChild:a];
[nerdText addChild:b];
nerdText.position = CGPointMake(150.0, 250.0);
[self addChild:nerdText];
I had the same problem. I created a drop-in replacement for SKLabelNode called DSMultilineLabelNode that supports word wrap, line breaks, etc. The underlying implementation draws the string into a graphics context and then applies that to a texture on an SKSpriteNode.
It's available on GitHub at:
https://github.com/downrightsimple/DSMultilineLabelNode
static func multipleLineText(labelInPut: SKLabelNode) -> SKLabelNode {
let subStrings:[String] = labelInPut.text!.componentsSeparatedByString("\n")
var labelOutPut = SKLabelNode()
var subStringNumber:Int = 0
for subString in subStrings {
let labelTemp = SKLabelNode(fontNamed: labelInPut.fontName)
labelTemp.text = subString
labelTemp.fontColor = labelInPut.fontColor
labelTemp.fontSize = labelInPut.fontSize
labelTemp.position = labelInPut.position
labelTemp.horizontalAlignmentMode = labelInPut.horizontalAlignmentMode
labelTemp.verticalAlignmentMode = labelInPut.verticalAlignmentMode
let y:CGFloat = CGFloat(subStringNumber) * labelInPut.fontSize
print("y is \(y)")
if subStringNumber == 0 {
labelOutPut = labelTemp
subStringNumber++
} else {
labelTemp.position = CGPoint(x: 0, y: -y)
labelOutPut.addChild(labelTemp)
subStringNumber++
}
}
return labelOutPut
}
As of iOS 11/ macOS 10.13, SKLabelNode has a numberOfLines property that behaves in a similar way to the one that UILabel has. By default it's set to 1. If you set it to zero, you can have an unlimited number of lines. See also lineBreakMode and preferredMaxLayoutWidth. I thought it was worth pointing this out here in case anyone arrives at this page before they see the Apple documentation. If your minimum build target is iOS 11/ macOS 10.13, you don't need the helper methods posted above.
Here is another five minute hack by yours truly. It's not too bad.
+(SKSpriteNode*)spritenodecontaininglabelsFromStringcontainingnewlines:(NSString*)text fontname:(NSString*)fontname fontcolor:(NSColor*)colorFont fontsize:(const CGFloat)SIZEFONT verticalMargin:(const CGFloat)VERTICALMARGIN emptylineheight:(const CGFloat)EMPTYLINEHEIGHT {
NSArray* strings = [text componentsSeparatedByString:#"\n"];
//DLog(#"string count: %lu", (unsigned long)strings.count);
NSColor* color = NSColor.clearColor;
#ifdef DEBUG
color = [NSColor colorWithCalibratedRed:1 green:0 blue:0 alpha:0.5];
#endif
SKSpriteNode* spritenode = [SKSpriteNode spriteNodeWithColor:color size:CGSizeMake(0, 0)];
CGFloat totalheight = 0;
CGFloat maxwidth = 0;
NSMutableArray* labels = [NSMutableArray array];
for (NSUInteger i = 0; i < strings.count; i++) {
NSString* str = [strings objectAtIndex:i];
const BOOL ISEMPTYLINE = [str isEqualToString:#""];
if (!ISEMPTYLINE) {
SKLabelNode* label = [SKLabelNode labelNodeWithFontNamed:fontname];
label.text = str;
label.fontColor = colorFont;
label.fontSize = SIZEFONT;
const CGSize SIZEOFLABEL = [label calculateAccumulatedFrame].size;
if (SIZEOFLABEL.width > maxwidth)
maxwidth = SIZEOFLABEL.width;
totalheight += SIZEOFLABEL.height;
[labels addObject:label];
}
else {
totalheight += EMPTYLINEHEIGHT;
[labels addObject:[NSNull null]];
}
if (i + 1 < strings.count)
totalheight += VERTICALMARGIN;
}
spritenode.size = CGSizeMake(maxwidth, totalheight);
//DLog(#"spritenode total size: %#", NSStringFromSize(spritenode.size));
CGFloat y = spritenode.size.height * 0.5;
const CGFloat X = 0;
for (NSUInteger i = 0; i < strings.count; i++) {
id obj = [labels objectAtIndex:i];
if ([obj isKindOfClass:SKLabelNode.class]) {
SKLabelNode* label = obj;
label.verticalAlignmentMode = SKLabelVerticalAlignmentModeTop;
label.position = ccp(X, y);
[spritenode addChild:label];
const CGSize SIZEOFLABEL = [label calculateAccumulatedFrame].size;
y -= SIZEOFLABEL.height;
}
else {
y -= EMPTYLINEHEIGHT;
}
if (i + 1 < labels.count)
y -= VERTICALMARGIN;
}
return spritenode;
}
Btw you will need
static inline CGPoint ccp( CGFloat x, CGFloat y )
{
return CGPointMake(x, y);
}
So after doing a bit of research I learned that SkLabelNode was not intended to have multiline strings involved. Since functionality is limited with SKLabelNode it makes more sense to simply use a UILabel to hold the place of your text. Learning how to smoothly implement UI elements into sprite kit has made life a whole lot easier. UI elements are created programmatically, and added to your scene by using
[self.view addsubview:(your UIelement)];
So all you have to do
1.Initialize an instance of the UIelement in this case a UIlabel
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
label.backgroundColor = [UIColor whiteColor];
label.textColor = [UIColor blackColor];
label.text = #"helllllllllo";
2. After you have created your UIelement just add it TO THE VIEW Using the method described above
3.I have found it important to note that UI elements and SK elements do not interact the same when it comes to positioning. There are some simple methods provided such as convertPointToView:
-(CGPoint)convertPointToView(CGPoint);
To help when it comes to converting points. I hope that helped Good Luck!
I wrote a solution for Swift 3.
An Xcode demo project is available on the open source GitHub project: https://github.com/benmorrow/Multilined-SKLabelNode
Here's the SKLabelNode extension:
extension SKLabelNode {
func multilined() -> SKLabelNode {
let substrings: [String] = self.text!.components(separatedBy: "\n")
return substrings.enumerated().reduce(SKLabelNode()) {
let label = SKLabelNode(fontNamed: self.fontName)
label.text = $1.element
label.fontColor = self.fontColor
label.fontSize = self.fontSize
label.position = self.position
label.horizontalAlignmentMode = self.horizontalAlignmentMode
label.verticalAlignmentMode = self.verticalAlignmentMode
let y = CGFloat($1.offset - substrings.count / 2) * self.fontSize
label.position = CGPoint(x: 0, y: -y)
$0.addChild(label)
return $0
}
}
}
Here's how you use it:
let text = "hot dogs\ncold beer\nteam jerseys"
let singleLineMessage = SKLabelNode()
singleLineMessage.fontSize = min(size.width, size.height) /
CGFloat(text.components(separatedBy: "\n").count) // Fill the screen
singleLineMessage.verticalAlignmentMode = .center // Keep the origin in the center
singleLineMessage.text = text
let message = singleLineMessage.multilined()
message.position = CGPoint(x: frame.midX, y: frame.midY)
message.zPosition = 1001 // On top of all other nodes
addChild(message)
Here's what the app looks like:
The alternative is to create a bitmap version of the text, then use the resulting image with a SKSpriteNode.
It's easier than it sounds.
An example, assume we have a string or an attributed string and a CGSize variable with the size of the resulting text area.
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
// Assuming size is in actual pixels. Multiply size by the retina scaling
// factor if not.
CGContextRef context = CGBitmapContextCreate(NULL, (size_t)round(size.width), (size_t)round(size.height), 8, (size_t)round(size.width) * 4, rgbColorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(rgbColorSpace);
// Draw text, potentially flipping the coordinate system before
// (depending on methods you use).
// Make sure that you draw the font twice as big for retina.
// E.g. [#"My text" drawInRect:rect withAttributes:attr];
// Once we have drawn the text, simply extract the image and
// Make a texture from it.
CGImageRef image = CGBitmapContextCreateImage(context);
SKTexture *texture = [SKTexture textureWithCGImage:image];
CGImageRelease(image);
CGContextRelease(context);
// Texture created, so make a sprite node to use it.
SKSpriteNode *node = [self node];
node.texture = texture;
// Set the node size to the size in non-retina pixels, so if size was with
// scale factor already multiplied in, then we would need to divide by the scale
// factor.
node.size = size;
Here just to contribute my solution. I find myself wanting the same thing - to make multilines of SKLabelNode from a long string. Creating it one by one and manually positioning them is non practical. So I made an easier way to make multiline SKLabelNode. This method uses SKLabelNodes (and not capturing text into image).
Please see my solution if you are interested:
http://xcodenoobies.blogspot.com/2014/12/multiline-sklabelnode-hell-yes-please-xd.html
The result:
Lots of nice solutions here, but I didn't see any written in swift, so here we go. this function will take in one long string, and break it up where you place \n characters.
func createMultiLineText(textToPrint:String, color:UIColor, fontSize:CGFloat, fontName:String, fontPosition:CGPoint, fontLineSpace:CGFloat)->SKNode{
// create node to hold the text block
var textBlock = SKNode()
//create array to hold each line
let textArr = textToPrint.componentsSeparatedByString("\n")
// loop through each line and place it in an SKNode
var lineNode: SKLabelNode
for line: String in textArr {
lineNode = SKLabelNode(fontNamed: fontName)
lineNode.text = line
lineNode.fontSize = fontSize
lineNode.fontColor = color
lineNode.fontName = fontName
lineNode.position = CGPointMake(fontPosition.x,fontPosition.y - CGFloat(textBlock.children.count ) * fontSize + fontLineSpace)
textBlock.addChild(lineNode)
}
// return the sknode with all of the text in it
return textBlock
}
So I know this question is a little older, but just incase any comes back to it like I have, there's now a property preferredMaxLayoutWidth that you can use in conjunction with lineBreakMode and numberOfLines:
Example:
let longMessage = "Super super super super super super super super super long text"
let label = SKLabelNode(fontNamed: "Thonburi")
label.text = longMessage
label.fontSize = 24
label.fontColor = SKColor.black
// set preferredMaxLayoutWidth to the width of the SKScene
label.preferredMaxLayoutWidth = size.width
label.lineBreakMode = .byWordWrapping
label.numberOfLines = 0
addChild(label)
Like several others I have implemented a solution to this problem myself. It's a simple SKLabelNode subclass which can be used as a replacement for the regular SKLabelNode. I find subclassing the best approach for this functionality as I use it "everywhere" "all" the time...
The whole thing is available at github (for anyone interested) but the main gist is as follows: It separates the string and creates regular SKLabelNode instances and ads these as children of the node. This is done whenever setText: is invoked:
- (void)setText:(NSString *)text{
self.subNodes = [self labelNodesFromText:text];
[self removeAllChildren];
for (SKLabelNode *childNode in self.subNodes) {
[self addChild:childNode];
}
_text = #""; // (synthesized in the implementation)
}
The label subnodes are created here:
- (NSArray *)labelNodesFromText:(NSString *)text{
NSArray *substrings = [text componentsSeparatedByString:#"\n"];
NSMutableArray *labelNodes = [[NSMutableArray alloc] initWithCapacity:[substrings count]];
NSUInteger labelNumber = 0;
for (NSString *substring in substrings) {
SKLabelNode *labelNode = [SKLabelNode labelNodeWithFontNamed:self.fontName];
labelNode.text = substring;
labelNode.fontColor = self.fontColor;
labelNode.fontSize = self.fontSize;
labelNode.horizontalAlignmentMode = self.horizontalAlignmentMode;
labelNode.verticalAlignmentMode = self.verticalAlignmentMode;
CGFloat y = self.position.y - (labelNumber * self.fontSize * kLineSpaceMultiplier); // kLineSpaceMultiplier is a float constant. 1.5 is the value I have chosen
labelNode.position = CGPointMake(self.position.x, y);
labelNumber++;
[labelNodes addObject:labelNode];
}
return [labelNodes copy];
}
As you might have noticed I also have a property subNodes (array). This comes in handy elsewhere as the full implementation also allows for changing any of properties with the regular SKLabelNode syntax. (Text, fontName, fontSize, alignment etc.)
If anyone is interested, I've created a better SKLabelNode called SKLabelNodePlus that has multi-line support like Chris Allwein's but also has other features I find pretty useful.
Check it out on GitHub:
https://github.com/MKargin0/SKLabelNodePlus
Using https://github.com/downrightsimple/DSMultilineLabelNode and How to write text on image in Objective-C (iOS)? for reference this is what I did for a quick and dirty way to get a text-wrapping SKNode (Xcode 7.1.1):
-(SKNode*)getWrappingTextNode:(NSString*)text maxWidth:(CGFloat)width {
UIImage *img = [self drawText:text widthDimension:width];
return [SKSpriteNode spriteNodeWithTexture:[SKTexture textureWithImage:img]];
}
-(UIImage*)drawText:(NSString*)text widthDimension:(CGFloat)width {
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
paragraphStyle.alignment = NSTextAlignmentLeft; //or whatever alignment you want
UIFont *font = [UIFont fontWithName:#"Verdana" size:22]; //or whatever font you want
NSDictionary *att = #{NSFontAttributeName:font, NSParagraphStyleAttributeName: paragraphStyle};
//using 800 here but make sure this height is greater than the potential height of the text (unless you want a max-height I guess but I did not test max-height)
CGRect rect = [text boundingRectWithSize:CGSizeMake(width, 800) options:NSStringDrawingUsesLineFragmentOrigin attributes:att context:nil];
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0f);
[text drawInRect:rect withAttributes:att];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Here is a quick and easy function I wrote to just make life easier.
Step 1) Pass in a string, get a SKSpriteNode.
Step 2) Add sprite node to scene.
/******************************************************************************/
- (SKSpriteNode*) ConvertString: (NSString*) str
WithFontSize: (NSInteger) font_size
ToParagraphWithSize: (CGSize) para_size
{
SKSpriteNode* paragraph = [[SKSpriteNode alloc] initWithColor: [SKColor clearColor]
size: para_size];
// Set the anchor point to the top left corner. This is where English
// paragraphs usually start
paragraph.anchorPoint = CGPointMake(0,1);
// Create an array to hold multilple sub strings. These sub strings will
// become multiple SKLabels that will be added to the paragraph sprite node
// created above
NSMutableArray* str_arr = [[NSMutableArray alloc] init];
// Lets separate words by a single space.
NSArray* word_arr = [str componentsSeparatedByString:#" "];
// 50% is an approximate character height to width ratio. Change this
// number to adjust the number of characters per line you would like.
// Increase it if you have a lot of capitol W's
float est_char_width = font_size * 0.50;
NSInteger num_char_per_line = para_size.width / est_char_width;
// For every word in the original string, make sure it fits on the line
// then add it to the string array.
NSString* temp_str = #"";
for (NSString* word in word_arr)
{
if ((NSInteger)word.length <= num_char_per_line - (NSInteger)temp_str.length)
{
temp_str = [NSString stringWithFormat:#"%# %#", temp_str, word];
}
else
{
[str_arr addObject: temp_str];
temp_str = word;
}
}
[str_arr addObject: temp_str];
// For every sub string, create a label node and add it to the paragraph
for (int i = 0; i < str_arr.count; i++)
{
NSString* sub_str = [str_arr objectAtIndex: i];
SKLabelNode* label = [self CreateLabelWithText: sub_str];
label.fontSize = 14;
label.position = CGPointMake(0, -(i+1) * font_size);
[paragraph addChild: label];
}
return paragraph;
}
/******************************************************************************/
- (SKLabelNode*) CreateLabelWithText: (NSString*) str
{
enum alignment
{
CENTER,
LEFT,
RIGHT
};
SKLabelNode* label;
label = [SKLabelNode labelNodeWithFontNamed:#"ChalkboardSE-Light"];
label.name = #"label_name";
label.text = str;
label.zPosition = 1;
label.horizontalAlignmentMode = LEFT;
label.fontColor = [SKColor whiteColor];
return label;
}
I have written a utility method to take a string and divide it up into an array of strings with a given maximum length. It automatically ends each line with a whole word and removes leading whitespace. Hope it helps somebody!
- (NSArray*)linesFromString:(NSString*)string withMaxLineLength:(int)maxLineLength;
{
NSMutableArray *lines = [NSMutableArray arrayWithCapacity:1];
BOOL gotLine = NO;
BOOL doneFormat = NO;
BOOL endOfString = NO;
int innerLoops = 0;
int outerLoops = 0;
int lineIndex = 0;
int currentStringIndex = 0;
int stringLength = (int)[string length];
int rangeLength = maxLineLength;
NSString *line;
NSString *testChar;
NSString *testChar2;
while (!doneFormat) {
outerLoops++;
while (!gotLine) {
endOfString = NO;
innerLoops++;
line = [string substringWithRange:NSMakeRange(currentStringIndex, rangeLength)];
testChar = [line substringWithRange:NSMakeRange(0, 1)];
if (currentStringIndex + rangeLength > [string length] - 1) {
endOfString = YES;
} else {
testChar2 = [string substringWithRange:NSMakeRange(currentStringIndex + rangeLength, 1)];
}
//If the line starts with a space then advance 1 char and try again.
if ([testChar isEqualToString:#" "]) {
currentStringIndex++;
// If we were at the end of the string then reduce the rangeLength as well.
if (endOfString) {
rangeLength--;
}
// else, if this line ends at the end of a word (or the string) then it's good. ie next char in the string is a space.
} else if ([testChar2 isEqualToString:#" "] || endOfString) {
gotLine = YES;
currentStringIndex += [line length];
// else, make the line shorter by one character and try again
} else if (rangeLength > 1){
rangeLength--;
// Otherwise the word takes up more than 1 line so use it all.
} else {
line = [string substringWithRange:NSMakeRange(currentStringIndex, maxLineLength)];
currentStringIndex += [line length];
gotLine = YES;
}
// Make sure we're not stuck in an endless loop
if (innerLoops > 1000) {
NSLog(#"Error: looped too long");
break;
}
}
// If we processed a line, and the line is not nil, add it to our array.
if (gotLine && line) {
[lines insertObject:line atIndex:lineIndex];
lineIndex++;
}
// Reset variables
rangeLength = maxLineLength;
gotLine = NO;
// If the current index is at the end of the string, then we're done.
if (currentStringIndex >= stringLength) {
doneFormat = YES;
// If we have less than a full line left, then reduce the rangeLength to avoid throwing an exception
} else if (stringLength - (currentStringIndex + rangeLength) < 0) {
rangeLength = stringLength - currentStringIndex;
}
// Make sure we're not stuck in an endless loop
if (outerLoops > 1000) {
NSLog(#"Error: Outer-looped too long");
break;
}
}
return lines;
}
And then I just call it and create some label nodes to add to my layer node as follows. I'm aligning my line labels underneath and with the left edge of button2, so it all lines up left justified.
CGFloat fontSize = 30.0f;
int lineCount;
NSString *description = [product localizedDescription];
NSString *line;
NSArray *lines = [self linesFromString:description withMaxLineLength:43];
if (lines) {
lineCount = (int)[lines count];
for (int i = 0; i < lineCount; i++) {
line = [lines objectAtIndex:i];
// Create a new label for each line and add it to my SKSpriteNode layer
SKLabelNode *label = [SKLabelNode labelNodeWithFontNamed:#"Superclarendon-Black"];
label.text = line;
label.fontSize = fontSize;
label.scale = 1.0f;
label.name = #"lineLabel";
label.fontColor = [UIColor blackColor];
label.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
label.position = CGPointMake(button2.position.x - button2.size.width * 0.5f, button2.position.y - button2.size.height - i * fontSize * 1.1);
[layer addChild:label];
}
}
In the scene editor, change the SKLabelNode's text to attributed in the attributes inspector in the right pane, as shown below.
Doing so will give you very much freedom to customize the text that is displayed without having to create multiple SKLabelNode instances or a UIImage. For instance, you can create a paragraph as shown below.
For programmatic interaction, use the attributedString property of the label node to add custom attributes.
label.numberOfLines = 0 //equates to multiple lines
label.numberOfLines.preferredMaxLayoutWidth = screenWidth
I am trying to show the number of objects in an NSArray in a UILabel as part of a UITabelViewCell:
UILabel *numberLabel = (UILabel *)[cell viewWithTag:103];
numberLabel.numberOfLines = [self.inputValues indexOfObject:inputValue];
NSLog(#"rownumber is: %d", numberLabel.numberOfLines);
The NSLoggives me the right number, but the label shows just the default title value. What am I missing here? No errors are thrown.
You need to set the label's text property. Example:
NSUInteger index = [self.inputValues indexOfObject:inputValue];
numberLabel.text = [NSString stringWithFormat:#"Row %lu", (unsigned long)index];
However, it seems likely that you could just use the row from the cell's index path, like this:
numberLabel.text = [NSString stringWithFormat:#"Row %ld", (long)indexPath.row];
I'm pretty sure that instead you want:
UILabel *numberLabel = (UILabel *)[cell viewWithTag:103];
numberLabel.text = [NSString stringWithFormat:#"%d", [self.inputValues indexOfObject:inputValue]];
NSLog(#"rownumber is: %d", numberLabel.numberOfLines);
I have a weird dilema that I can't seem to place a finger on the issue and would like some outside assistance when trying to figure out the issue. I have a NSString value that I read in from a textbox and I convert it into a NSNumber. This works well and I get my value. Then I take my new number and I want to compare it with an array of 4 floating point numbers. However, when I try to compare I never get the proper results and this is where I am pulling my hair out. Below is a small snippet of code explaining my situation:
// THE FIRST IF STATEMENT IS WHAT GETS SELECTED
// newValue = 0.93
// colorRange = {0.10, 0.20, 0.80, 0.90 }
NSNumberFormatter *format = [[NSNumberFormatter alloc] init];
[format setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *newValue = [format numberFromString:value];
[format release];
if (newValue < [colorRange objectAtIndex:0]) {
// Red background
selectedButton.backgroundColor = [UIColor redColor];
}
else if (newValue > [colorRange objectAtIndex:0] && newValue < [colorRange objectAtIndex:1]) {
// White background
selectedButton.backgroundColor = [UIColor whiteColor];
}
else if (newValue > [colorRange objectAtIndex:1] && newValue < [colorRange objectAtIndex:2]) {
// Black background
selectedButton.backgroundColor = [UIColor blackColor];
}
else if (newValue > [colorRange objectAtIndex:2] && newValue < [colorRange objectAtIndex:3]) {
// Blue background
selectedButton.backgroundColor = [UIColor blueColor];
}
else {
// Green background
selectedButton.backgroundColor = [UIColor greenColor];
}
What I am trying to do is see where my input value lies within my percentage range and select a color based on that information. If there is a more optimal way of doing this please let me know.
You can not compare NSNumbers directly like that, as you are comparing the values of their pointers. Instead, use the compare method of NSNumber to compare them like this:
if ([newValue compare:[colorRange objectAtIndex:0]] == NSOrderedAscending) {
// Red background
selectedButton.backgroundColor = [UIColor redColor];
}
...
I would do it in simple way:
if ([newValue floatVaue] < [colorRange objectAtIndex:0] floatValue])
And it is.
This (and the others like it):
newValue < [colorRange objectAtIndex:1]
Compares the pointer newValue to the pointer [colorRange objectAtIndex:1]. So it'll evaluate to non-zero if newValue happens to be lower down in memory.
Having been beaten to saying that by at least two posters, I'll take the time to propose the more compact method:
NSArray *backgroundColours = #[ [UIColor redColor], [UIColor whiteColor], ...];
NSUInteger index = 0;
for(NSNumber *colour in colorRange)
{
if([newValue compare:colour] == NSOrderedAscending)
{
selectedButton.backgroundColor = [backgroundColours objectAtIndex:index];
break;
}
index++;
}
You cannot compare NSNumber* objects using the < or > operators: it compares pointers, giving you arbitrary results. Use the compare: method instead:
if ([newValue compare:[colorRange objectAtIndex:0]] == NSOrderedAscending) ...
NSOrderedAscending means that the receiver is less than the argument
NSOrderedDescending means that the receiver is greater than the argument
NSOrderedSame means that the receiver is equal to the argument
As everybody else said you cannot compare pointers like that, just variables.
You could use
if ([newValue floatValue]<[[color objectAtIndex:0] floatValue]
i need to loop using timer and want to display the output, but the condition is there should be only one label and using that i ve to split the words randomly hide them, use underscores for hidden lables, and now on looping through the timer i need to display the word in the database in the same place
For eg:
in first loop of timer:
MA_A_S
hint: HUMAN
in second loop of timer:
A_NIM_L_S
hint: TIGER
etc..
the "words" with underscore is not being overridden... it comes as MA_A_S A_NIM_L_S
My create function is:
- (void)createbutton:(NSInteger)j {
p = 30;
x = x+p ;
if(x>250) {
x=35;
y=y+70;
}
pLblMyLable1 = [[UILabel alloc] initWithFrame:CGRectMake(x, y, 45, 45)];
[pLblMyLable1 setTag:j+1];
iTag = [pLblMyLable1 tag];
if (i == n|| i == r || i == s) {
pLblMyLable1.hidden = YES;
pLblUnderScore =[[UILabel alloc] initWithFrame:CGRectMake(x, y, 45, 45)];
pLblUnderScore.backgroundColor = [UIColor clearColor];
pLblUnderScore.text = #"_";
pLblUnderScore.font = [UIFont fontWithName:#"Arial" size: 10.0];
[pLblUnderScore setTag:2];
[self.view addSubview:pLblUnderScore];
} else {
pLblMyLable1.hidden = NO;
}
pLblMyLable1.backgroundColor = [UIColor clearColor];
pLblMyLable1.text = pStr;
pLblMyLable1.font = [UIFont fontWithName:#"Arial" size: 10.0];
[self.view addSubview:pLblMyLable1];
[pLblMyLable1 release];
}
Format your string according to your requirement. Use NSString to overWrite in same label's Text.
To add string in same string use stringByAppendingFormat. How to do check this:
NSString *str #"MA_MA_"
YourLabel.text = str
Now
[str stringByAppendingFormat:#"ANI__L....."];
YourLabel.text = str;
Your label will display MA_MA_ANI__L.....