I have a button that I am trying to add a border to like this:
.h
#interface MyButton : UIButton
.m
#implementation MyButton
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
self.layer.borderWidth=1.0f;
self.layer.cornerRadius = 4;
self.layer.borderColor=[[UIColor blueColor] CGColor];
return self;
}
The border is not set, what am I doing wrong?
UIButton is not meant to be subclassed, I recommend using a category if all you are trying to do is style buttons. Here is an example category to accomplish what you want... note that this has not been run through a compiler, but you get the idea:
UIButton+Styles.h
#import <UIKit/UIKit.h>
#interface UIButton (Styles)
-(void)styleWithBorderColor:(UIColor *)color;
#end
.m
#import "UIButton+Styles.h"
#import <QuartzCore/QuartzCore.h>
#implementation UIButton (CURStyles)
-(void)styleWithBorderColor:(UIColor *)color
{
self.layer.masksToBounds = YES;
self.layer.cornerRadius = 4.0f;
self.layer.borderWidth = 1.0f;
self.layer.borderColor = color.CGColor;
}
#end
Now when you want to style a button simply import the category and call it like so:
[myButton styleWithBorderColor:[UIColor whiteColor]];
EDIT:
Please see comments... these should be prefixed to avoid confusion with framework methods
Add
self.layer.masksToBounds = YES;
Also if you are creating your button via Nib or Storyboard file initWithFrame method will not be called. In such a case do not forget to place your additional code in awakeFromNib method
- (void)awakeFromNib
{
self.layer.masksToBounds = YES;
self.layer.borderWidth=1.0f;
self.layer.cornerRadius = 4;
self.layer.borderColor=[[UIColor blueColor] CGColor];
}
There is nothing wrong with subclassing UIButton at all.. I suggest maybe you need to set
self.backgroundColor = nil; // or [UIColor clearColor]
self.layer.backgroundColor = desiredBackgroundColor.CGColor;
The backgroundcolor in UIView covers the border on the layer, move the background color to the layer instead to put it behind (and clip it to) the border
Related
I am trying to implement a solution I found in another thread but I fail. In interface builder I used the custom class ZFRippleButton for the UIButton class and I changed the type to Custom and State Config to Highlighted. This is the code I used:
#interface ZFRippleButton : UIButton
- (id)initWithCoder:(NSCoder *)aDecoder;
#end
#implementation ZFRippleButton
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self makeBorder];
}
return self;
}
- (void)makeBorder {
self.layer.cornerRadius = 10.0;
self.layer.borderColor = [[UIColor blueColor] CGColor];
self.layer.borderWidth = 1.0;
}
#end
My purpose is to get a circle with a custom color when I tap the button. What am I doing wrong?
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
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.
So I am new to iOS and I want some buttons with rounded boarders. I also want those borders to have the same effect as the text within the button when the button is selected.
Since roundRect buttons are no longer an object in iOS (or at least I couldn't find it and everywhere I read said that is was no more) I decided to write a custom class that extends UIButton. This is what I have:
- (void)drawRect:(CGRect)rect{
{
UIColor *blackColor = blackColor;
UIColor *transBlack = [blackColor colorWithAlphaComponent:(0.5)];
[self.layer setCornerRadius:10.0f];
[self.layer setBorderColor:[UIColor blackColor].CGColor];
[self.layer setBorderWidth:1.0];
if(self.isSelected){
[self.layer setBorderColor:(transBlack.CGColor)];
}
I'm not sure if I am using isSelected properly. I had an NSLog under it and it never seems to be executed no matter how many times I press the buttons.
Any help and suggestions of all kinds would be greatly appreciated. Thank you.
UIButton inherit from UIView, So you can use Layer's Methods...
Create new Object that Subclassing UIButton call it whatever you want, then implement the next Code:
In this sample i have UIButton subclass called PressedButton in the .m file:
#implementation PressedButton
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
//When the button is pressed the border color change to red
self.layer.borderColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.5].CGColor;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
//When the button is pressed the border color change back to black
self.layer.borderColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5].CGColor;
}
- (void)initialize{
self.layer.cornerRadius = 10.0f;
self.layer.borderColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5].CGColor;
self.layer.borderWidth = 2;
self.layer.masksToBounds = YES;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
[self initialize];
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initialize];
}
return self;
}
- (instancetype)init
{
self = [super init];
if (self) {
[self initialize];
}
return self;
}
#end
*** I implemented the all init methods to be sure no matter where i set the button (storyboard or via Code its get the same init).
After that just configure your button custom class to your "Pressed Button class" and that's it
If you need more help be free to ask :)
Im going through the different options of creating a custom UINavigationBar and since my app is iOS 5+, i am using this code:
// Set the background image all UINavigationBars
[[UINavigationBar appearance] setBackgroundImage:NavigationPortraitBackground
forBarMetrics:UIBarMetricsDefault];
Now i want a custom image button on the very right side and am a bit lost. Should I go another way, subclass UINavigationBar and add a button to it or would there be an easier way?
Absolutely subclass this thing. UINavigationBar is easy to subclass, but very hard to put into a navigation controller. I will show you my subclass (CFColoredNavigationBar), which also comes with an arbitrarily colored background for free.
//.h
#import <UIKit/UIKit.h>
#interface CFColoredNavigationBar : UINavigationBar
#property (nonatomic, strong) UIColor *barBackgroundColor;
#property (nonatomic, strong) UIButton *postButton;
#end
//.m
#import "CFColoredNavigationBar.h"
#implementation CFColoredNavigationBar
#synthesize barBackgroundColor = barBackgroundColor_;
#synthesize postButton = postButton_;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
-(void)awakeFromNib {
postButton_ = [[UIButton alloc]initWithFrame:CGRectMake(CGRectGetWidth(self.frame)-60, 0, 60.0f, CGRectGetHeight(self.frame))];
[postButton_ setImage:[UIImage imageNamed:#"Post.png"] forState:UIControlStateNormal];
[self addSubview:postButton_];
}
- (void)drawRect:(CGRect)rect {
if (barBackgroundColor_ == nil) {
barBackgroundColor_ = [UIColor blackColor];
}
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [barBackgroundColor_ CGColor]);
CGContextFillRect(context, CGRectInset(self.frame, 0, self.frame.size.height*-2));
}
#end