Custom UILabel does not show text - objective-c

I've made an custom UILabel class in which i draw a red line at the bottom of the frame.
The red line is showing but i cant get the text to show.
#import <UIKit/UIKit.h>
#interface LetterLabel : UILabel {
}
#end
#import "LetterLabel.h"
#implementation LetterLabel
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code
}
return self;
}
- (void)drawRect:(CGRect)rect {
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 2.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), 0.0, self.frame.size.height);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), self.frame.size.width, self.frame.size.height);
CGContextStrokePath(UIGraphicsGetCurrentContext());
}
- (void)dealloc {
[super dealloc];
}
#end
#import <UIKit/UIKit.h>
#import "Word.h"
#interface WordView : UIView {
Word *gameWord;
}
#property (nonatomic, retain) Word *gameWord;
#end
#implementation WordView
#synthesize gameWord;
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor whiteColor];
LetterLabel *label = [[LetterLabel alloc] initWithFrame:CGRectMake(0, 0, 20, 30)];
label.backgroundColor = [UIColor cyanColor];
label.textAlignment = UITextAlignmentCenter;
label.textColor = [UIColor blackColor];
[label setText:#"t"];
[self addSubview:label];
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Drawing code
}
- (void)dealloc {
[gameWord release];
[super dealloc];
}
#end

Surely your LetterLabel needs to call the UILabel's drawRect: at some point?
-(void)drawRect:(CGRect)rect {
// Your stuff goes here
[super drawRect: rect];
}

Related

How to draw Signature on UIView

