How to customise scene size in SpriteKite using initWithSize - objective-c

I need to lay a new scene on top of the old one, so that an upper band of the old one remains visible at the top. How should I modify initWithSize below?
- (id)initWithSize:(CGSize)size
{
self = [super initWithSize:size];
if (self)
{
//code
}
}
I tried using:
self = [super initWithSize:CGSizeMake(size.width, size.height +30)];
instead of
self = [super initWithSize:size];
but it doesn't work. It simply compresses vertically the scene a bit, but I still cannot see the underlying old scene. Cheers.

Related

Only show the rows in UITableView

I have a UITableView and for the life of me I can't hide the header and all the footer. I have tried multiple methods posted on here.
I want to hide the white space on top and bottom of the populated rows.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//Disable Scrolling in TableView
self.tableView.scrollEnabled = NO;
//Get rid of unpopulated rows
self.tableView.tableFooterView = [[UIView alloc] init];
//Hide UITableViewHeader
self.tableView.tableHeaderView = [[UIView alloc] init];
//Populate Table with Test Data
[self testTableView];
}
It looks like your UITableView's layout frame is not getting properly adjusted. Since I am not sure if you are using autolayout constraints or autozingmask therefore please try adding following code to your view controller to force your table to size according to the screen.
- (void)viewDidLayoutSubviews {
self.tableView.frame = self.view.frame;
}
Just set the tableviewHeader to nil or if you want to hide section headers just return nil from viewForHeaderInSection and reload the tableData.

How to make iPhone app smaller on iPad?

I have converted ILColorPicker to work on XCode4 and Storyboard. My problem is that it fills the entire UIView on the iPad... where do I start looking for a way to make it smaller?
I was thinking of using a subview, but not sure how to "wire" it into the subview. Any other ideas?
UPDATE: here is the code where I believe I can modify the frame, except I don't know how...
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self setup];
}
return self;
}
Adjusting the frame size is programmed with CGRectMake like this:
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:CGRectMake(x, y, width, height)])) {
// Initialization code
}
return self;
}
In the above the variable x and y corrispond to the top-left corner. And width and height are the width and height of the frame.

Rotating, scaling Cocos2d inherited layer with 2 sprites as children

