Properly cast a UILabel - ios

I've created a custom sub-class GTLabel of UILabel to have the right font, size, color, etc...
When I create a GTLabel programmatically, everything works fine. When I create a UILabel in the IB, I just have to change its class into GTLabel and it works.
Now when I have a UIButton, with a titleLabel, I would like to transform this UILabel into a GTLabel.
I've created a class method in GTLabel :
+ (GTLabel*)labelFromLabel:(UILabel*)label
{
...
return myGTLabel;
}
I don't really see how I'm suppose to proceed in this method.
Am I suppose to do as bellow?
GTLabel *myGTLabel = [[GTLabel alloc] init];
// Get all the properties of the original label
myGTLabel.text = label.text;
myGTLabel.frame = label.frame;
// Do the modifications
myGTLabel.font = [UIFont fontWithName:#"Gotham-Light"
size:label.font.pointSize];
The idea would be to do something like
myButton.titleLabel = [GTLabel labelFromLabel:myButton.titleLabel];
Thanks for your help !

You could implement your custom UIButton ( eg. GTButton ) and redefine titleLabel property, setting the same propertylabel used for your GTLabel
something like:
#import "GTButton.h"
#implementation GTButton
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
-(UILabel *)titleLabel
{
UILabel* parentLabel = [super titleLabel];
parentLabel.font = [UIFont fontWithName:#"Gotham-Light"
size:parentLabel.font.pointSize];
// ... set all your attributes
return parentLabel;
}
#end

titleLabel method of UIButton is read-only.
Although this property is read-only, its own properties are read/write. Use these properties primarily to configure the text of the button.
For example:
UIButton *button = [UIButton buttonWithType: UIButtonTypeSystem];
button.titleLabel.font = [UIFont systemFontOfSize: 12];
button.titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
Create custom class for UIButton as you create for label and set property in it.

Related

Objective c / iOS: How to override custom class's layoutSubviews in viewController

I have created a custom UILabel class and set the default background color.
Here are .h and .m files of my custom class.
#import <UIKit/UIKit.h>
#interface imLabel : UILabel
#end
AND
#import "imLabel.h"
#implementation imLabel
- (void)drawRect:(CGRect)rect {
}
- (void) layoutSubviews {
self.backgroundColor = [UIColor redColor];
}
#end
It works fine, but here is what I need: I want this work only if the backgroundColor is not set in ViewController.
Here is my viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
label = [[imLabel alloc] initWithFrame:CGRectMake(50, 50, 300, 300)];
label.backgroundColor = [UIColor blueColor];
[self.view addSubview:label];
}
You control whether set label's backgroundColor or not in ViewController, so the best way to meet your need that I think is check the label had set backgroundColor or not, if not then set it.
/* Somewhere in your ViewController */
if (!self.label.backgroundColor) {
self.label.backgroundColor = [UIColor redColor];
}
Delete all your other code in imLabel.m, then:-
(instancetype)initWithFrame:(CGRect)aRect { self = [super initWithFrame:aRect]; if (self) { self.backgroundColor = [UIColor redColor]; } return self;}
Thanks to #Meiliang Dong

UITableView cell selection

I've got a UILabel with a background color in a cell. When I select this cell, the cell changes the color (which it should) but it also changes the background of the label. I want the preserve the background color on the UILabel. When I use an image with just a random color in it it is preserved, but isn't there any better way?
Thanks in advance
Code:
_label = [UILabel new];
_label.translatesAutoresizingMaskIntoConstraints = NO;
_label.font = [UIFont systemFontOfSize:10.f];
_label.backgroundColor = HEXCOLOR(0xFFE5E5E5); //Macro just a UIColor
But I use this way to add a different selection color (could have something to do with it)
UIView *selectionColor = [[UIView alloc] init];
selectionColor.backgroundColor = HEXCOLOR(0XFFF1F1F1);
self.selectedBackgroundView = selectionColor;
self.contentView.backgroundColor = [UIColor whiteColor];
Nothing really more to it. Just a simple label added with autolayout to fill with a padding of 5.
Solution:
Create a subclass of UILabel and just not call super
- (instancetype) initWithColor:(UIColor *)color
{
self = [super init];
if (self) {
[super setBackgroundColor:color];
}
return self;
}
- (void) setBackgroundColor:(UIColor *)backgroundColor
{
//do nothing here!
}
The default behavior of UITableView is that when a cell is selected the background color of all the cell's subviews is temporarily removed.
We usually handled this issue by subclassing UILabel, overwrite setBackgroundColor: and simply do not call [super setBackgroundColor:] after we've set our own color.
#interface MyLabel : UILabel
#property(nonatomic) BOOL backgroundColorLocked;
#end
#implementation MyLabel
-(void) setBackgroundColor:(UIColor*)backgroundColor {
if (_backgroundColorLocked) {
return;
}
super.backgroundColor = backgroundColor;
}
#end
Usage:
MyLabel* label = …;
label.backgroundColor = UIColor.redColor;
label.backgroundColorLocked = YES;
As long as backgroundColorLocked is YES no-one, not even UITableView(Cell), can change the label's background color.

Reuse UIButton style

