how to show UI objects code in xcode? - 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

Related

NSCollectionViewAttributes not getting applied correctly with custom NSFlowLayout subclass

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;
}

How make [UIView animateWithDuration: ..] work in application porting by apportable?

On portal application by apportable I need to make some animation (move/scale/change alpha) of UIView *object via call:
[UIView
animateWithDuration:1.f
delay:0.5f
options:UIViewAnimationOptionAllowUserInteraction
animations:^(void)
{
myview.center = moveTo;
myview.transform = transformTo;
myview.alpha = alphaTo;
}
completion:^(BOOL finished)
{
[self animationFinished];
}];
For now it's only make delay, then execute animation code & completion code immediately.
Thank you for answer.
But I need animation "today", so I make next class.
It's work not good enoght, but it's much better then nothing.
Maybe for one it will be helpful
AOTAnimate.h
//
// AOTAnimate.h
//
// Created by Andrei Bakulin on 18/11/2013.
//
#import <Foundation/Foundation.h>
#interface AOTAnimate : NSObject
{
UIView *view;
NSInteger animationTicksLeft;
CGFloat scaleX;
CGFloat scaleY;
CGPoint moveDelta;
CGSize scaleCurrent;
CGSize scaleDelta;
CGFloat alphaDelta;
void (^completeAction)();
}
#property (nonatomic, assign) CGFloat duration;
#property (nonatomic, assign) CGFloat delay;
#property (nonatomic, assign) CGFloat frequency;
#property (nonatomic, assign) UIViewAnimationOptions options;
#property (nonatomic, assign) CGPoint moveFrom;
#property (nonatomic, assign) CGAffineTransform transformFrom;
#property (nonatomic, assign) CGFloat alphaFrom;
#property (nonatomic, assign) CGPoint moveTo;
#property (nonatomic, assign) CGAffineTransform transformTo;
#property (nonatomic, assign) CGFloat alphaTo;
+ (AOTAnimate*)makeAnimationOnView:(UIView*)view_ duration:(CGFloat)duration_;
+ (AOTAnimate*)makeAnimationOnView:(UIView*)view_ duration:(CGFloat)duration_ delay:(CGFloat)delay_;
- (void)run;
- (void)runWithCompleteAction:(void (^)(void))complete_;
#end
AOTAnimate.m
//
// AOTAnimate.m
//
// Created by Andrei Bakulin on 18/11/2013.
//
#import "AOTAnimate.h"
#implementation AOTAnimate
#synthesize duration, delay, frequency, options;
#synthesize moveFrom, transformFrom, alphaFrom;
#synthesize moveTo, transformTo, alphaTo;
+ (AOTAnimate*)makeAnimationOnView:(UIView*)view_ duration:(CGFloat)duration_
{
return [self makeAnimationOnView:view_ duration:duration_ delay:0.f];
}
+ (AOTAnimate*)makeAnimationOnView:(UIView*)view_ duration:(CGFloat)duration_ delay:(CGFloat)delay_
{
return [[AOTAnimate alloc] initWithView:view_ duration:(CGFloat)duration_ delay:(CGFloat)delay_];
}
//----------------------------------
- (void)dealloc
{
[view release];
if( completeAction )
Block_release(completeAction);
[super dealloc];
}
- (id)initWithView:(UIView*)view_ duration:(CGFloat)duration_ delay:(CGFloat)delay_
{
self = [super init];
if (self)
{
view = [view_ retain];
duration = duration_;
delay = delay_;
frequency = 0.025f;
options = UIViewAnimationOptionAllowUserInteraction;
moveFrom = view.center;
transformFrom = view.transform;
alphaFrom = view.alpha;
moveTo = view.center;
transformTo = view.transform;
alphaTo = view.alpha;
}
return self;
}
//----------------------------------
#pragma mark - Run animation
- (void)run
{
[self runWithCompleteAction:nil];
}
- (void)runWithCompleteAction:(void (^)(void))complete_
{
view.center = moveFrom;
view.transform = transformFrom;
view.alpha = alphaFrom;
#ifndef ANDROID
[UIView
animateWithDuration:duration
delay:delay
options:options
animations:^(void)
{
view.center = moveTo;
view.transform = transformTo;
view.alpha = alphaTo;
}
completion:^(BOOL finished)
{
if( complete_ )
complete_();
}];
#else
if( duration <= 0.f )
{
[self doAnimationComplete];
return;
}
animationTicksLeft = ceil( duration / frequency );
if( animationTicksLeft == 0 )
{
[self doAnimationComplete];
return;
}
moveDelta = CGPointMake( (moveTo.x-moveFrom.x)/animationTicksLeft, (moveTo.y-moveFrom.y)/animationTicksLeft );
alphaDelta = (alphaTo-alphaFrom)/animationTicksLeft;
CGSize scaleFrom = CGSizeMake( [self scaleX:transformFrom], [self scaleY:transformFrom] );
CGSize scaleTo = CGSizeMake( [self scaleX:transformTo], [self scaleY:transformTo] );
scaleDelta = CGSizeMake((scaleTo.width - scaleFrom.width)/animationTicksLeft,
(scaleTo.height - scaleFrom.height)/animationTicksLeft );
scaleCurrent = scaleFrom;
if( complete_ )
{
completeAction = Block_copy(complete_);
}
[self performSelector:#selector(doAnimationTick) withObject:nil afterDelay:delay];
#endif
}
//----------------------------------
#pragma mark - Manual animation
#ifdef ANDROID
- (void)doAnimationTick
{
if( CGPointEqualToPoint( moveDelta, CGPointZero ) == NO )
{
view.center = CGPointMake( view.center.x + moveDelta.x, view.center.y + moveDelta.y );
}
if( CGSizeEqualToSize( scaleDelta, CGSizeZero) == NO )
{
view.transform = CGAffineTransformMakeScale( scaleCurrent.width, scaleCurrent.height );
scaleCurrent.width += scaleDelta.width;
scaleCurrent.height += scaleDelta.height;
}
if( alphaDelta != 0.f )
{
view.alpha = view.alpha + alphaDelta;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
animationTicksLeft--;
if( animationTicksLeft > 0 )
{
[self performSelector:#selector(doAnimationTick) withObject:nil afterDelay:frequency];
}
else
{
[self doAnimationComplete];
}
}
- (void)doAnimationComplete
{
view.center = moveTo;
view.transform = transformTo;
view.alpha = alphaTo;
if( completeAction )
completeAction();
}
//----------------------------------
#pragma mark - Helpers
- (CGFloat)scaleX:(CGAffineTransform)t
{
return sqrt(t.a * t.a + t.c * t.c);
}
- (CGFloat)scaleY:(CGAffineTransform)t
{
return sqrt(t.b * t.b + t.d * t.d);
}
#endif
#end
Use like this:
UIView *someview;
AOTAnimate *animate = [AOTAnimate makeAnimationOnView:someview duration:1.f delay:0.5f];
// allow to assign - animate.moveFrom / .tranfromFrom / alphaFrom properties,
// but by default they are copy from UIView* object
animate.moveTo = CGPointMake( 100, 200 ); // new point where need to move
animate.transformTo = CGAffineTransformScale( CGAffineTransformIdentity, 1.5f, 1.5f );
animate.alphaTo = 0.5f;
[animate runWithCompleteAction:^{
NSLog(#"Animation done..);
}];
If this method will run on iOS device - it'll use normal [UIView animateWithDuration:...] method
PS: This class do only "move" from one center point to another. Transform use only to scale object (not move). Alpha on my 2 test devices not supported, but maybe some where it does.
Animations do not work on the current version of Apportable's UIKit. We have fully functioning animations coming in the next version of UIKit, though. We will be releasing that once we are satisfied with the quality and coverage.

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.

subclassing TTTableMessageItemCell, anything wrong?

I subclassing TTTableMessageItemCell, got EXC_BAD_ACCESS runtime error. Anythign wrong?
CustomTTTableSubtitleItemCell.h
#import "Three20/Three20.h"
#interface CustomTTTableSubtitleItemCell : TTTableMessageItemCell {
TTButton *_rightButton;
}
#end
CustomTTTableSubtitleItemCell.m
#import "CustomTTTableSubtitleItemCell.h"
#import "CustomTTTableSubtitleItem.h"
#import "XYDefaultStyleSheet.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
static CGFloat kHPadding = 10;
static CGFloat kVPadding = 15;
#interface ButtonStyleSheet : TTDefaultStyleSheet
#end
#implementation ButtonStyleSheet
- (TTStyle*)blueToolbarButton:(UIControlState)state {
TTShape* shape = [TTRoundedRectangleShape shapeWithRadius:4.5];
UIColor* tintColor = RGBCOLOR(30, 110, 255);
return [TTSTYLESHEET toolbarButtonForState:state shape:shape tintColor:tintColor font:nil];
}
#end
#implementation CustomTTTableSubtitleItemCell
+ (CGFloat)tableView:(UITableView*)tableView rowHeightForItem:(id)item {
CustomTTTableSubtitleItem* captionedItem = item;
CGFloat maxWidth = tableView.width - kHPadding*2;
CGSize titleSize = [captionedItem.title sizeWithFont:TTSTYLEVAR(myTitleFont)
constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX)
lineBreakMode:UILineBreakModeWordWrap];
CGSize textSize = [captionedItem.text sizeWithFont:TTSTYLEVAR(myHeadingFont)
constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX)
lineBreakMode:UILineBreakModeWordWrap];
CGSize subtextSize = [captionedItem.caption sizeWithFont:TTSTYLEVAR(mySubtextFont)
constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
return kVPadding*2 + titleSize.height + textSize.height + subtextSize.height + kVPadding;
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier {
if (self = [super initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier]) {
_item = nil;
[TTStyleSheet setGlobalStyleSheet:[[[ButtonStyleSheet alloc] init] autorelease]];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
[self.detailTextLabel sizeToFit];
self.detailTextLabel.top = kVPadding;
self.textLabel.height = self.detailTextLabel.height;
//_rightButton.frame = CGRectMake(20, self.detailTextLabel.bottom + kVPadding, kImageWidth, kImageHeight);
//_rightButton.alpha = !self.showingDeleteConfirmation;
[_rightButton sizeToFit];
_rightButton.left = self.contentView.width - (_timestampLabel.width + kHPadding);
_rightButton.top = self.height/2;
}
- (id)object {
return _item;
}
- (void)setObject:(id)object {
if (_item != object) {
[super setObject:object];
CustomTTTableSubtitleItem* item = object;
//self.textLabel.textColor = TTSTYLEVAR(myHeadingColor);
// self.textLabel.font = TTSTYLEVAR(myHeadingFont);
// self.textLabel.textAlignment = UITextAlignmentRight;
// self.textLabel.contentMode = UIViewContentModeCenter;
// self.textLabel.lineBreakMode = UILineBreakModeWordWrap;
// self.textLabel.numberOfLines = 0;
//
// self.detailTextLabel.textColor = TTSTYLEVAR(mySubtextColor);
// self.detailTextLabel.font = TTSTYLEVAR(mySubtextFont);
// self.detailTextLabel.textAlignment = UITextAlignmentLeft;
// self.detailTextLabel.contentMode = UIViewContentModeTop;
// self.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
_rightButton = [TTButton
buttonWithStyle:#"blueToolbarButton:" title:item.rightButtonTitle];
}
}
- (void)dealloc {
TT_RELEASE_SAFELY(_rightButton);
[super dealloc];
}
#end
You're creating the TTButton using autorelease, while you're releasing it in your dealloc function. So both the release pool and the dealloc are trying to release your _rightButton TTButton.
in your header file, try adding:
#property (nonatomic, readonly, retain) TTButton* rightButton;
And then create the TTButton using his get function in your source file:
///////////////////////////////////////////////////////////////////////////////////////////////////
- (TTButton*)rightButton {
if (!_rightButton) {
_rightButton = [[TTButton
buttonWithStyle:#"blueToolbarButton:" title:item.rightButtonTitle] retain];
[self.contentView addSubview:rightButton];
}
return rightButton;
}
When using the rightButton, make sure to use self.rightBotton and not _rightButton, such as in the layout function (Because you need to object to be created).
self.rightButton.frame = CGRectMake(20, self.detailTextLabel.bottom + kVPadding, kImageWidth, kImageHeight);
I suggest opening the Three20UI/TTTableMessageItemCell.h & source file and trying to copy the behavior of one of the elements. That's what I did.

Resources