I am new in ios.And I need to create a textview or label in which i can sign.
Like this image.
You can draw signature on UIView for that first subclass UIView and your subclass of UIView should be something like,
SignatureView.h
#import <UIKit/UIKit.h>
#interface SignatureView : UIView{
UIBezierPath *_path;
}
- (void)erase;
#end
SignatureView.m
#import "SignatureView.h"
#implementation SignatureView
- (void)drawRect:(CGRect)rect {
_path.lineCapStyle = kCGLineCapRound;
[_path stroke];
}
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame: frame];
if (self) {
[self setMultipleTouchEnabled: NO];
_path = [UIBezierPath bezierPath];
[_path setLineWidth:2.0];
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *mytouch=[[touches allObjects] objectAtIndex:0];
[_path moveToPoint:[mytouch locationInView:self]];
[_path addLineToPoint:[mytouch locationInView:self]];
[self setNeedsDisplay];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *mytouch=[[touches allObjects] objectAtIndex:0];
[_path addLineToPoint:[mytouch locationInView:self]];
[self setNeedsDisplay];
}
- (void)erase {
_path = nil; //Set current path nil
_path = [UIBezierPath bezierPath]; //Create new path
[_path setLineWidth:2.0];
[self setNeedsDisplay];
}
Then you can import SignatureView.h in any your view controller and can instantiate signature view something like,
SignatureView *signView= [[ SignatureView alloc] initWithFrame: CGRectMake(10, 10, self.view.frame.size.width-40, 200)];
[signView setBackgroundColor:[UIColor whiteColor]];
signView.layer.borderColor = [[UIColor lightGrayColor]CGColor];
signView.layer.borderWidth = 1.0;
[self.view addSubview:signView];
And on that view you can draw your signature!
And you can call erase method to erase the signature!
This my solution.
First I created the SignatureDrawView class.In side the SignatureDrawView class I wrote the function for the draw the signature.
SignatureDrawView.h
#import <UIKit/UIKit.h>
#interface SignatureDrawView : UIView
#property (nonatomic, retain) UIGestureRecognizer *theSwipeGesture;
#property (nonatomic, retain) UIImageView *drawImage;
#property (nonatomic, assign) CGPoint lastPoint;
#property (nonatomic, assign) BOOL mouseSwiped;
#property (nonatomic, assign) NSInteger mouseMoved;
- (void)erase;
- (void)setSignature:(NSData *)theLastData;
- (BOOL)isSignatureWrite;
#end
SignatureDrawView.m
#import "SignatureDrawView.h"
#implementation SignatureDrawView
#synthesize theSwipeGesture;
#synthesize drawImage;
#synthesize lastPoint;
#synthesize mouseSwiped;
#synthesize mouseMoved;
#pragma mark - View lifecycle
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (id)initWithCoder:(NSCoder*)coder
{
if ((self = [super initWithCoder:coder]))
{
drawImage = [[UIImageView alloc] initWithImage:nil];
drawImage.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
[self addSubview:drawImage];
self.backgroundColor = [UIColor whiteColor];
mouseMoved = 0;
}
return self;
}
#pragma mark touch handling
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches)
{
NSArray *array = touch.gestureRecognizers;
for (UIGestureRecognizer *gesture in array)
{
if (gesture.enabled & [gesture isMemberOfClass:[UISwipeGestureRecognizer class]])
{
gesture.enabled = NO;
self.theSwipeGesture = gesture;
}
}
}
mouseSwiped = NO;
UITouch *touch = [touches anyObject];
lastPoint = [touch locationInView:self];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self];
UIGraphicsBeginImageContext(self.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 3.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 0.0, 0.0, 1.0);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = currentPoint;
mouseMoved++;
if (mouseMoved == 10) {
mouseMoved = 0;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if(!mouseSwiped)
{
UIGraphicsBeginImageContext(self.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 3.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 0.0, 0.0, 1.0);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
CGContextFlush(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
self.theSwipeGesture.enabled = YES;
mouseSwiped = YES;
}
#pragma mark Methods
- (void)erase
{
mouseSwiped = NO;
drawImage.image = nil;
}
- (void)setSignature:(NSData *)theLastData
{
UIImage *image = [UIImage imageWithData:theLastData];
if (image != nil)
{
drawImage.image = [UIImage imageWithData:theLastData];
mouseSwiped = YES;
}
}
- (BOOL)isSignatureWrite
{
return mouseSwiped;
}
#end
Next in ViewController I created the UIImageView with UIView.
ViewController.h
#import <UIKit/UIKit.h>
#import "SignatureDrawView.h"
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet SignatureDrawView *drawSignView;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize drawSignView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)actionSave:(id)sender
{
// code for save the signature
UIGraphicsBeginImageContext(self.drawSignView.bounds.size);
[[self.drawSignView.layer presentationLayer] renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *postData = UIImageJPEGRepresentation(viewImage, 1.0);
....Then do your stuff to save this in DB or server
}
- (IBAction)actionCancel:(id)sender
{
//code for cancel the signature
[self.drawSignView erase];
}
- (IBAction)actionClear:(id)sender
{
//code for clear the signature
[self.drawSignView erase];
}
#end
NOTE:When you set the view in xib first identity inspector(it is left
> side in utilities).Then click the drop down box of class(it is part of
Custom Class).Select or choose SignatureDrawView.After that hook up
the view from xib or storyboard to ViewController.h
Below is the output screenshots
Also

getting into the loop when doing progress view, ios

I am creating progress view by using CALayer by following
Header class
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#interface ProgressBar : UIView
#property (strong, nonatomic) CALayer *subLayer;
#property (nonatomic) CGFloat progress;
#end
Implementation class
#implementation ProgressBar
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.progress = 0;
self.backgroundColor = [UIColor whiteColor];
self.subLayer = [CALayer layer];
self.subLayer.frame = self.bounds;
self.subLayer.backgroundColor = [UIColor orangeColor].CGColor;
[self.layer addSublayer:self.subLayer];
}
return self;
}
- (void)setProgress:(CGFloat)value {
NSLog(#"what is going on here");
if (self.progress != value) {
self.progress = value;
[self setNeedsLayout];
}
}
- (void)layoutSubviews {
CGRect rect = [self.subLayer frame];
rect.size.width = CGRectGetWidth([self bounds]) * self.progress;
[self.subLayer setFrame:rect];
}
In my viewcontroller, I am doing
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.pBar = [[ProgressBar alloc] initWithFrame:CGRectMake(0, 50, 320, 10)];
[self.view addSubview:self.pBar];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)click:(id)sender {
[self.pBar setProgress:.8];
}
When (IBAction)click is fired, I am getting into the infinitive loop like the picture below
Does anyone know what I am getting into this loop. Please advice me on this issue. Thanks
The problem is that your setProgress: method calls the setProgress: method - recursion.
- (void)setProgress:(CGFloat)value {
NSLog(#"what is going on here");
if (self.progress != value) {
self.progress = value; // <-- This calls [self setProgress:value]
[self setNeedsLayout];
}
}
Change the bad line to:
_progress = value;
Setting the ivar directly is always required when you implement the setter method of a property.

Implement "Empty View" for NSTabView

I've been experimenting with JUEmptyView (a custom Cocoa control / NSView subclass, which displays a custom center-aligned placeholder in the middle of the view when all subviews have been removed).
So, I tried implementing the same thing for an NSTabView - simply by making it an NSTabView subclass (and re-setting my initial NSTabView item class).
Generally, it does work - it does show the placeholder (when the last tab is closed).
However, some issues still exist :
The background remains as that of a tabitem (thought they've all been closed)
When resizing the window (given that the NSTabView stretches all the way from left to right and from top to bottom), the view seems like it fails to redraw itself properly.
Example :
Full Code :
Interface
#import <Cocoa/Cocoa.h>
#interface JUTabEmptyView : NSTabView
{
#private
BOOL forceShow;
NSString *title;
NSColor *titleColor;
NSFont *titleFont;
NSColor *backgroundColor;
}
#property (nonatomic, copy) NSString *title;
#property (nonatomic, retain) NSFont *titleFont;
#property (nonatomic, retain) NSColor *titleColor;
#property (nonatomic, retain) NSColor *backgroundColor;
#property (nonatomic, assign) BOOL forceShow;
- (id)initWithTitle:(NSString *)title;
- (id)initWithTitle:(NSString *)title andFont:(NSFont *)font;
- (id)initWithTitle:(NSString *)title font:(NSFont *)font color:(NSColor *)color andBackgroundColor:(NSColor *)backgroundColor;
#end
Implementation
#import "JUTabEmptyView.h"
#implementation JUTabEmptyView
#synthesize title, titleFont, titleColor, backgroundColor;
#synthesize forceShow;
#pragma mark -
#pragma mark Setter
- (void)setTitle:(NSString *)ttitle
{
[title autorelease];
title = [ttitle copy];
[self setNeedsDisplay:YES];
}
- (void)setTitleFont:(NSFont *)ttitleFont
{
[titleFont autorelease];
titleFont = [ttitleFont retain];
[self setNeedsDisplay:YES];
}
- (void)setTitleColor:(NSColor *)ttitleColor
{
[titleColor autorelease];
titleColor = [ttitleColor retain];
[self setNeedsDisplay:YES];
}
- (void)setBackgroundColor:(NSColor *)tbackgroundColor
{
[backgroundColor autorelease];
backgroundColor = [tbackgroundColor retain];
[self setNeedsDisplay:YES];
}
- (void)setForceShow:(BOOL)tforceShow
{
forceShow = tforceShow;
[self setNeedsDisplay:YES];
}
#pragma mark -
#pragma Drawing
- (void)drawRect:(NSRect)dirtyRect
{
if(forceShow || [[self subviews] count] == 0)
{
NSRect rect = [self bounds];
NSSize size = [title sizeWithAttributes:[NSDictionary dictionaryWithObject:titleFont forKey:NSFontAttributeName]];
NSSize bezierSize = NSMakeSize(size.width + 40.0, size.height + 20.0);
NSRect drawRect;
// Background
drawRect = NSMakeRect(0.0, 0.0, bezierSize.width, bezierSize.height);
drawRect.origin.x = round((rect.size.width * 0.5) - (bezierSize.width * 0.5));
drawRect.origin.y = round((rect.size.height * 0.5) - (bezierSize.height * 0.5));
[backgroundColor setFill];
[[NSBezierPath bezierPathWithRoundedRect:drawRect xRadius:8.0 yRadius:8.0] fill];
// String
drawRect = NSMakeRect(0.0, 0.0, size.width, size.height);
drawRect.origin.x = round((rect.size.width * 0.5) - (size.width * 0.5));
drawRect.origin.y = round((rect.size.height * 0.5) - (size.height * 0.5));
[title drawInRect:drawRect withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:titleColor, NSForegroundColorAttributeName,
titleFont, NSFontAttributeName, nil]];
}
}
- (void)willRemoveSubview:(NSView *)subview
{
[super willRemoveSubview:subview];
[self setNeedsDisplay:YES];
}
- (void)didAddSubview:(NSView *)subview
{
[super didAddSubview:subview];
[self setNeedsDisplay:YES];
}
#pragma mark -
#pragma mark Constructor / Destructor
- (void)constructWithTitle:(NSString *)ttitle font:(NSFont *)font color:(NSColor *)color andBackgroundColor:(NSColor *)tbackgroundColor
{
title = ttitle ? [ttitle copy] : [[NSString alloc] initWithString:#"No active document"];
titleFont = font ? [font retain] : [[NSFont boldSystemFontOfSize:[NSFont smallSystemFontSize]] retain];
titleColor = color ? [color retain] : [[NSColor colorWithCalibratedRed:0.890 green:0.890 blue:0.890 alpha:1.0] retain];
backgroundColor = tbackgroundColor ? [tbackgroundColor retain] : [[NSColor colorWithCalibratedRed:0.588 green:0.588 blue:0.588 alpha:1.000] retain];
}
- (id)initWithCoder:(NSCoder *)decoder
{
if(self = [super initWithCoder:decoder])
{
[self constructWithTitle:nil font:nil color:nil andBackgroundColor:nil];
}
return self;
}
- (id)initWithFrame:(NSRect)frameRect
{
if(self = [super initWithFrame:frameRect])
{
[self constructWithTitle:nil font:nil color:nil andBackgroundColor:nil];
}
return self;
}
- (id)initWithTitle:(NSString *)ttitle
{
if((self = [super init]))
{
[self constructWithTitle:ttitle font:nil color:nil andBackgroundColor:nil];
}
return self;
}
- (id)initWithTitle:(NSString *)ttitle andFont:(NSFont *)font
{
if((self = [super init]))
{
[self constructWithTitle:ttitle font:font color:nil andBackgroundColor:nil];
}
return self;
}
- (id)initWithTitle:(NSString *)ttitle font:(NSFont *)font color:(NSColor *)color andBackgroundColor:(NSColor *)tbackgroundColor
{
if((self = [super init]))
{
[self constructWithTitle:ttitle font:font color:color andBackgroundColor:tbackgroundColor];
}
return self;
}
- (void)dealloc
{
[title release];
[titleFont release];
[titleColor release];
[backgroundColor release];
[super dealloc];
}
#end
OK, so that's how I've managed to fix it.
It turns out this "Empty View" implementation, apart from print a rounded box with a label in it, in the very middle of the parent view, failed to re-draw the main background. So, all it takes is to repaint it...
In drawRect: just add :
[[NSColor grayColor] set]; // or any other color you prefer
NSRectFill([self bounds]);

UITextField shadow does not display when editing

I want to draw the text in an UITextField with a shadow. In order to do this, I have subclassed UITextField, and implemented the drawTextInRect: method as follows:
- (void)drawTextInRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// Create shadow color
float colorValues[] = {0.21875, 0.21875, 0.21875, 1.0};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef shadowColor = CGColorCreate(colorSpace, colorValues);
CGColorSpaceRelease(colorSpace);
// Create shadow
CGSize shadowOffset = CGSizeMake(2, 2);
CGContextSetShadowWithColor(context, shadowOffset, 0, shadowColor);
CGColorRelease(shadowColor);
// Render text
[super drawTextInRect:rect];
}
This works great for when the text field is not editing, but as soon as editing begins, the shadow disappears. Is there anything I am missing?
Here is the code for following component
#interface AZTextField ()
- (void)privateInitialization;
#end
#implementation AZTextField
static CGFloat const kAZTextFieldCornerRadius = 3.0;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (!self) return nil;
[self privateInitialization];
return self;
}
// In case you decided to use it in a nib
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (!self) return nil;
[self privateInitialization];
return self;
}
- (void)privateInitialization
{
self.borderStyle = UITextBorderStyleNone;
self.layer.masksToBounds = NO;
self.layer.shadowColor = [UIColor blackColor].CGColor;
self.layer.shadowOffset = CGSizeMake(0.0f, 5.0f);
self.layer.shadowOpacity = 0.5f;
self.layer.backgroundColor = [UIColor whiteColor].CGColor;
self.layer.cornerRadius = 4;
// This code is better to be called whenever size of the textfield changed,
// so if you plan to do that you can add an observer for bounds property
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:kAZTextFieldCornerRadius];
self.layer.shadowPath = shadowPath.CGPath;
}
#end
Couple of things to consider:
You want to set borderStyle to none, otherwise you'll end up with
UIKit putting subviews into your textfield
Depending on the Xcode
version you might want to link QuartzCore and to #import
<QuartzCore/QuartzCore.h>
For more complex appearance you can still
use shadow properties of the layer and move the drawing code itself
into the drawRect: method, but jake_hetfield was right if you
override drawRect you don't want to call super, especially in the end
of the method
As for the text drawing (you can see that it sticks to
close to the component borders), you have a separate
drawTextInRect: and drawPlaceholderInRect: method that draws the
text and placeholder respectively
You can use UIColor method for
colors and call CGColor property, it makes code more readable and
easier to maintain
Hope that helps!
Inspired by #jake_hetfield answer I created a custom UITextField that uses an internal label to do the drawing, check it out:
ShadowTextField .h file
#import <UIKit/UIKit.h>
#interface ShadowTextField : UITextField
// properties to change the shadow color & offset
#property (nonatomic, retain) UIColor *textShadowColor;
#property (nonatomic) CGSize textShadowOffset;
- (id)initWithFrame:(CGRect)frame
font:(UIFont *)font
textColor:(UIColor *)textColor
shadowColor:(UIColor *)shadowColor
shadowOffset:(CGSize)shadowOffset;
#end
ShadowTextField .m file
#import "ShadowTextField.h"
#interface ShadowTextField ()
#property (nonatomic, retain) UILabel *internalLabel;
#end
#implementation ShadowTextField
#synthesize internalLabel = _internalLabel;
#synthesize textShadowColor = _textShadowColor;
#synthesize textShadowOffset = _textShadowOffset;
- (id)initWithFrame:(CGRect)frame
font:(UIFont *)font
textColor:(UIColor *)textColor
shadowColor:(UIColor *)shadowColor
shadowOffset:(CGSize)shadowOffset
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
// register to my own text changes notification, so I can update the internal label
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleUITextFieldTextDidChangeNotification)
name:UITextFieldTextDidChangeNotification
object:nil];
self.font = font;
self.textColor = textColor;
self.textShadowColor = shadowColor;
self.textShadowOffset = shadowOffset;
}
return self;
}
// when the user enter text we update the internal label
- (void)handleUITextFieldTextDidChangeNotification
{
self.internalLabel.text = self.text;
[self.internalLabel sizeToFit];
}
// init the internal label when first needed
- (UILabel *)internalLabel
{
if (!_internalLabel) {
_internalLabel = [[UILabel alloc] initWithFrame:self.bounds];
[self addSubview:_internalLabel];
_internalLabel.font = self.font;
_internalLabel.backgroundColor = [UIColor clearColor];
}
return _internalLabel;
}
// override this method to update the internal label color
// and to set the original label to clear so we wont get two labels
- (void)setTextColor:(UIColor *)textColor
{
[super setTextColor:[UIColor clearColor]];
self.internalLabel.textColor = textColor;
}
// override this method to update the internal label text
- (void)setText:(NSString *)text
{
[super setText:text];
self.internalLabel.text = self.text;
[self.internalLabel sizeToFit];
}
- (void)setTextShadowColor:(UIColor *)textShadowColor
{
self.internalLabel.shadowColor = textShadowColor;
}
- (void)setTextShadowOffset:(CGSize)textShadowOffset
{
self.internalLabel.shadowOffset = textShadowOffset;
}
- (void)drawTextInRect:(CGRect)rect {
// don't draw anything
// we have the internal label for that...
}
- (void)dealloc {
[_internalLabel release];
[_textShadowColor release];
[super dealloc];
}
#end
Here is how you use it in your view controller
- (void)viewDidLoad
{
[super viewDidLoad];
ShadowTextField *textField = [[ShadowTextField alloc] initWithFrame:CGRectMake(0, 0, 320, 30)
font:[UIFont systemFontOfSize:22.0]
textColor:[UIColor whiteColor]
shadowColor:[UIColor redColor]
shadowOffset:CGSizeMake(0, 1) ] ;
textField.text = #"This is some text";
textField.backgroundColor = [UIColor blackColor];
[self.view addSubview:textField];
}
You could try to do the drawing of the label yourself. Remove
[super drawTextInRect:rect]
And instead draw your own label. I haven't tried this but it could look something like this:
// Declare a label as a member in your class in the .h file and a property for it:
UILabel *textFieldLabel;
#property (nonatomic, retain) UILabel *textFieldLabel;
// Draw the label
- (void)drawTextInRect:(CGRect)rect {
if (self.textFieldLabel == nil) {
self.textFieldLabel = [[[UILabel alloc] initWithFrame:rect] autorelease];
[self.view addSubview:myLabel];
}
self.textFieldLabel.frame = rect;
self.textFieldLabel.text = self.text;
/** Set the style you wish for your label here **/
self.textFieldLabel.shadowColor = [UIColor grayColor];
self.textFieldLabel.shadowOffset = CGSizeMake(2,2);
self.textFieldLabel.textColor = [UIColor blueColor];
// Do not call [super drawTextInRect:myLabel] method if drawing your own text
}
Stop calling super and render the text yourself.
Have your tried with the standard shadow properties of the CALayer? it usually is enough and it is lot simpler. Try something like this with a regular UITextField:
self.inputContainer.layer.shadowColor=[UIColor blackColor].CGColor;
self.inputContainer.layer.shadowRadius=8.0f;
self.inputContainer.layer.cornerRadius=8.0f;
self.inputContainer.layer.shadowOffset=CGSizeMake(0, 4);
You need to import QuartzCore first of course!
#import <QuartzCore/QuartzCore.h>