Straight to the point, I have a class which is basically inherited from CCLayer and has 2 sprites as children.
some_layer.h
#interface some_layer : CCLayer {
CCSprite *back;
CCSprite *front;
}
some_layer.mm
// on "init" you need to initialize your instance
-(id) init
{
if( (self=[super init])) {
back = [CCSprite spriteWithFile:#"back.png"];
front = [CCSprite spriteWithFile:#"front.png"];
[front setOpacity:0];
[self addChild:back];
[self addChild:front];
//this is after modification
back.positionInPixels = CGPointMake(winSizeInPixels.width/2,winSizeInPixels.height/2);
front.positionInPixels = CGPointMake(winSizeInPixels.width/2,winSizeInPixels.height/2);
}
return self;
}
//after the edit
-(void) setPositionInPixels:(CGPoint)positionInPixels {
[super setPositionInPixels:CGPointMake(positionInPixels.x -(winSizeInPixels.width/2), positionInPixels.y -(winSizeInPixels.height/2))];
}
-(void) setPosition:(CGPoint)position {
[super setPosition:CGPointMake(position.x -(winSize.width/2), position.y -(winSize.height/2))];
}
Of course that is not all the implementation of the layer, but that code is the only one related to the problem, let me know if you think you need more.
Now in some part of the parent layer am trying to do this
float x = winSizeInPixels.width/2;
float y = winSizeInPixels.height/2;
[self setPositionInPixels:CGPointMake(x, y)];
mylayer = [[some_layer alloc] init];
[mylayer setPositionInPixels:CGPointMake(-offset, -offset)];
[self addChild:mylayer];
[mylayer runAction:[CCEaseInOut actionWithAction:[CCRotateTo actionWithDuration:speed*20 angle:angle] rate:4]];
The output of this code, is that I can see the sprites rotating, but not around the center of some_layer, I want them to rotate and stay in their place (rotate around themselves), what am trying to do is rotate, scale them at the same time while keeping their positions the same on screen,
The sprites are keeping in rotating around some random point ( Maybe around parent of their parent which is self in the last code )
BTW, I'm not touching the sprites back and front positions, I only deal with that "some_layer", I tried setting their positions to (0,0)
The only time the position of "some_layer" is correct is when it's rotation angle is 0, and it's scale is 1.0, if there's something unclear please let me know, thanks a lot, I can provide some screen shots
Edit : I modified the code above, it works properly as a workaround, but I think this is not the right way of doing it!!! Please check the comments, I don't know what's strange happening!!
Thank you!
Edit 2: Answer found
Answer to my self
Add this to the init method of some_layer.mm
[self setContentSize:CGSizeMake(0, 0)];
Thanks for everyone who tried to help me :)
Analysing the code is the best solution!
BTW I deleted the overridden methodes for both setPos and deleted the code that changes the Sprites positions, it's like this now
// on "init" you need to initialize your instance
-(id) init
{
if( (self=[super init])) {
back = [CCSprite spriteWithFile:#"back.png"];
front = [CCSprite spriteWithFile:#"front.png"];
[front setOpacity:0];
[self addChild:back];
[self addChild:front];
[self setContentSize:CGSizeMake(0, 0)];
}
return self;
}
Are you setting some anchorPoint for the Layer or Sprite which you are using. if yes then please check that the anchor point should be set at center :
someSprite.anchorPoint=ccp(0.5,0.5);
For more details : http://www.qcmat.com/understanding-anchorpoint-in-cocos2d/

Stop drawing of CATiledLayer

Is is possible to stop CATiledLayer to draw (drawLayer:inContext)?
It draws asynchronously and when i try to release CGPDFDocumentRef, which is used by CATiledLayer, the app crashes (EXC_BAD_ACCESS).
That's my view:
#implementation TiledPDFView
- (id)initWithFrame:(CGRect)frame andScale:(CGFloat)scale{
if ((self = [super initWithFrame:frame])) {
CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
tiledLayer.levelsOfDetail = 4;
tiledLayer.levelsOfDetailBias = 4;
tiledLayer.tileSize = CGSizeMake(512.0, 512.0);
myScale = scale;
}
return self;
}
// Set the layer's class to be CATiledLayer.
+ (Class)layerClass {
return [CATiledLayer class];
}
- (void)stopDrawing{
CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
[tiledLayer removeFromSuperlayer];
tiledLayer.delegate = nil;
}
// Set the CGPDFPageRef for the view.
- (void)setPage:(CGPDFPageRef)newPage
{
CGPDFPageRelease(self->pdfPage);
self->pdfPage = CGPDFPageRetain(newPage);
//self->pdfPage = newPage;
}
-(void)drawRect:(CGRect)r
{
}
// Draw the CGPDFPageRef into the layer at the correct scale.
-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context
{
// First fill the background with white.
CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0);
CGContextFillRect(context,self.bounds);
CGContextSaveGState(context);
// Flip the context so that the PDF page is rendered
// right side up.
CGContextTranslateCTM(context, 0.0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// Scale the context so that the PDF page is rendered
// at the correct size for the zoom level.
CGContextScaleCTM(context, myScale,myScale);
CGContextDrawPDFPage(context, pdfPage);
CGContextRestoreGState(context);
}
// Clean up.
- (void)dealloc {
CGPDFPageRelease(pdfPage);
[super dealloc];
}
And this is where i try to stop and release PDF in view controller:
v is instance of TiledPDFView
-(void) stopDwaring {
[v stopDrawing];
[v removeFromSuperview];
[v release];
[self.view removeFromSuperview];
self.view = nil;
CGPDFDocumentRelease(pdf);
}
this post helped me solving my own trouble with CATiledLayer. I used TiledPDFview.m from Apple's documentation as example.
Since I need to redraw the entire view and all tiles at some point, I use a CATiledLayer as property.
When exiting and deallocating the viewcontroller, it crashed with [CATiledLayer retain]: Message sent to deallocated instance.
Here is my dealloc method of the view controller:
- (void)dealloc {
self.tiledLayer.contents=nil;
self.tiledLayer.delegate=nil;
[self.tiledLayer removeFromSuperlayer];
// note: releasing the layer still crashes-
// I guess removeFromSuperlayer releases it already,
// but couldn't find documentation so far.
// So that's why it's commented out:
// [self.tiledLayer release], self.tiledLayer=nil;
//release the other viewcontroller stuff...
[super dealloc];
}
That works for me. Hope it helps someone.
Remove the CATiledLayer from its superlayer before releasing the CGPDFDocumentRef.
[yourTiledLayer removeFromSuperlayer];
Dont forget to set it's delegate to nil too.
yourTiledLayer.delegate = nil;
After that, you can safely release your CGPDFDocumentRef.
Edit after OP adds code:
Did you get pdfPage using CGPDFDocumentGetPage()? If so, you shouldn't release it, it is an autoreleased object.
Regarding how to add it as sublayer:
You don't actually need TiledPDFView. In your view controller, you can simply do this:
CATiledLayer *tiledLayer = [CATiledLayer layer];
tiledLayer.delegate = self; //sets where tiledLayer will look for drawLayer:inContext:
tiledLayer.tileSize = CGSizeMake(512.0f, 512.0f);
tiledLayer.levelsOfDetail = 4;
tiledLayer.levelsOfDetailBias = 4;
tiledLayer.frame = CGRectIntegral(CGRectMake(0.0f, 0.0f, 512.0f, 512.0f));
[self.view.layer addSublayer:tiledLayer];
Then move your drawLayer:inContext: implementation to your view controller.
Then in your view controller's dealloc, release it as:
[tiledLayer removeFromSuperlayer];
tiledLayer.delegate = nil;
CGPDFDocumentRelease(pdf);
Note that you can't do this on a UIView subclass, as the drawLayer:inContext: will conflict with the UIView's main layer.
object.layer.contents = Nil
This should wait for the thread to finish. It helped in my case.
TiledPDFView *pdfView;
In dealloc of pdfView's superview class, write below line of codes.
- (void)dealloc {
if (nil != self.pdfView.superview) {
self.pdfView.layer.delegate = nil;
[self.pdfView removeFromSuperview];
}
}
This works for me. Hope it will help.
I've had a similar problem.
I ended up setting a float variable "zoom" in my TiledPDFView which I set as the zoomScale of PDFScrollView in the UIScrollview Delegate method: scrollViewDidZoom
Then in my drawLayer method inside TiledPDFView I only called the contents of that method if the float variable "zoom" was above 2.
This fixes any issues of someone leaving the view without zooming. It may not be ideal for your case as this error still occurs if someone zooms above 2 then releases the viewcontroller quickly, but you might be able to find a similar technique to cover all bases.
It looks like you're doing the same thing I am, which is borrowing the ZoomingPDFView code and integrating it into your project. If your UIScrollView delegate methods in PDFScrollView are unchanged, you can solve your problem by just commenting both lines of your dealloc method (in TiledPDFView). That stuff should only be happening when you kill the parent view, anyway.

Adding Padding To The 'left' of a Text Field

I have a text field with a background but to make it look right the text field needs to have some padding on the left side of it a bit like the NSSearchField does. How would I give the text field some padding on the left?
smorgan's answer points us in the right direction, but it took me quite a while to figure out how to restore the customized textfield's ability to display a background color -- you must call setBorder:YES on the custom cell.
This is too late to help Joshua, but here's the how you implement the customized cell:
#import <Foundation/Foundation.h>
// subclass NSTextFieldCell
#interface InstructionsTextFieldCell : NSTextFieldCell {
}
#end
#import "InstructionsTextFieldCell.h"
#implementation InstructionsTextFieldCell
- (id)init
{
self = [super init];
if (self) {
// Initialization code here. (None needed.)
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (NSRect)drawingRectForBounds:(NSRect)rect {
// This gives pretty generous margins, suitable for a large font size.
// If you're using the default font size, it would probably be better to cut the inset values in half.
// You could also propertize a CGFloat from which to derive the inset values, and set it per the font size used at any given time.
NSRect rectInset = NSMakeRect(rect.origin.x + 10.0f, rect.origin.y + 10.0f, rect.size.width - 20.0f, rect.size.height - 20.0f);
return [super drawingRectForBounds:rectInset];
}
// Required methods
- (id)initWithCoder:(NSCoder *)decoder {
return [super initWithCoder:decoder];
}
- (id)initImageCell:(NSImage *)image {
return [super initImageCell:image];
}
- (id)initTextCell:(NSString *)string {
return [super initTextCell:string];
}
#end
(If, like Joshua, you only want an inset at the left, leave the origin.y and height as is, and add the same amount to the width -- not double -- as you do to the origin.x.)
Assign the customized cell like this, in the awakeFromNib method of the window/view controller that owns the textfield:
// Assign the textfield a customized cell, inset so that text doesn't run all the way to the edge.
InstructionsTextFieldCell *newCell = [[InstructionsTextFieldCell alloc] init];
[newCell setBordered:YES]; // so background color shows up
[newCell setBezeled:YES];
[self.tfSyncInstructions setCell:newCell];
[newCell release];
Use a custom NSTextFieldCell that overrides drawingRectForBounds:. Have it inset the rectangle by however much you want, then pass than new rectangle to [super drawingRectForBounds:] to get the normal padding, and return the result of that call.