CALayer does not seem to be defined - iphone

I wanted to add rounded Rects to a UITextView as explained in How to style UITextview to like Rounded Rect text field?. However when I do this I receive an error message that the methods used there are not found. I think this is weird as they are also still in the documentation. On the other side XCode does not show anything in autocomplete on the field layer. Is this field somehow deprecated or where could be the problem?
Here the two code snippets I was using:
#interface AddItemViewController : UIViewController {
IBOutlet UITextView *detailsTextView;
}
#end
Hier will ich dann die Eigenschaften aendern.
- (void)viewDidLoad
{
[super viewDidLoad];
// add rounded rects to detailsTextView
//first leads to warning that method is unknown
[detailsTextView.layer setCornerRadius:8.0f];
// displays error that property is not found on object of type CALayer *
textView.layer.cornerRadius = 8.0f;
detailsTextView.clipsToBounds = YES;
}

Add the QuartzCore framework in your project
Include this in your .h file
#import <QuartzCore/QuartzCore.h>

Related

Can I reuse colors in Interface Builder?

I've got several yellow buttons created using Inteface Builder. All have the same color. Currently I declare color in each xib. Can I declared it globally and reuse across all xibs?
Not possible in Interface Builder. Do it in code, for example by creating special subclass of the button.
You could use system Color Palette to save the color, but you still need to apply it to all buttons every time you decide to change it. Or you can just use Recently Used Colors in the color chooser, but neither way is enough dynamic.
Yes, you can do this.
At the bottom of the color picker popup in Interface Builder, there's a row of squares you can use to store colors for later use. Drag a color into it from the rectangle where the current color is shown at the top of the color picker to store it, and then just click a stored color later to use it.
I don't believe there is a way to do this entirely in interface builder, unfortunately. However, you can come pretty close with a little bit of code. The best way I've found to be able to change colors throughout the app in one go is to subclass the item that you want to color (UILabel, for instance) to set the color upon initialization:
#interface HuedUILabel : UILabel
#end
#implementation HuedUILabel
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
// Initialization code
self.textColor = [AppConfig primaryColor];
}
return self;
}
#end
Then, set the label to have a custom class in IB:
Now, when you want to change the color of all your UILabels, you can do it by changing your one color def AND you don't have to clutter your code with a bunch of appearance assignments.
Most definitely!
Create a singleton object (you can call it OksanaColor, to be cool)...
... or, if you're really lazy, a read-only UIColor property that you can access from your app delegate.
You can also add a category on UIColor, so you can use it same as when you use UIColor. For example in my App I add a new file called ApplicationColors which contains all my app colors.
#interface UIColor (ApplicationColours)
+(UIColor *)savaColor;
#end
Implementation:
#implementation UIColor (ApplicationColours)
+(UIColor *)savaColor
{
return [UIColor colorWithRed:228.0f/255.0f green:86.0f/255.0f blue:86.0f/255.0f alpha:1.0f];
}
#end
Then to use it in my app, I import the ApplicationColours.h and use the same as any other UIColor. i.e:
label.textColor = [UIColor savaColor];
Here's a very simple implementation of a named colors category for UIColor. With this code in your project, UIColor will remember any colors you want to save, and will let you access your own colors or system colors using +colorWithName:
#interface UIColor (namedColors)
+ (UIColor *) colorWithName:(NSString *) name;
+ (void) setColor:(UIColor *) color forName:(NSString *) name;
#end
static NSMutableDictionary *colorStorage;
#implementation UIColor (namedColors)
+ (NSMutableDictionary *) colorStorage
{
if (!colorStorage)
colorStorage = [[NSMutableDictionary alloc] initWithCapacity:10];
return colorStorage;
}
+ (UIColor *) colorWithName:(NSString *) name
{
UIColor *result =[[self colorStorage] valueForKey:name]; // See if we have a color with this name in the colorStorage.
if (result) return result;
SEL selector = NSSelectorFromString(name); // look for a class method whose selector matches the given name, such as "blueColor" or "clearColor".
if ([self respondsToSelector:selector] && (result = [self performSelector:selector]))
if ([result isKindOfClass:[self class]])
return result;
return nil;
}
+ (void) setColor:(UIColor *) color forName:(NSString *) name
{
[[self colorStorage] setValue:color forKey:name];
}
#end

