NSCollectionViewAttributes not getting applied correctly with custom NSFlowLayout subclass - cocoa

I'm currently working on an NSCollectionView with a custom layout. For that purpose, I subclassed NSCollectionViewFlowLayout to top-align my items (which all have a fixed width what made the algorithm pretty easy). The problem I have now is that only the first nine items in my collection view get displayed correctly, that is top-aligned.
These top nine items are at least partially visible when the collection view is initially displayed. The other items that appear when scrolling down the collection view will be drawn without any top-alignment, just vertically-centered-per-row as the default behaviour of NSCollectionViewFlowLayout. By extensive logging I could verify that my Layout only provides NSCollectionViewLayoutAttributes correctly modified for top-alignment.
When I resize the window containing the NSCollectionView, thus resizing the collection view itself, all items in the visible part of it will suddenly be displayed correctly.
What am I missing?
Here comes my custom subclass:
#import "MyCollectionViewLayout.h"
#interface MyCollectionViewLayout ()
#property (nonatomic, strong) NSMutableDictionary<NSIndexPath *, NSCollectionViewLayoutAttributes *> *attributesCache;
#property NSInteger numberOfItemsPerRow;
#property NSInteger numberOfItemsTotal;
#end
#implementation MyCollectionViewLayout
- (void)prepareLayout {
NSLog(#"Preparing layout");
[super prepareLayout];
self.itemSize = CGSizeMake(100, 138);
self.minimumInteritemSpacing = 5;
self.minimumLineSpacing = 5;
self.sectionInset = NSEdgeInsetsMake(10, 10, 10, 10);
self.attributesCache = #{}.mutableCopy;
self.numberOfItemsTotal = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:0];
NSInteger numberOfItemsPerRow = 1;
CGFloat computedSize = self.itemSize.width;
CGFloat usableWidth = self.collectionView.frame.size.width - (self.sectionInset.right + self.sectionInset.left);
repeat: {
computedSize += self.minimumInteritemSpacing + self.itemSize.width;
if (computedSize < usableWidth) {
numberOfItemsPerRow++;
goto repeat;
}
}
self.numberOfItemsPerRow = numberOfItemsPerRow;
}
#pragma mark NSCollectionViewFlowLayout override
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSLog(#"Getting layout attributes for rect: %f, %f, %f, %f", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
NSArray *attributesArray = [super layoutAttributesForElementsInRect:rect].mutableCopy;
for (int i = 0; i < attributesArray.count; i++) {
NSCollectionViewLayoutAttributes *attributes = attributesArray[i];
NSLog(#"Forwarding attribute request for %#", attributes.indexPath);
attributes = [self layoutAttributesForItemAtIndexPath:attributes.indexPath];
}
return attributesArray;
}
- (NSCollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
if (!self.attributesCache[indexPath]) NSLog(#"");
NSLog(#"Getting layout attributes for %#", indexPath);
if (!self.attributesCache[indexPath]) {
NSLog(# "Not cached yet, caching full row");
[self computeAndCacheAttributesForRowContaining:indexPath];
}
return self.attributesCache[indexPath];
}
#pragma mark Private instance methods
- (void)computeAndCacheAttributesForRowContaining:(NSIndexPath *)indexPath {
NSDictionary<NSIndexPath *, NSCollectionViewLayoutAttributes *> *allAttributesInRowByPath = [self getAllAttributesInRowContaining:indexPath];
CGFloat minY = CGFLOAT_MAX;
for (NSIndexPath *path in allAttributesInRowByPath) {
if (allAttributesInRowByPath[path].frame.origin.y < minY) {
minY = allAttributesInRowByPath[path].frame.origin.y;
}
}
for (NSIndexPath *path in allAttributesInRowByPath) {
if (indexPath.item == 9) {
}
NSLog(#"Changing frame for indexPath %#", path);
NSRect frame = allAttributesInRowByPath[path].frame;
NSLog(#"Previous y Position: %f", frame.origin.y);
NSLog(#"New y Position: %f", minY);
frame.origin.y = minY;
allAttributesInRowByPath[path].frame = frame;
}
[self.attributesCache addEntriesFromDictionary:allAttributesInRowByPath];
}
- (NSDictionary<NSIndexPath *, NSCollectionViewLayoutAttributes *> *)getAllAttributesInRowContaining:(NSIndexPath *)indexPath {
NSMutableDictionary<NSIndexPath *, NSCollectionViewLayoutAttributes *> *attributesToReturn = #{}.mutableCopy;
NSInteger index = indexPath.item;
NSInteger firstIndex = index - (index % self.numberOfItemsPerRow);
NSIndexPath *path;
for (index = firstIndex; (index < firstIndex + self.numberOfItemsPerRow) && (index < self.numberOfItemsTotal); index++) {
path = [NSIndexPath indexPathForItem:index inSection:indexPath.section];
[attributesToReturn setObject:[super layoutAttributesForItemAtIndexPath:path].copy forKey:path];
}
return attributesToReturn.copy;
}
#end

You're missing attributesArray[i] = attributes; in layoutAttributesForElementsInRect : and are returning the unmodified attributes.
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSLog(#"Getting layout attributes for rect: %f, %f, %f, %f", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
NSMutableArray *attributesArray = [super layoutAttributesForElementsInRect:rect].mutableCopy;
for (int i = 0; i < attributesArray.count; i++) {
NSCollectionViewLayoutAttributes *attributes = attributesArray[i];
NSLog(#"Forwarding attribute request for %#", attributes.indexPath);
attributes = [self layoutAttributesForItemAtIndexPath:attributes.indexPath];
attributesArray[i] = attributes; // <---
}
return attributesArray;
}

Related

UIButton Randomize Title With Single Characters

The code below takes a string, adds each letter to an array and shuffles that array and shows the end result in a label. That works well. But I'd like for each character to contain a single character of the shuffled string. Right now it almost works, but it always repeats the characters. Like instead of having a series of 6 buttons with their titles: L e a g u e, the code generates repeated characters like: Leaauu.
My code is this:
- (IBAction)shuffleButttonTitles:(id)sender {
// The mutable array must be created here to create a new instance each time the button is tapped
letters = [[NSMutableArray alloc] init];
str = #"League";
length = str.length;
NSString *letter;
UIButton *button;
// First loop through the string and add each letter to an array
for (int i = 0; i < length; i++) {
letter = [NSString stringWithFormat:#"%c", [str characterAtIndex:i]];
[letters addObject:letter];
}
// Shuffle the string for the label/buttons
for (int i = 0; i < length; i++) {
int value = arc4random() % (length - 1);
[letters exchangeObjectAtIndex:i withObjectAtIndex:value];
//Create the button and shuffle the letters for their titles
button = [[UIButton alloc] initWithFrame:CGRectMake(50 * i, 350, 44, 44)];
// HERE THE CODE REPEATS THE CHARACTERS
[button setTitle:[letters objectAtIndex:i] forState:UIControlStateNormal];
//Store the button in our array
[myButtons addObject:button];
NSLog(#"Letters in Array: %lu", letters.count);
}
for (UIButton *button in myButtons){
[button setBackgroundColor:[UIColor redColor]];
[self.view addSubview:button];
}
// Now we set the randomized title to the label
NSString *results = [letters componentsJoinedByString:#""];
string.text = results;
}
After some searching on the web I've figured it out. I post the complete code for others. This code takes a random string from the Characters.txt file and shuffles that string. Then it rotates the tiles slighty. You can enter the correct word when you have figured out the anagram, which then shows an alert view if you got it or didn't get it.
#define kTileSpacing 20
#define randomf(minX,maxX) ((float)(arc4random() % (maxX - minX + 1)) + (float)minX)
#interface ViewController ()
#end
#implementation ViewController
{
}
#synthesize progressView;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:#"Anagrams" ofType:#"plist"];
dictionary = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSString *quotesFile = [[NSBundle mainBundle] pathForResource:#"Characters" ofType:#"txt"];
fileContents = [NSString stringWithContentsOfFile:quotesFile encoding:NSUTF8StringEncoding error:NULL];
// [txtField becomeFirstResponder];
//[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(checkWord:) name:nil object:nil];
}
- (IBAction)clear:(id)sender {
quoteArray = [fileContents componentsSeparatedByString:#"\n"];
NSString *quoteToDisplay;
currentQuestion = arc4random() % quoteArray.count;
quoteToDisplay = [quoteArray objectAtIndex: currentQuestion];
welldone.text = quoteToDisplay;
txtField.text = nil;
[txtField becomeFirstResponder];
for (UILabel *lbl in myButtons) {
[lbl removeFromSuperview];
}
}
- (IBAction)ShuffleString:(id)sender {
[self clear:nil];
// The mutable array must be created here to create a new instance each time the button is tapped
charactersArray = [[NSMutableArray alloc] init];
indexArray = [[NSMutableArray alloc] init];
myButtons = [[NSMutableArray alloc] init];
// 1. Shuffle the plist with the words to form anagrams from
currentQuestion = arc4random() % quoteArray.count;
str = [quoteArray objectAtIndex: currentQuestion]; //[[dictionary objectAtIndex:currentQuestion] objectForKey:#"Anagram"];
length = str.length;
NSString *letter;
// 2. Loop throught the chosen word and break it down into its letters and add them to an array
for (int i = 0; i < str.length; i++) {
// [charactersArray removeObjectAtIndex:i];
letter = [NSString stringWithFormat:#"%c", [str characterAtIndex:i]];
[charactersArray addObject:letter];
// NSLog(#"Number of letters: %#", charactersArray);
}
while ([charactersArray count]) {
int randomizing = arc4random() % [charactersArray count];
[indexArray addObject:[charactersArray objectAtIndex:randomizing]];
[charactersArray removeObjectAtIndex:randomizing];
// NSLog(#"NO REPEAT SHUFFLE: %lu", (unsigned long)indexArray.count);
}
/***************/
CGFloat staticY = self.view.bounds.size.height / 9 * 1; // Static X for all buttons.
CGFloat staticWidth = 46; // Static Width for all Buttons.
CGFloat staticHeight = 46; // Static Height for all buttons.
CGFloat staticPadding = 10; // Padding to add between each button.
float tileSize = ceilf( self.view.bounds.size.width / str.length );
NSLog(#"size %f", tileSize);
CGFloat xOffset = (self.view.bounds.size.width - str.length * (44+staticPadding));
NSLog(#"xOffset %f", tileSize);
xOffset = tileSize/ 2;
for (int i = 0; i < str.length; i++) {
singleCharacterLabel = [[UILabel alloc] init];
singleCharacterLabel.textAlignment = NSTextAlignmentCenter;
singleCharacterLabel.font = [UIFont fontWithName:#"Verdana-Bold" size:21];
singleCharacterLabel.frame = CGRectMake((staticPadding + (i * (staticHeight + staticPadding))), staticY, staticWidth, staticHeight);
// NSLog(#"X: %f", (staticPadding + (i * (staticHeight + staticPadding))));
//singleCharacterLabel.center = CGPointMake(i * 50 + self.view.bounds.origin.x + self.view.bounds.size.width /3, 80); // i * int +self... int = space between labels. Here it is '50'
// singleCharacterLabel.center = CGPointMake(self.view.bounds.size.width * i, self.view.bounds.size.height / 5 * 1); // 1/4th down from the top
singleCharacterLabel.layer.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"Tile.png"]].CGColor;
NSString *anagramString = [indexArray objectAtIndex:i];
singleCharacterLabel.text = anagramString;
[myButtons addObject:singleCharacterLabel];
//1
//set random rotation of the tile
//anywhere between -0.2 and 0.3 radians
float rotation = randomf(0,50) / (float)100 - 0.2;
singleCharacterLabel.transform = CGAffineTransformMakeRotation( rotation );
//2
//move randomly upwards
int yOffset = (arc4random() % 10) - 10;
singleCharacterLabel.center = CGPointMake(singleCharacterLabel.center.x, singleCharacterLabel.center.y + yOffset);
[self.view addSubview:singleCharacterLabel];
//NSLog(#"LOOP: %#", anagramString);
}
}
- (IBAction)checkWord:(id)sender {
if (([txtField.text isEqual:str])) {
alertCorrect = [[UIAlertView alloc] initWithTitle:#"" message:#"Well done!" delegate:self cancelButtonTitle:nil otherButtonTitles:#"Next", nil];
[alertCorrect show];
} else {
alertWrong = [[UIAlertView alloc] initWithTitle:#"" message:#"Sorry, try again." delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alertWrong show];
}
// NSLog(#"String is: %lu", str.length);
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (alertView == alertCorrect) {
if (buttonIndex == 0) {
[self ShuffleString:nil];
NSLog(#"next");
}
}
if (alertView == alertWrong) {
if (buttonIndex == 1) {
// Wrong answer. Close view and let user try again
}
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (txtField.text.length == length) {
[self checkWord:nil];
NSLog(#"You entered %lu characters", length);
}
return YES;
}

how to show UI objects code in xcode?

in one part of my project I need to create some UI objects programmatically, can I just customize my UI Objects like labels,... visually in storyboard then simply copy/paste generated code relevant to that object?
I searched in xcode menu but I couldn't find this but once I saw it in a tutorial in youtube.
Thanks in Advance
Yes you can customize the UI Classes or any other class, Like I have customize UILabel Class as UILabelExtended
UILabelExtended.h
#import <Foundation/Foundation.h>
/* **********************************************************************************************
This class inherit the class UILabel and extend the features of UILabel.
********************************************************************************************** */
#interface UILabelExtended : UILabel {
__unsafe_unretained id customDelegate;
id objectInfo;
SEL selector;
}
#property (nonatomic,assign) SEL selector;;
#property (nonatomic,assign) id customDelegate;
#property (nonatomic,retain) id objectInfo;
#end
#interface UILabel(UILabelCategory)
- (void)setHeightOfLabel;
- (void)setWidthOfLabel;
- (void)setHeightOfLabelWithMaxHeight:(float)maxHeight;
- (void)setWidthOfLabelWithMaxWidth:(float)maxWidth ;
#end
UILabelExtended.m
#import "UILabelExtended.h"
#implementation UILabelExtended
#synthesize selector,customDelegate, objectInfo;
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if(self.selector)
if([self.customDelegate respondsToSelector:self.selector]) {
[self.customDelegate performSelector:self.selector withObject:self];
return;
}
}
- (void)dealloc {
self.customDelegate = nil;
self.selector = NULL;
self.objectInfo = nil;
}
#end
#implementation UILabel(UILabelCategory)
- (void)setHeightOfLabel {
UILabel* label = self;
//get the height of label content
CGFloat height = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(label.bounds.size.width, 99999) lineBreakMode:NSLineBreakByWordWrapping].height;
//set the frame according to calculated height
CGRect frame = label.frame;
if([label.text length] > 0) {
frame.size.height = height;
}
else {
frame.size.height = 0;
}
label.frame = frame;
}
- (void)setWidthOfLabel {
UILabel* label = self;
//get the height of label content
CGFloat width = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(99999, label.bounds.size.height) lineBreakMode:NSLineBreakByWordWrapping].width;
//set the frame according to calculated height
CGRect frame = label.frame;
if([label.text length] > 0) {
frame.size.width = width+5;
}
else {
frame.size.width = 0;
}
label.frame = frame;
}
- (void)setHeightOfLabelWithMaxHeight:(float)maxHeight {
UILabel* label = self;
//get the height of label content
CGFloat height = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(label.bounds.size.width, maxHeight) lineBreakMode:NSLineBreakByWordWrapping].height;
//set the frame according to calculated height
CGRect frame = label.frame;
if([label.text length] > 0) {
if (height > maxHeight) {
frame.size.height = maxHeight;
}
else {
frame.size.height = height;
}
}
else {
frame.size.height = 0;
}
label.frame = frame;
}
- (void)setWidthOfLabelWithMaxWidth:(float)maxWidth {
UILabel* label = self;
//get the height of label content
CGFloat width = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(99999, label.bounds.size.height) lineBreakMode:NSLineBreakByWordWrapping].width;
//set the frame according to calculated height
CGRect frame = label.frame;
if([label.text length] > 0) {
if (width > maxWidth) {
frame.size.width = maxWidth;
}
else {
frame.size.width = width;
}
}
else {
frame.size.width = 0;
}
label.frame = frame;
}
#end

UITextView in UIScrollView in UIView : IBOutlet Hierarchy?

I have an UITextView inside an UIScrollView inside an UITextView.
And I want to add a "zoom skill" to UITextView.
I added <...UIScrollViewDelegate> in .h file.
I added this into .m file.
#synthesize myTextView;
#synthesize scrollView;
- (void)scrollViewDidZoom:(UIScrollView *)sv
{
float zoomScale = sv.zoomScale;
if (zoomScale < 3)
{
if(zoomScale < 0.5)
{
UIFont* myFont = [UIFont systemFontOfSize:12];
myTextView.font = myFont;
}else{
UIFont* myFont = [UIFont systemFontOfSize:(zoomScale * 12)];
myTextView.font = myFont;
}
UIFont* myFont = [UIFont systemFontOfSize:36];
myTextView.font = myFont;
}
}
"scrollViewDidZoom" is never called.
I successfully add those objects with interface builder. To be honest I am a bit lost.
I don't know how I should create outlets and delegates (with 3 level hierarchy).
I realised there is a simple way to do it with UIPinchGestureRecognizer.
- (void)viewDidLoad
{
//...
UIPinchGestureRecognizer *pinchGest = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(changeTextViewFontSize:)];
pinchGest.delegate = self;
[myTextView addGestureRecognizer:pinchGest];
[pinchGest release];
}
- (void)changeTextViewFontSize:(UIPinchGestureRecognizer *)p
{
CGFloat zoomVelocity = [(UIPinchGestureRecognizer *)p velocity];
UIFont *font = self.myTextView.font;
CGFloat pointSize = font.pointSize;
NSString *fontName = font.fontName;
pointSize = ((zoomVelocity > 0) ? 1 : -1) * 1 + pointSize;
if (pointSize < 8) pointSize = 8;
if (pointSize > 32) pointSize = 32;
self.myTextView.font = [UIFont fontWithName:fontName size:pointSize];
}
Thank you Aral Balkan : http://aralbalkan.com/3831/

GL_STACK_OVERFLOW (0x503) error Cocos2d

So I have it set up so when the characters health is < 100 (for testing purposes) it stop the scene and goes to the game over scene.
if (playerDataManager.playerHealth < 100) {
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:3 scene: [GameLogic scene]]];
}
However when the players health drops below 100, it goes to the new scene, but the FPS drops dramatically from 60 to 5.
I get a list of OpenGL error 0x0503 in -[EAGLView swapBuffers] then it stays frozen like that for about 40 seconds, then the FPS unfreeze and goes back out to 60 and I get a list of 2012-07-13 10:37:50.234 Tilegame[93513:10a03] cocos2d: removeChildByTag: child not found!
Then I can continue with the app like normal, going back to the main menu, starting a new game, then recreate the error.
#import "HelloWorldLayer.h"
#import "Menu.h"
#import "SimpleAudioEngine.h"
#import "LogCabinMap.h"
#import "LogShedMap.h"
#import "SaveData.h"
#import "pauseM.h"
#import "Player.h"
#import "GameLogic.h"
CCSprite *player;
CGPoint newPos;
int joyDegrees;
// HelloWorldLayer implementation
#implementation HelloWorldLayer
#synthesize tileMap = _tileMap;
#synthesize background = _background;
#synthesize buildings = _buildings;
#synthesize meta = _meta;
#synthesize player = _player;
#synthesize foreground = _foreground;
#synthesize numCollected = _numCollected;
#synthesize hud = _hud;
-(void) animateEnemy:(CCSprite*)enemy {
//speed of the enemy
ccTime actualDuration = .2;
id actionMove;
int distanceFromPlayer = ccpDistance(player.position, enemy.position);
if (distanceFromPlayer < 200) { //Check whether enemy can "see" Ninja before moving towards him.
//rotate to face the player
CGPoint diff = ccpSub(player.position,enemy.position);
float angleRadians = atanf((float)diff.y / (float)diff.x);
float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
float cocosAngle = -1 * angleDegrees;
if (diff.x < 0) {
cocosAngle += 180;
}
enemy.rotation = cocosAngle;
actionMove = [CCMoveBy actionWithDuration:actualDuration
position:ccpMult(ccpNormalize(ccpSub(player.position,enemy.position)),10)];
} else {
actionMove = [CCMoveBy actionWithDuration:actualDuration
position:ccpMult(ccpNormalize(ccpSub(player.position,enemy.position)),0)];
}
id actionMoveDone = [CCCallFuncN actionWithTarget:self
selector:#selector(enemyMoveFinished:)];
[enemy runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
}
// callback. starts another iteration of enemy movement.
- (void) enemyMoveFinished:(id)sender {
CCSprite *enemy = (CCSprite *)sender;
[self animateEnemy: enemy];
}
-(void)addEnemyAtX:(int)x y:(int)y {
CCSprite *enemy = [CCSprite spriteWithFile:#"enemy1.png"];
enemy.position = ccp(x, y);
[self addChild:enemy];
[self animateEnemy:enemy];
}
-(void)setViewpointCenter:(CGPoint) position {
CGSize winSize = [[CCDirector sharedDirector] winSize];
int x = MAX(position.x, winSize.width / 2);
int y = MAX(position.y, winSize.height / 2);
x = MIN(x, (_tileMap.mapSize.width * _tileMap.tileSize.width)
- winSize.width / 2);
y = MIN(y, (_tileMap.mapSize.height * _tileMap.tileSize.height)
- winSize.height/2);
CGPoint actualPosition = ccp(x, y);
CGPoint centerOfView = ccp(winSize.width/2, winSize.height/2);
CGPoint viewPoint = ccpSub(centerOfView, actualPosition);
self.position = viewPoint;
}
-(id) init
{
if( (self=[super init] )) {
[[SimpleAudioEngine sharedEngine] preloadEffect:#"pickup.caf"];
[[SimpleAudioEngine sharedEngine] preloadEffect:#"hit.caf"];
[[SimpleAudioEngine sharedEngine] preloadEffect:#"move.caf"];
//[[SimpleAudioEngine sharedEngine] playBackgroundMusic:#"TileMap.caf"];
self.isTouchEnabled = YES;
self.tileMap = [CCTMXTiledMap tiledMapWithTMXFile:#"TileMap.tmx"];
self.background = [_tileMap layerNamed:#"Background"];
self.foreground = [_tileMap layerNamed:#"Foreground"];
self.buildings = [_tileMap layerNamed:#"Buildings"];
self.meta = [_tileMap layerNamed:#"Meta"];
_meta.visible = NO;
CCTMXObjectGroup *objects = [_tileMap objectGroupNamed:#"Objects"];
NSAssert(objects != nil, #"'Objects' object group not found");
//NSMutableDictionary * padPoints = [objects objectNamed:#"pad"];
NSMutableDictionary * padPoints;
SaveData * SaveDataManager = [SaveData sharedSaveDataManager];
for (int i = 0; i < 20; i ++) {
for (padPoints in [objects objects]) {
if ([[SaveDataManager.padArray objectAtIndex: i] intValue] == 1 ){
if ([[padPoints valueForKey:#"pad"] intValue] == i){
int x = [[padPoints valueForKey:#"x"] intValue];
int y = [[padPoints valueForKey:#"y"] intValue];
self.player = [CCSprite spriteWithFile:#"man.png"];
_player.position = ccp(x+16,y+16);
//[self addChild:_player];
}
}
}
}
// iterate through objects, finding all enemy spawn points
// create an enemy for each one
NSMutableDictionary * spawnPoints;
for (spawnPoints in [objects objects]) {
if ([[spawnPoints valueForKey:#"Enemy"] intValue] == 2){
int x = [[spawnPoints valueForKey:#"x"] intValue];
int y = [[spawnPoints valueForKey:#"y"] intValue];
[self addEnemyAtX:x+=16 y:y+=64];
}
}
player = [CCSprite spriteWithFile:#"man.png"];
player.position= _player.position;
[_tileMap addChild:player z: 0];
// [self addChild:player z:10];
[self setViewpointCenter:player.position];
[self addChild:_tileMap z:-1];
[self scheduleUpdate];
}
return self;
}
- (CGPoint)tileCoordForPosition:(CGPoint)position {
int x = position.x / _tileMap.tileSize.width;
int y = ((_tileMap.mapSize.height * _tileMap.tileSize.height) - position.y) / _tileMap.tileSize.height;
return ccp(x, y);
}
-(void)setPlayerPosition:(CGPoint)position {
Player * playerDataManager = [Player playerSaveDataManager];
CGPoint tileCoord = [self tileCoordForPosition:position];
int tileGid = [_meta tileGIDAt:tileCoord];
int x = player.position.x;
int y = player.position.y;
if (tileGid) {
NSDictionary *properties = [_tileMap propertiesForGID:tileGid];
if (properties) {
NSString *collision = [properties valueForKey:#"Collidable"];
if (collision && [collision compare:#"True"] == NSOrderedSame) {
//[[SimpleAudioEngine sharedEngine] playEffect:#"hit.caf"];
if (joyDegrees > 45 && joyDegrees < 135){
player.position = ccp(x,y-1);
}
if (joyDegrees > 135 && joyDegrees < 225){
player.position = ccp(x+1,y);
}
if (joyDegrees > 225 && joyDegrees < 315){
player.position = ccp(x,y+1);
}
if ((joyDegrees > 315 && joyDegrees < 360) || (joyDegrees > -1 && joyDegrees < 45)){
player.position = ccp(x-1,y);
}
return;
}
NSString *collectable = [properties valueForKey:#"Collectable"];
if (collectable && [collectable compare:#"True"] == NSOrderedSame) {
[[SimpleAudioEngine sharedEngine] playEffect:#"pickup.caf"];
[_meta removeTileAt:tileCoord];
[_foreground removeTileAt:tileCoord];
self.numCollected += 1;
[_hud numCollectedChanged:_numCollected];
playerDataManager.playerHealth -= 10;
}
NSString *Gate = [properties valueForKey:#"Gate"];
if (Gate && [Gate compare:#"1"] == NSOrderedSame) {
SaveData * SaveDataManager = [SaveData sharedSaveDataManager];
//[SaveDataManager.padArray removeAllObjects];
for (int i = 0; i < 20; i ++) {
[SaveDataManager.padArray replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:0]];
}
[SaveDataManager.padArray replaceObjectAtIndex:1 withObject:[NSNumber numberWithInt:1]];
//[[CCDirector sharedDirector] replaceScene:[LogCabinMap scene]];
[[CCDirector sharedDirector] pushScene:[LogCabinMap scene]];
}
if (Gate && [Gate compare:#"2"] == NSOrderedSame) {
SaveData * SaveDataManager = [SaveData sharedSaveDataManager];
//[SaveDataManager.padArray removeAllObjects];
for (int i = 0; i < 20; i ++) {
[SaveDataManager.padArray replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:0]];
}
[SaveDataManager.padArray replaceObjectAtIndex:1 withObject:[NSNumber numberWithInt:1]];
//[[CCDirector sharedDirector] replaceScene:[LogShedMap scene]];
[[CCDirector sharedDirector] pushScene:[LogShedMap scene]];
}
}
}
//[[SimpleAudioEngine sharedEngine] playEffect:#"move.caf"];
player.position = position;
}
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
return YES;
}
-(void) update:(ccTime)deltaTime {
[self setPlayerPosition:newPos];
[self setViewpointCenter:player.position];
}
// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
// in case you have something to dealloc, do it in this method
// in this particular example nothing needs to be released.
// cocos2d will automatically release all the children (Label)
self.tileMap = nil;
self.background = nil;
self.foreground = nil;
self.buildings = nil;
self.meta =nil;
self.player = nil;
player = nil;
self.hud = nil;
// don't forget to call "super dealloc"
[super dealloc];
}
#end
#implementation HelloWorldHud
#synthesize background;
#synthesize background2;
#synthesize health;
#synthesize baseScaleFactor;
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorldHud *layer = [HelloWorldHud node];
// add layer as a child to scene
[scene addChild: layer z:2];
HelloWorldLayer *hud = [HelloWorldLayer node];
[scene addChild: hud z:1];
//layer.hud = hud;
// return the scene
return scene;
}
-(void)initJoystick {
SneakyJoystickSkinnedBase *joystickBase = [[[SneakyJoystickSkinnedBase alloc] init] autorelease];
joystickBase.backgroundSprite = [CCSprite spriteWithFile:#"JoyB.png"];
joystickBase.thumbSprite = [CCSprite spriteWithFile:#"JoyS.png"];
joystickBase.joystick = [[SneakyJoystick alloc] initWithRect: CGRectMake(0, 0, 128, 128)];
joystickBase.position = ccp(55, 55);
[self addChild:joystickBase];
leftJoystick = [[joystickBase.joystick retain] autorelease];
}
-(void) update:(ccTime)deltaTime {
Player *playerDataManager = [Player playerSaveDataManager];
CGPoint scaledVelocity = ccpMult(leftJoystick.velocity, 100);
CGPoint newPosition = ccp(player.position.x + scaledVelocity.x * deltaTime, player.position.y + scaledVelocity.y * deltaTime);
if (leftJoystick.velocity.x == 0 && leftJoystick.velocity.y == 0 ){
if (!playerDataManager.standStill) {
[player stopAllActions];
playerDataManager.walkUp = FALSE;
playerDataManager.walkDown = FALSE;
playerDataManager.walkRight = FALSE;
playerDataManager.walkLeft = FALSE;
playerDataManager.standStill = TRUE;
[player runAction:playerDataManager.standAction];
}
}
if (leftJoystick.degrees > 45 && leftJoystick.degrees < 135){
if (!playerDataManager.walkUp) {
[player stopAllActions];
playerDataManager.walkUp = TRUE;
playerDataManager.walkDown = FALSE;
playerDataManager.walkRight = FALSE;
playerDataManager.walkLeft = FALSE;
playerDataManager.standStill = FALSE;
[player runAction:playerDataManager.walkUpAction];
}
}
if (leftJoystick.degrees > 135 && leftJoystick.degrees < 225){
if (!playerDataManager.walkLeft) {
[player stopAllActions];
playerDataManager.walkUp = FALSE;
playerDataManager.walkDown = FALSE;
playerDataManager.walkRight = FALSE;
playerDataManager.walkLeft = TRUE;
playerDataManager.standStill = FALSE;
[player runAction:playerDataManager.walkLeftAction];
}
}
if (leftJoystick.degrees > 225 && leftJoystick.degrees < 315){
if (!playerDataManager.walkDown) {
[player stopAllActions];
playerDataManager.walkUp = FALSE;
playerDataManager.walkDown = TRUE;
playerDataManager.walkRight = FALSE;
playerDataManager.walkLeft = FALSE;
playerDataManager.standStill = FALSE;
[player runAction:playerDataManager.walkDownAction];
}
}
if (((leftJoystick.degrees > 315 && leftJoystick.degrees < 360) && (leftJoystick.velocity.x != 0 && leftJoystick.velocity.y != 0 )) || ((leftJoystick.degrees > -1 && leftJoystick.degrees < 45) && (leftJoystick.velocity.x != 0 && leftJoystick.velocity.y != 0 ))){
if (!playerDataManager.walkRight) {
[player stopAllActions];
playerDataManager.walkUp = FALSE;
playerDataManager.walkDown = FALSE;
playerDataManager.walkRight = TRUE;
playerDataManager.walkLeft = FALSE;
playerDataManager.standStill = FALSE;
[player runAction:playerDataManager.walkRightAction];
}
}
float scaleFactor = playerDataManager.playerHealth/baseScaleFactor;
health.scaleX = playerDataManager.playerHealth/1;
newPos = newPosition;
joyDegrees = leftJoystick.degrees;
if (playerDataManager.playerHealth < 100) {
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:3 scene: [GameLogic scene]]];
[[CCDirector sharedDirector] replaceScene: [GameLogic scene]];
}
}
-(void) scroll:(ccTime)dt
{
//move 30*dt px vertically
if (background.position.y<background2.position.y){
background.position = ccp(background.contentSize.width/2, background.position.y - 225*dt);
background2.position = ccp(background2.contentSize.width/2, background.position.y+background.contentSize.height);
}else{
background2.position = ccp(background2.contentSize.width/2, background2.position.y- 225*dt);
background.position = ccp(background.contentSize.width/2, background2.position.y+background2.contentSize.height);
}
//reset offscreen position
if (background.position.y <-background.contentSize.height/2)
{
background.position = ccp(background.contentSize.height/2,background2.position.y+background2.contentSize.height);
}else if (background2.position.y < -background2.contentSize.height/2)
{
background2.position = ccp(background2.contentSize.height/2, background.position.y+background.contentSize.height);
}
}
-(id) init
{
if ((self = [super init])) {
CGSize size = [CCDirector sharedDirector].winSize;
background = [CCSprite spriteWithFile:#"rain.png"];
background2 = [CCSprite spriteWithFile:#"rain.png"];
[background.texture setAliasTexParameters];
[background2.texture setAliasTexParameters];
//position background sprites
background.position = ccp(background.contentSize.height/2,background.contentSize.width/2);
background2.position = ccp(size.width,0);
//schedule to move background sprites
//[self schedule:#selector(scroll:)];
//adding them to the main layer
//[self addChild:background z:-1];
//[self addChild:background2 z:-1];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"GUI.plist"];
CCSpriteBatchNode *GUISpriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"GUI.png"];
[self addChild:GUISpriteSheet];
CCSprite * healthBar = [CCSprite spriteWithSpriteFrameName:#"bar.png"];
CCSprite * cap = [CCSprite spriteWithSpriteFrameName:#"cap.png"];
CCSprite * endCap = [CCSprite spriteWithSpriteFrameName:#"endcap.png"];
health = [CCSprite spriteWithSpriteFrameName:#"red.png"];
healthBar.anchorPoint = ccp(0,1);
health.anchorPoint = ccp(0,1);
cap.anchorPoint = ccp(0,1);
endCap.anchorPoint = ccp(0,1);
healthBar.position = ccp(1 , size.height);
healthBar.scaleX = 25;
cap.position = ccp(0 , size.height);
int width = [healthBar boundingBox].size.width;
endCap.position = ccp(width , size.height);
health.position = ccp(1, size.height-2);
baseScaleFactor = width;
health.scaleX = baseScaleFactor;
[self addChild:healthBar];
[self addChild:cap];
[self addChild:endCap];
[self addChild:health];
CGSize winSize = [[CCDirector sharedDirector] winSize];
label = [CCLabelTTF labelWithString:#"0" dimensions:CGSizeMake(50, 20)
alignment:UITextAlignmentRight fontName:#"Verdana-Bold"
fontSize:18.0];
label.color = ccc3(0,0,0);
int margin = 10;
label.position = ccp(winSize.width - (label.contentSize.width/2)
- margin, label.contentSize.height/2 + margin);
[self addChild:label];
CCMenuItemFont * pause = [CCMenuItemFont itemFromString:#"Pause" target:self selector:#selector(pause:)];
CCMenu *menu = [CCMenu menuWithItems: pause, nil];
pause.position = ccp(206,142);
[self addChild:menu];
CCSprite *pix = [CCSprite spriteWithFile:#"pix.png"];
pix.position = ccp(size.width/2, size.height/2);
//pix.scale = 50000;
[self addChild:pix z:1];
//[pix runAction:[CCTintTo actionWithDuration:10 red:255 green:0 blue:0]];
//[pix runAction:[CCScaleTo actionWithDuration:15 scale:500]];
pix.color = ccc3(255, 255, 255);
[self scheduleUpdate];
[self initJoystick];
}
return self;
}
- (void)numCollectedChanged:(int)numCollected {
[label setString:[NSString stringWithFormat:#"%d", numCollected]];
// [label setString:[NSString stringWithFormat:#"%d", score]];
}
- (void) pause: (id) sender
{
[[CCDirector sharedDirector] pushScene:[pauseM scene]];
}
- (void) dealloc
{
self.background = nil;
self.background2 = nil;
self.health = nil;
self.meta =nil;
player = nil;
// don't forget to call "super dealloc"
[super dealloc];
}
#end
Above is the .m scene that is running when the problem occurs and below is the GameLogic.m
#import "GameLogic.h"
#import "Player.h"
#import "Menu.h"
#implementation GameLogic
+(id) scene
{
CCScene *scene = [CCScene node];
GameLogic *layer = [GameLogic node];
[scene addChild: layer];
return scene;
}
+(id) gameLogicSaveDataManager {
static id gameLogicSaveDataManager = nil;
if (gameLogicSaveDataManager == nil) {
gameLogicSaveDataManager = [[self alloc] init];
}
return gameLogicSaveDataManager;
}
-(id) init
{
if( (self=[super init] )) {
CCSprite *bg = [CCSprite spriteWithFile:#"bg.jpg"];
bg.anchorPoint = ccp(0,0);
id fadeIn = [CCFadeIn actionWithDuration:3];
[self addChild:bg];
[bg runAction: fadeIn];
CCLayer *menuLayer = [[[CCLayer alloc] init] autorelease];
[self addChild:menuLayer];
CCMenuItemImage *home = [CCMenuItemImage
itemFromNormalImage:#"bg.jpg"
selectedImage:#"bg.jpg"
target:self
selector:#selector(home:)];
CCMenu *menu = [CCMenu menuWithItems: home, nil];
home.position = ccp(0,0);
[menuLayer addChild: menu];
}
return self;
}
- (void) home: (id) sender
{
[[CCDirector sharedDirector] replaceScene:[Menu scene]];
}
- (void) dealloc
{
[super dealloc];
}
#end
OpenGL error 0x503 means GL_STACK_OVERFLOW, it means you are pushing too many things onto the opengl stack.
I see several instances of pushScene in your code, but no instances of pop anything anywhere. You cannot just keep pushing things indefinitely without popping them, or you will get this error.
We need to what is currently running in your scene, how it has been allocated and how it is released. We also need to know the same information for the new loaded scene GameLogic. Edit your question and add these data.

Why is my UIpageControl is not displayed?

I downloaded a dome about UIScorllView and UIPageControl. Why UIPageControl is not display?
Here is the code ,I am new in Iphone .Any help will be appreciated!
ScrollView.M I put the ResultViewController into ScrollView. I want scroll the resultViewController with PageController.
- (void)loadScrollViewWithPage:(int)page
{
if (page < 0)
return;
if (page >= pageNumber)
return;
ResultViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{
controller = [[ResultViewController alloc] initWithPageNumber:page locations:existLocations];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
if (controller.view.superview == nil)
{
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
existLocations = [FileManagerUtil readPlistFileForDictionary:#"Locations" fileName:#"CloudCheckLocations.plist"];
pageNumber = [existLocations count];
NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < pageNumber; i++)
{
[controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
[controllers release];
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[self.navigationItem setTitle:#"NetWork condition"];
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * pageNumber, scrollView.frame.size.height);
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.scrollsToTop = NO;
scrollView.delegate = self;
pageContronl.numberOfPages = pageNumber;
pageContronl.currentPage = 0;
[pageContronl addTarget:self action:#selector(changePage:) forControlEvents:UIControlEventValueChanged];
[pageContronl setBackgroundColor:[UIColor blackColor]];
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];
[scrollView addSubview:pageContronl];
[self.view addSubview:scrollView];
}
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
if (pageControlUsed)
{
return;
}
CGFloat pageWidth = scrollView.frame.size.width;
int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageContronl.currentPage = page;
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
pageControlUsed = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
pageControlUsed = NO;
}
- (IBAction)changePage:(id)sender
{
int page = pageContronl.currentPage;
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
pageControlUsed = YES;
}
ScrollView.h
#interface ScrollViewController : UIViewController<UIScrollViewDelegate>
{
NSMutableArray *viewControllers;
NSString *currectNetWork;
NSString *flag;
NSString *locationName;
IBOutlet UIScrollView *scrollView;
IBOutlet UIPageControl *pageContronl;
BOOL pageControlUsed;
int pageNumber;
NSMutableDictionary *existLocations;
}
#property (nonatomic,retain) NSString *currectNetWork;
#property (nonatomic,retain) NSString *flag;
#property (nonatomic,retain) NSString *locationName;
#property (nonatomic,retain) UIPageControl * pageContronl;
#property (nonatomic,retain) UIScrollView * scrollView;
#property (nonatomic,retain) NSMutableArray *viewControllers;
#property (nonatomic,retain) NSMutableDictionary *existLocations;
(IBAction)changePage:(id)sender;
ResultViewControl.M
This method will call by ScrollView.M
- (id)initWithPageNumber:(int)page locations :(NSMutableDictionary *) locations
{
titilArray = [[NSArray alloc] initWithObjects:#"Today", #"Past 7 Day",#"Past 30 Day",nil];
if (self = [super initWithNibName:#"ResultViewController" bundle:nil])
{
pageNumber = page;
existLocations = locations;
}
return self;
}
Check the background colour of pageControl and parent view. If both have same colour (default white) page control will not display.
In IOS6, you have new methods pageIndicatorTintColor and currentPageIndicatorTintColor.
Hope this will help.
Check your top and bottom constraints of container view/ tableView(if present). Both must not be attached with Top/Bottom Layout Guide. Attach them with container Margins.

Resources