Cocos2d - CCLabelTTF overlays new value when updated - ios

I have a CCLabelTTF variable defined as follows
#implementation LevelScene
{
CCLabelTTF *_collectedLabel;
int collectedStars1;
int collectedStars2;
int collectedStars3;
}
I also have a CCScrollView and I listen for scrollViewDidScroll.
- (void)setPageIndicatorTo:(NSInteger)page
{
if (page == 0) {
_collectedLabel.string = [NSString stringWithFormat:#"%d/75", collectedStars1];
} else if (page == 1) {
_collectedLabel.string = [NSString stringWithFormat:#"%d/75", collectedStars2];
} else if (page == 2) {
_collectedLabel.string = [NSString stringWithFormat:#"%d/75", collectedStars3];
}
}
- (void)scrollViewDidScroll:(CCScrollView *)scrollView
{
[self setPageIndicatorTo:_scrollView.horizontalPage];
}
In didLoadFromCCB, I set _collectedLabel.string to some value. It gives me the following :
When the view scroll, it calls - (void)setPageIndicatorTo:(NSInteger)page and thus updates the string. I then get
It should be 0/75. The new label overlays the previous one... How can I force the string to be updated?
I tried setting the string to "" before setting it to another value, but it gave the same result..

Related

Stop scrolling on UITableView at last during XCUI TestCase

In my one of UITableView have more then 10 rows. I want to scroll till last row while UITestCase running.
I have written below code to scroll till last row.
-(void)scrollToElement:(XCUIElement *)element application:(XCUIApplication *)app{
while ([self visible:element withApplication:app]) {
XCUIElement *searchResultTableView = app.tables[#"searchResultView"];
XCUICoordinate *startCoord = [searchResultTableView coordinateWithNormalizedOffset:CGVectorMake(0.5, 0.5)];
XCUICoordinate *endCoord = [startCoord coordinateWithOffset:CGVectorMake(0.0, -262)];
[startCoord pressForDuration:0.01 thenDragToCoordinate:endCoord];
}
}
-(BOOL)visible:(XCUIElement *)element withApplication:(XCUIApplication *)app{
if (element.exists && !CGRectIsEmpty(element.frame) && element.isHittable) {
return CGRectContainsRect([app.windows elementBoundByIndex:0].frame, element.frame);
} else {
return FALSE;
}
}
An i have called above method in my one of UITestCase method by below code
XCUIElement *searchResultTableView = app.tables[#"searchResultView"];
[self waitForElementToAppear:searchResultTableView withTimeout:30];
XCUIElement *table = [app.tables elementBoundByIndex:0];
XCUIElement *lastCell = [table.cells elementBoundByIndex:table.cells.count - 1];
[self scrollToElement:lastCell application:app];
By this code i can scroll to last row but after reaching last row, it continue doing scroll means can't stop scrolling.
Please help me to scroll to only last row and then it should stop to scroll so that i can perform next action event.
I have refer StackOverFlow answer but none of them meet my requirement.
Thanks in advance.
I faced similar issue in one of my project.
In that I wanted to test "Load More" feature by TestKit framework.
Here is some workaround to achieve the same scenario.
//app : is your current instance of appliaction
//listTable : is a Table which you've found via accessibility identifier
//loadMoreTest : is a parameter to determine whether code should perform test for loadmore feature or not
- (void)testScrollableTableForApplication:(XCUIApplication *)app
forTable:(XCUIElement *)listTable
withLoadMoreTest:(BOOL)loadMoreTest {
[listTable accessibilityScroll:UIAccessibilityScrollDirectionUp];
[listTable swipeUp];
if (loadMoreTest) {
__block BOOL isLoadMoreCalled;
__block XCUIElement *lastCell;
__block __weak void (^load_more)();
void (^loadMoreCall)();
load_more = loadMoreCall = ^() {
XCUIElementQuery *tablesQuery = app.tables;
XCUIElementQuery *cellQuery = [tablesQuery.cells containingType:XCUIElementTypeCell identifier:#"LoadMoreCell"];
lastCell = cellQuery.element;
if ([lastCell elementIsWithinWindowForApplication:app]) {
[self waitForElementToAppear:lastCell withTimeout:2];
[lastCell tap];
isLoadMoreCalled = true;
[self wait:2];
}
[listTable swipeUp];
if (!isLoadMoreCalled) {
load_more();
}
};
loadMoreCall();
}
}
- (void)waitForElementToAppear:(XCUIElement *)element withTimeout:(NSTimeInterval)timeout
{
NSUInteger line = __LINE__;
NSString *file = [NSString stringWithUTF8String:__FILE__];
NSPredicate *existsPredicate = [NSPredicate predicateWithFormat:#"exists == 1"];
[self expectationForPredicate:existsPredicate evaluatedWithObject:element handler:nil];
[self waitForExpectationsWithTimeout:timeout handler:^(NSError * _Nullable error) {
if (error != nil) {
NSString *message = [NSString stringWithFormat:#"Failed to find %# after %f seconds",element,timeout];
[self recordFailureWithDescription:message inFile:file atLine:line expected:YES];
}
}];
}
create one category for XCUIElement
XCUIElement+Helper.m and import it into your respective Test class.
#import <XCTest/XCTest.h>
#interface XCUIElement (Helper)
/// Check whether current XCUIElement is within current window or not
- (BOOL)elementIsWithinWindowForApplication:(XCUIApplication *)app ;
#end
#implementation XCUIElement (Helper)
/// Check whether current XCUIElement is within current window or not
/*
#description: we need to check particular element's frame and window's frame is intersecting or not, to get perfectly outcome whether element is currently visible on screen or not, because if element has not yet appeared on screen then also the flag frame, exists and hittable can become true
*/
- (BOOL)elementIsWithinWindowForApplication:(XCUIApplication *)app {
if (self.exists && !CGRectIsEmpty(self.frame) && self.hittable)
return CGRectContainsRect(app.windows.allElementsBoundByIndex[0].frame, self.frame);
else
return false;
}
#end
To get the "Load More" cell, i've given the
cell.accessibilityIdentifier = #"LoadMoreCell";
Rest of the code is, recursive function in testScrollableTableForApplication to make Tableview scroll to reach to bottom so i can have the access of load more cell(in your case last cell). Then i am performing the action Tap to fetch new records from server. Then again i am scrolling the Table to verify if the new records has been fetched from server or not.
Tip : you can replace recursive function with do while or while loop to achieve the same.
Hope this helps!
Happy Coding!!

UILabel int count ++ doesn't work

I'm trying to indefinitely count up a number of taps on a UILabel, every time the label is tapped a different string is displayed. However, it stops at 2 taps always using ++ or += 1
-(void)cycleLabelString {
int taps;
taps += 1;
NSLog(#"taps = %d", taps);
if (taps == 1) {
self.randomLabel.text = [NSString stringWithFormat:#"$%.2f", pagesCount * 0.69];
} else if (taps == 2) {
self.randomLabel.text = [NSString stringWithFormat:#"%d", pagesCount];
} else if (taps >= 3) {
NSLog(#" >= 3");
}
}
int taps;
This initializes a new taps each time, and it is initialized to zero by default. You probably want it in a property. Make a private class extension at the top of your .m file like this:
#interface YourClassNameHere ()
#property (nonatomic) int taps;
#end
And then to use it:
-(void)cycleLabelString {
self.taps += 1;
NSLog(#"taps = %d", self.taps);
if (self.taps == 1) {
self.randomLabel.text = [NSString stringWithFormat:#"$%.2f", pagesCount * 0.69];
} else if (self.taps == 2) {
self.randomLabel.text = [NSString stringWithFormat:#"%d", pagesCount];
} else if (self.taps >= 3) {
NSLog(#" >= 3");
}
}
is this function getting called everytime the label is tapped? if so, you will need to define taps as a global variable, as it is being reset everytime the label is tapped. try something like:
int taps;
-(void)cycleLabelString {
...

My UILabel is not displaying when my if statement is false

I have a story board that has a UITextField, UIButton, UIImage, and UILabel to display the images in an array. If you type the correct name for the image file into a text field. So, the problem is that once the text field input does not match, it should update the UILabel to display "Result not found", but it doesn't.
#import "ViewController.h"
#interface ViewController ()
{
myClass *myNewClass;
NSMutableArray *picArray;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
picArray = [#[#"Button_Red",#"Button_Green"]mutableCopy];
}
- (IBAction)displayImageAction:(id)sender
{
NSString *titleSearched = self.textSearchField.text;
NSString *titleNotHere = self.notFoundLabel.text;
//Declare a bool variable here and set
BOOL variable1;
for (int i = 0; i < picArray.count; i++)
{
NSString *currentPic = picArray[i];
if ([titleSearched isEqualToString:currentPic])
{
variable1 = YES;
}
}
if (variable1 == YES) {
//this works fine displays the image
self.outputImage.image = [UIImage imageNamed: titleSearched];
[self.textSearchField resignFirstResponder];
} else {
//problem is here its not showing when input for the array is not equal it should display a message label "Result Not Found" but it remains blank on the IOS simulator
titleNotHere = [NSString stringWithFormat:#"Result Not found"];
[self.textSearchField resignFirstResponder];
}
}
//Get rid of the texfield when done typing
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// Retract keyboard if up
[self.textSearchField resignFirstResponder];
}
Your problem is that
titleNotHere = [NSString stringWithFormat:#"Result Not found"];
simply sets the method variable titleNotHere.
What you want is
self.notFoundLabel.text=#"Result Not found";
You will also want
self.notFoundLabel.text=#"";
when the result is found.
I think you will have to SET the value to the variable
self.notFoundLabel.text = [NSString stringWithFormat:#"Result Not found"]
or
self.notFoundLabel setText:[NSString stringWithFormat:#"Result Not found"]
UILabel.text = #"whatever..." is actually converted into [UILable setText:#"whatever..."].
NSString *labelText = UILabel.text has to be thought as NSString *labelText = [UILabel text];
This:
NSString *titleNotHere = self.notFoundLabel.text;
stores the text from the label into a variable, but updating that variable again will not change the label text - it only changes what that variable points to.
You need to explicitly update the label text:
self.notFoundLabel.text = #"Result Not found";
note also that this uses a string literal - you don't need to use a format string as you aren't adding any parameters to it.
Also, when checking booleans, don't use if (variable1 == YES) {, just use if (variable1) { (it's safer).

Change Text Of A UILabel To A Random Array Object By Pressing UIButton

As the title says... I need to change the contents of my UILabel to a random object from NSArray by pressing a UIButton... Here is the code i have in the button:
- (IBAction)moodButton:(UILongPressGestureRecognizer *)sender {
UILabel *moodLabel = [[UILabel alloc] init];
if (sender.state == UIGestureRecognizerStateEnded) {
NSArray *moodArray = [[NSArray alloc] initWithObjects:#"Happy", #"Angry", #"Sad", #"Bored",
#"Tired", #"Stressed", #"Busy", nil];
id randomObject = [moodArray objectAtIndex:arc4random_uniform([moodArray count])];
if (randomObject == moodArray[0]) {
moodLabel.text = #"Happy";
}
else if (randomObject == moodArray[1]) {
moodLabel.text = #"Angry";
}
else if (randomObject == moodArray[2]) {
moodLabel.text = #"Sad";
}
else if (randomObject == moodArray[3]) {
moodLabel.text = #"Bored";
}
else if (randomObject == moodArray[4]) {
moodLabel.text = #"Tired";
}
else if (randomObject == moodArray[5]) {
moodLabel.text = #"Stressed";
}
else if (randomObject == moodArray[6]) {
moodLabel.text = #"Busy";
}
}
}
What am I doing wrong?
Thanks in advance.
You have a number of issues with your code.
You're creating a new label and then doing nothing with it other than adding some text (not even adding it to another view). Do you have an existing label you want to use instead? I'd recommend you keep a property pointing to a label in your view, which you can use to just update the text.
Your entire if statement is completely redundant. randomObject already contains a random string from your array, so you don't need to manually check which value it contains. Just remove your whole if statement, and do:
moodLabel.text = (NSString *)randomObject;
The answer by James covers the issues but I thought I would clarify by showing some code.
- (IBAction)moodButton:(UILongPressGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
NSArray *moodArray = #[ #"Happy", #"Angry", #"Sad", #"Bored",
#"Tired", #"Stressed", #"Busy" ];
NSString *randomString = moodArray[arc4random_uniform([moodArray count])];
self.moodLabel.text = randomString;
}
}
Note how the label is needs to be obtained from the existing label. Don't create a new one. Also note the use of modern Objective-C syntax for the array and its access.

Clearing/Resetting all string and variables

I have a routine in xcode that calls a function and spits out a result to a UITextView element on an iPhone app.
Before the routine is started I want to reset all NSString objects/values and any variables that I used to calculate the result. Is there a quick way to do this?
So far no matter what I retype in the UITextField it just gets ignored after the initial calculation.
Code for the solve button :-
- (IBAction)Solve:(id)sender {
//
// Reset strings and variable code here
//
[_Number1 resignFirstResponder];
[_Number2 resignFirstResponder];
[_Number3 resignFirstResponder];
[_Number4 resignFirstResponder];
[_Number5 resignFirstResponder];
[_Number6 resignFirstResponder];
[_TargetNum resignFirstResponder];
// Dismiss Keyboard
int numb1,numb2,numb3,numb4,numb5,numb6,numTar;
numb1 = [self.Number1.text intValue];
numb2 = [self.Number2.text intValue];
numb3 = [self.Number3.text intValue];
numb4 = [self.Number4.text intValue];
numb5 = [self.Number5.text intValue];
numb6 = [self.Number6.text intValue];
numTar = [self.TargetNum.text intValue];
mainLoopOne(numb1,numb2,numb3,numb4,numb5,numb6,numTar);
// Start calculation with field values
readAnswers = #"Please read answers bottom-up.\n";
cantCalc = NULL;
finalResult = #"";
if (numb1 != 0) {
int ii;
for(ii = 0; ii < 6 ; ii++) {
if (allAnswers[ii] != NULL) {
finalResult = [finalResult stringByAppendingFormat:#"%#", allAnswers[ii]];
}
}
if (finalResult == NULL) {
cantCalc = #"Unfortunately, that doesn't seem to be possible, as there was no answer calculated.\n";
readAnswers = #"";
}
CompileText = [NSString stringWithFormat:#"%#\n%#\nfrom %d combination tries.", readAnswers, finalResult, countCombi];
[self.TextWin setText:CompileText];
}
countCombi = 0;
}
#end
Most of the strings and variables are set just under the #import "ViewController.h" so they are global :-
NSString *readAnswers;
NSString *cantCalc;
NSString *finalResult;
NSString *allAnswers[10];
NSString *CompileText;
NSString *readAnswers;
NSString *finalResult;
#define DIV 0
#define MUL 1
#define ADD 2
#define SUB 3
int n1,n2,n3,n4,n5,n6;
int answer_counter = 0;
int tar2 = 0;
int number[6];
int target = 0;
int used[6];
int countCombi;
Thanks.
Create a reset method that alloc inits every string in your view controller again. You can set the textview's text to "".
In theory you could write a helper class that you pass in an object (your view controller) and it uses introspection to reset everything that is a string or whatever you want. This is a good approach for modularity and reusability, however it requires knowledge of c, and introspection.
Yes whatever williams say thats correct. Implement like below:
-(IBAction)doClear:sender
{
[Yourtextview setString];
}

Resources