How do I set a custom font for the whole application?

Is there any way to How to Apply global font [new custom font] to whole application in iphone objective-c.
I know that we can use below method to set font for each label
[self.titleLabel setFont:[UIFont fontWithName:#"FONOT_NAME" size:FONT_SIZE]];
But I want to change for whole application.
Please help me if anyone know.
Apparently to change ALL UILabels altogether you will need to setup a category on UILabel and change the default font. So here's a solution for you:
Create a file CustomFontLabel.h
#interface UILabel(changeFont)
- (void)awakeFromNib;
-(id)initWithFrame:(CGRect)frame;
#end
Create a file CustomFontLabel.m
#implementation UILabel(changeFont)
- (void)awakeFromNib
{
[super awakeFromNib];
[self setFont:[UIFont fontWithName:#"Zapfino" size:12.0]];
}
-(id)initWithFrame:(CGRect)frame
{
id result = [super initWithFrame:frame];
if (result) {
[self setFont:[UIFont fontWithName:#"Zapfino" size:12.0]];
}
return result;
}
#end
Now ... in any view controller you want these custom font labels, just include at the top:
#import "CustomFontLabel.h"
That's all - good luck
Ican's solution with category might be prefered just to save the day. But avoid using category to override existing methods as apple explains:
Avoid Category Method Name Clashes
... If the name of a method declared in a category is the same as a method in the original class, or a method in another category on the same class (or even a superclass), the behavior is undefined as to which method implementation is used at runtime. ...
Note also that overriding -(id) init; would be safer than overriding -(id)initWithFrame:(CGRect)frame. You would not face with the problem of not receiving touch events when clicking on a label on UIButtons.
Is this what you mean?
#interface GlobalMethods
+(UIFont *)appFont;
#end
#implementation GlobalMethods
+(UIFont *)appFont{
return [UIFont fontWithName:#"someFontName" size:someFontSize];
}
#end
...
[self.titleLabel setFont:[GlobalMethods appFont]];
In case you want to do it somehow automatically (without using setFont on each control), I don't believe it's possible.
If you can limit your application – or this particular feature – to iOS 5, there’s a new API coming that lets you skin the default UI very conveniently. I can’t give you details, since they are still under NDA at the time I am writing this. Take a look at iOS 5 beta SDK to find out more.
CustomLabel.h
#import <UIKit/UIKit.h>
#interface VVLabel : UILabel
#end
CustomLabel.m
#import "CustomLabel.h"
#define FontDefaultName #"YourFontName"
#implementation VVLabel
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder: aDecoder];
if (self) {
// Initialization code
// Static font size
self.font = [UIFont fontWithName:FontDefaultName size:17];
// If you want dynamic font size (Get font size from storyboard / From XIB then put below line)
self.font = [UIFont fontWithName:FontDefaultName size:self.font.pointSize];
}
return self;
}

Moving an UIView - newbie iphone sdk

Hey guys... today is my first day hacking away on the iphone SDK. Having a blast but have a quick question.
I'm trying to move an UIView around the screen dynamically by sending it information from a slider. My slider is working fine but I cant seem to figure out how to get the UIView to move.
My .h file...
#interface Slider_BallViewController : UIViewController
{
IBOutlet UISlider *theslider;
IBOutlet UITextField *ytext;
IBOutlet UIView *theball;
}
- (IBAction)moveVert:(id)sender;
My .m file...
- (IBAction)moveVert:(id)sender
{
int progressAsInt = (int)(theslider.value);
NSString *newText = [[NSString alloc] initWithFormat:#"%d", progressAsInt];
ytext.text = newText;
theball.frame.origin.y += progressAsInt;
}
I get an error on the frame.origin line in my .m file that says... lvalue required as left operand assignment. Not sure what im doing wrong.
Any help is great, thanks.
If you want to modify a UIView's frame property, you should do it by following:
CGRect curFrame = theball.frame;
curFrame.origin.y += progressAsInt;
theball.frame = curFrame;

Subclasses of UIButton loaded from nibs are not initialized properly

I have a very simple subclass of UIButton:
#interface MyButton : UIButton
#end
#implementation MyButton
- (id) initWithCoder:(NSCoder *)decoder
{
if (!(self = [super initWithCoder:decoder]))
return nil;
NSLog(#"-[%# initWithCoder:%#]", self, decoder);
return self;
}
#end
In Interface Builder I add a UIButton, set its button type to Rounded Rect and its class identity to MyButton.
When running, I have the following log:
-[<MyButton: 0x5b23970; baseClass = UIButton; frame = (103 242; 114 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x5b23a90>> initWithCoder:<UINibDecoder: 0x6819200>]
but the button is not a round rect button anymore.
Observed on both iOS 3.2 and iOS 4.
Is this a bug or am I missing something obvious?
Create an instance of MyButton programmatically is not an acceptable answer, thanks.
Programmatically, you instantiate a button with +[UIButton buttonWithType:] which is actually a factory that returns a subclass of UIButton. So if you derive from UIButton you actually don't derive from your round rect button class (UIRoundedRectButton) but from a generic button class. But you are not allowed to subclass from UIRoundedRectButton AFAIK since it's an internal class.
It seems to be problematic to derive from UIButton, I've seen a lot of people recommed to derive from UIControl instead and implement the drawing yourself.
But you might find these articles helpful:
How to override -drawrect in UIButton subclass?
http://www.cocoabuilder.com/archive/cocoa/284622-how-to-subclass-uibutton.html
http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/
Also, I don't know why you want to derive from UIButton, but if you want to do some customization that does not involve overwriting any other methods it might be helpful to use the fact that you can do something like this:
- (id)initWithCoder:(NSCoder *)decoder {
// Decode the frame
CGRect decodedFrame = ...;
[self release];
self = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[self setFrame:decodedFrame];
// Do the custom setup to the button
return self;
}
I’m not sure if this is acceptable for your needs, but I tend to prefer to override -awakeFromNib instead of -initWithCoder: in these circumstances. Does doing this resolve the issue you’re seeing?

Set graphics context to display UIImage (Obj-C)

I'm trying to render a UIImage in Objective-C (working on a simple iPhone app (breakout-type thing) to get used to the environment). However, I'm getting an "Error: CGContextDrawImage: invalid context" error when I try and draw it.
My question is: how do I set the context that the DrawAtPoint method of UIImage uses?
Here the relevant code for how I'm initializing / calling everything:
#interface GameItem : NSObject
{
IBOutlet UIImage * sprite;
CGPoint pos;
}
- (id) initWithPositionAndSprite: (CGPoint)placementPosition :(UIImage*) blockImage;
- (void) update;
#property CGPoint pos;
#end
in update:
[sprite drawAtPoint:pos];
And initializing it like:
newBall = [[Ball alloc] initWithPositionAndSprite:CGPointMake(3.0, 4.0) :[UIImage imageNamed:#"ball.png"]];
(Ball inherits from GameItem, doesn't do anything different just yet)
I'm getting the invalid context from the drawAtPoint call afaik. Any help/pointers to somewhere that will explain how to set the context would be greatly appreciated.
Thanks!
If this is to be drawn to the screen, you'll need to locate your drawing code within the -drawRect: method of a UIView (or –drawInContext: of a CALayer). To update its contents, you'd need to call -setNeedsDisplay on the UIView or CALayer. Attempting drawing at any other time will cause the "invalid context" error you're seeing.
Try wrapping the call in UIGraphicsBeginImageContext() and UIGraphicsEndImageContext().