I've got a couple of UIButtons with all the same style, but sometimes they have different colors and sometimes they have different widths. However, I hate to make a seperate class for a new button that just needs a slightly different color, so I thought that there must be a way to style a button and take, for instance, the color and height as a property. After that I image it would work just as importing a UITableView's datasource/delegate.
So a more concrete question: is there a way to make a class for a UIButton that takes parameters such as width and height, and is it possible to declare this kind of class to a UIButton?
That's no problem at all. Create a category or subclass of UIButton. Define a custom init method like - (instancetype)initWithColor:(UIColor *)color size:(CGSize)size. In the init method call self = [super initWithFrame:CGRectZero] and then set those properties on self.
About the frequently used style, you can make a method which return a styled button.
- (UIButton *)styledButtonWithFrame:(CGRect)frame
{
UIButton *btn = [[UIButton alloc] initWithFrame:frame];
[btn setBackgroundColor:[UIColor redColor]];
[btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
return btn;
}
and you can create an instance of styledButton
UIButton *styledBtn = [self styledButtonWithFrame:CGRectMake(0, 0, 10, 10)];
The second question, you can use category.
#interface UIView (BKExpansion)
#property (nonatomic, assign) CGFloat frameX;
#property (nonatomic, assign) CGFloat frameHeight;
#end
#implementation UIView (BKExpansion)
- (CGFloat)frameX
{
return self.frame.origin.x;
}
- (void)setFrameX:(CGFloat)frameX
{
CGRect frame_ = self.frame;
frame_.origin.x = frameX;
self.frame = frame_;
}
- (CGFloat)frameWidth
{
return self.frame.size.width;
}
- (void)setFrameWidth:(CGFloat)frameWidth
{
CGRect frame_ = self.frame;
frame_.size.width = frameWidth;
self.frame = frame_;
}
#end
You can add frameY, frameBottom, and so on.
If you want to change frameX or frameWidth, just use
[styledBtn setFrameY:30];

how to change TTStyledTextTableItemCell 's background

Suppose I create TTTableStyledTextItem objects in <TTTableViewDataSource> conforming class as follows:
NSString* text = [NSString stringWithFormat:#"<b>%#</b>\n%#", #"aaaa..", #"bbbb.."];
TTStyledText* styledText = [TTStyledText textFromXHTML:text lineBreaks:YES URLs:NO];
TTTableStyledTextItem* item = [TTTableStyledTextItem itemWithText:styledText URL:#"my://url"];
By default, the table view cell class returned by tableView:cellClassForObject: is going to be TTStyledTextTableItemCell.
This works all right by I'd like to customize the background color of the cell when it is in the normal state (when it is not in the selected state).
I've managed to change the cell's background in the selected state by creating a TTStyledTextTableItemCell subclass and overriding the initWithStyle:reuseIdentifier: initializer as follows:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier {
self = [super initWithStyle:style reuseIdentifier:identifier];
if (self) {
// WORKS!
// cell's backgroundview (selected)
UIView *selectedView = [[UIView alloc] init];
selectedView.backgroundColor = [UIColor someColor..];
self.selectedBackgroundView = selectedView;
// DOESN'T WORK
// cell's background (normal)
UIView *normalView = [[UIView alloc] init];
normalView.backgroundColor = [UIColor someColor..];
self.backgroundView = normalView;
}
return self;
}
but I can't find a way to change the background of the cell when it's not selected (self.backgroundView). I know that there's an associated TTStyledTextLabel subview in the TTStyledTextTableItemCell class, but I still have no success customizing it.
Is there an easy way to achieve this??
Thanks

Displaying a single string in a view programmatically on iOS

We have a window filled with little view squares (think of a Calculator).
For a specific view on the window we want display a single string in the view without using the Interface Builder to add the string.
We need to be able to change the string and have the view refresh.
How do we programmatically add a string to a view and show it?
Update:
Ok here is the code we have currently. Nothing special in the header file.
I suppose the real quandry is considering we can easily get the background color to change, why is it that our text is just not showing??
Both versions are in there, would be happy to get 'apples' or 'oranges' displaying.
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
bgString = #"orange";
UILabel* aLabel = [[UILabel alloc] init];
aLabel.text = #"apple";
self.textLabel = aLabel;
[aLabel release];
[self addSubview:textLabel];
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Drawing code
[[UIColor yellowColor] setFill];
UIRectFill(rect);
[self drawStringCenteredIn:rect];
}
- (void)drawStringCenteredIn:(CGRect)r {
//CGSize strSize = [bgString size];
CGPoint strOrigin;
strOrigin.x = r.origin.x; //+ (r.size.width - 10)/2;
strOrigin.y = r.origin.y; //+ (r.size.height - 10)/2;
//[bgString drawAtPoint:strOrigin withFont:[UIFont fontWithName:#"Helvetica" size:10]];
[textLabel drawTextInRect:r];
}
In your view controller's .h:
#interface MyViewController
{
UILabel* label;
}
#property (nonatomic, retain) UILabel* label;
In your view controller's .m:
- (void)dealloc
{
[label release];
[super dealloc];
}
- (void)viewDidLoad
{
[super viewDidLoad];
UILabel* aLabel = [[UILabel alloc] init];
aLabel.text = #"Initial Text";
self.label = aLabel;
[aLabel release];
[self.view addSubview:aLabel];
}
- (void)viewDidUnload
{
[self.label removeFromSuperview];
self.label = nil;
}
// Call this when you need to update the label
- (void)updateLabel
{
self.label.text = #"Some updated text";
}
Did that from memory but it should work.
Try this:
UILabel* aLabel = [[UILabel alloc] initWithFrame:[self bounds]];
If you are creating the label manually, you need to set it's frame manually too.
Frame itself is size and position inside parent view(superview).
In my example i've set the frame of label to occupy the entire view. If you need your custom size you can use:
UILabel* aLabel = [[UILabel alloc] initWithFrame:CGRectMake(x,y,width,height)];
Where (x,y) - position of the top left corner of your label.
How about creating a UILabel and adding it to the view?
If you subclass the UIView, you can draw your string in the view's drawRect. This allows great flexibility in modifying the text, its appearance, and its placement (you can even animate it around, spin, rotate, etc.)
Call setNeedsDisplay on the view after you change your NSString. Then do an drawAtPoint:withFont: on the NSString when the drawRect is called.

Resources