UITextField Example in Cocos2d

Can anyone please suggest some links for using UITextField in cocos2d.
I want to press on label, then the UITextField should get selected and I need to edit on that UITextField.
I'm doing this in a current project to allow for entering the number of the level to start playing at, so that's why my variables and methods are named the way they are; you should probably adjust these to make sense for you.
In your app controller, define this as an instance variable:
UITextField *levelEntryTextField;
Create it inside applicationDidFinishLaunching:
levelEntryTextField = [[UITextField alloc] initWithFrame:
CGRectMake(60, 165, 200, 90)];
[levelEntryTextField setDelegate:self];
Define a method to activate the text field. You should also declare it in the header file for your app controller.
- (void)specifyStartLevel
{
[levelEntryTextField setText:#""];
[window addSubview:levelEntryTextField];
[levelEntryTextField becomeFirstResponder];
}
This will make pressing "return" on the keypad end editing
- (BOOL)textFieldShouldReturn:(UITextField*)textField {
//Terminate editing
[textField resignFirstResponder];
return YES;
}
This is triggered when the editing is actually done.
- (void)textFieldDidEndEditing:(UITextField*)textField {
if (textField==levelEntryTextField) {
[levelEntryTextField endEditing:YES];
[levelEntryTextField removeFromSuperview];
// here is where you should do something with the data they entered
NSString *result = levelEntryTextField.text;
}
}
Now to actually set things in motion, you put this somewhere. I call this from within one of my Scene classes, in response to a user action:
[[[UIApplication sharedApplication] delegate] specifyStartLevel];
I took the example that Jack provided and actually created a working project, this was done using the Cocos2D 0.7.1 XCode Template, and then just editting the *AppDelegate.m/.h files, which are provided below in there entirety. I also modified some of what Jack said, because I feel that creating the UITextField in the appDidFinishLoading would utilize a bit too much memory, especially if the text field is not used all the time ... this solution creates the text field only when it is needed, the sample draws an empty Cocos2D Layer scene, and on screen touch, it displays the text field for you to start entering text into. It will spit out the result of what you entered to the Console - you can pass this to whatever is necessary in your own code.
the .h
#import <UIKit/UIKit.h>
#import "cocos2d.h"
#interface MYSCENE : Layer <UITextFieldDelegate>
{
UITextField *myText;
}
-(void)specificStartLevel;
#end
#interface textFieldTestAppDelegate : NSObject <UIAccelerometerDelegate, UIAlertViewDelegate, UITextFieldDelegate, UIApplicationDelegate>
{
UIWindow *window;
}
#end
and then the .m
#import "textFieldTestAppDelegate.h"
#implementation MYSCENE
-(id) init
{
self = [super init];
isTouchEnabled = YES;
return self;
}
-(BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self specifyStartLevel];
return kEventHandled;
}
-(void)specifyStartLevel {
myText = [[UITextField alloc] initWithFrame:CGRectMake(60, 165, 200, 90)];
[myText setDelegate:self];
[myText setText:#""];
[myText setTextColor: [UIColor colorWithRed:255 green:255 blue:255 alpha:1.0]];
[[[[Director sharedDirector] openGLView] window] addSubview:myText];
[myText becomeFirstResponder];
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
[myText resignFirstResponder];
return YES;
}
-(void)textFieldDidEndEditing: (UITextField *)textField {
if(textField == myText) {
[myText endEditing:YES];
[myText removeFromSuperview];
NSString *result = myText.text;
NSLog([NSString stringWithFormat:#"entered: %#", result]);
} else {
NSLog(#"textField did not match myText");
}
}
-(void) dealloc
{
[super dealloc];
}
#end
#implementation textFieldTestAppDelegate
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[window setUserInteractionEnabled:YES];
[[Director sharedDirector] setDisplayFPS:YES];
[[Director sharedDirector] attachInWindow:window];
Scene *scene = [Scene node];
[scene addChild: [MYSCENE node]];
[window makeKeyAndVisible];
[[Director sharedDirector] runWithScene: scene];
}
-(void)dealloc
{
[super dealloc];
}
-(void) applicationWillResignActive:(UIApplication *)application
{
[[Director sharedDirector] pause];
}
-(void) applicationDidBecomeActive:(UIApplication *)application
{
[[Director sharedDirector] resume];
}
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
[[TextureMgr sharedTextureMgr] removeAllTextures];
}
#end
To add Text field in cocos2d as below code
first of all you add view in Scene and afetr add textfield add in view thats very easy.
-(id) init
{
if( (self=[super init]) )
{
// add view in scene
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 568)];
view.backgroundColor = [UIColor redColor];
// add textfield in view
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 140, 300, 30)];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.font = [UIFont systemFontOfSize:15];
textField.placeholder = #"enter text";
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.keyboardType = UIKeyboardTypeDefault;
textField.returnKeyType = UIReturnKeyDone;
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
textField.delegate = self;
[view addSubview:textField];
// add view in scene
[[[CCDirector sharedDirector] view] addSubview:view];
}
return self;
}
you can also use CCTextfield in cocos2d best example is https://github.com/iNinja/CCTextField
Try the following CCNode subclass, CCMenuItemTextField, to use text fields in cocos2d.
The class is directly subclassed from CCMenuItemSprite. When tapped, the "selected" method is called and a UITextField is added to the main window. After editing is done, "unselected" method is called and the UITextField is removed from screen. User's input is saved to a CCLabelTTF node, which position itself exactly as the original UITextField.
CCMenuItemTextField.h
#interface CCMenuItemTextField : CCMenuItemSprite<UITextFieldDelegate> {
UITextField *textField_;
CCLabelTTF *label_;
CGFloat paddingLeft_;
}
#property (readonly, nonatomic) UITextField *textField;
#property (readonly, nonatomic) CCLabelTTF *label;
#property (assign, nonatomic) CGFloat paddingLeft;
- (void)selected;
- (void)unselected;
- (void)setFontSize:(CGFloat)size;
- (NSString*)text;
- (void)setText:(NSString*)text;
#end
CCMenuItemTextField.m
#import "CCMenuItemTextField.h"
#implementation CCMenuItemTextField
#synthesize
textField = textField_,
label = label_,
paddingLeft = paddingLeft_;
- (id)init
{
CCSprite *normalSprite = [CCSprite spriteWithFile:#"text_field_background.png"];
CCSprite *selectedSprite = [CCSprite spriteWithFile:#"text_field_background.png"];
CCSprite *disabledSprite = [CCSprite spriteWithFile:#"text_field_background.png"];
return [self initWithNormalSprite:normalSprite selectedSprite:selectedSprite disabledSprite:disabledSprite];
}
- (id)initWithNormalSprite:(CCNode<CCRGBAProtocol> *)normalSprite
selectedSprite:(CCNode<CCRGBAProtocol> *)selectedSprite
disabledSprite:(CCNode<CCRGBAProtocol> *)disabledSprite
{
self = [super initWithNormalSprite:normalSprite
selectedSprite:selectedSprite
disabledSprite:disabledSprite
target:self
selector:#selector(selected)];
if (self) {
paddingLeft_ = 3.0;
textField_ = [[UITextField alloc] init];
[textField_ setTextColor:[UIColor blackColor]];
[textField_ setFont:[UIFont systemFontOfSize:18]];
label_ = [[CCLabelTTF node] retain];
[label_ setAnchorPoint:ccp(0,0.5)];
[label_ setFontSize:18];
[label_ setVisible:NO];
[label_ setColor:ccBLACK];
[self addChild:label_];
}
return self;
}
- (void)dealloc
{
[label_ release];
[textField_ release];
[super dealloc];
}
// --------------------------------
// Public
// --------------------------------
- (void)selected
{
[super selected];
[label_ setVisible:NO];
CGAffineTransform transform = [self nodeToWorldTransform];
float textFieldHeight = textField_.font.lineHeight;
float width = self.contentSize.width;
float height = self.contentSize.height;
float left = transform.tx + paddingLeft_;
float top = 480 - transform.ty - height + (height - textFieldHeight) / 2;
[textField_ setFrame:CGRectMake(left, top, width, height)];
[[[[CCDirector sharedDirector] view] window] addSubview:textField_];
[textField_ becomeFirstResponder];
[textField_ setDelegate:self];
}
- (void)unselected
{
[super unselected];
[label_ setVisible:YES];
[label_ setPosition:ccp(paddingLeft_, self.contentSize.height/2)];
NSString *text = textField_.text ? textField_.text : #"";
[label_ setString:text];
[textField_ resignFirstResponder];
[textField_ removeFromSuperview];
}
- (NSString*)text
{
return [label_ string];
}
- (void)setText:(NSString*)text
{
[label_ setString:text];
[textField_ setText:text];
}
// --------------------------------
// UITextFieldDelegate
// --------------------------------
- (BOOL)textFieldShouldReturn:(UITextField*)textField {
[self unselected];
return YES;
}
- (void)textFieldDidEndEditing:(UITextField*)textField {
[self unselected];
}
- (void)setFontSize:(CGFloat)size
{
[label_ setFontSize:size];
[textField_ setFont:[UIFont systemFontOfSize:size]];
}
// --------------------------------
// CCNode
// --------------------------------
- (void)onExitTransitionDidStart
{
[super onExitTransitionDidStart];
[self unselected];
}
#end