I have a UIButton subclass that I initialize as:
MyButton *button = [MyButton buttonWithType:UIButtonTypeCustom];
I want to set the background color of this button.
If I do the following in the view controller after creating the button:
MyButton.backgroundColor = [UIColor ...];
It works fine. But if I try to do the following within the UIButton subclass, either in initWithFrame or in DrawRect:
self.backgroundColor = [UIColor ...];
It simply does nothing. The button remains transparent.
The thing is, my logic is such that I really need to set the color inside the UIButton subclass, not in the calling code.
Any ideas?
UIButton is not meant to be subclassed. It is a class cluster and you almost certainly get it wrong (it may break now or in the future). The base method buttonWithType: also will never return an instance of your class, so you need to go to great lengths to make all your code work.
The much better way is to to make a factory method that uses UIButton.buttonWithType: and configures the button the way you need it.
Can you implement "Buttonwithtype" method in your subclass and write code there self.backgroundColor = [UIColor WhateverColor];
It should work. let me know.
Related
I'm subclassing UITextField and want to assign to its rightView property a custom button.
I setup the button in setFrame of the subclass.
My textfields had their outlet connections in the ViewController and Class set to my subclass in Identity Inspector in Interface Builder.
The problem is that my custom button is not appearing.
I've tried to overcome the problem and made a setupRightView method in my subclass.
Then, when I call setupRightView on the outlet property from the View Controller - voila - everything is working just fine!
I'm fairly new to Objective-C and I suppose I'm making some stupid mistake with the object model.
Why I can't set correctly rightView property in my subclass?
Did you remember to do this:
self.rightViewMode = UITextFieldViewModeAlways;
That property is set to UITextFieldViewModeNever by default, so you won't see your button if you don't include that line.
After Edit: I checked on putting my code in setFrame, and it didn't work there -- not sure why. It worked fine if I put it in awakeFromNib.
-(void)awakeFromNib {
UIButton *myButton = [UIButton buttonWithType:2];
self.rightView = myButton;
self.rightViewMode = UITextFieldViewModeAlways;
}
The UITableView I am using has a custom UItableViewCell. This custom cell has a subview (an UIView subclass) to it. I use the drawRect of the custom UIView subclass to place all the text to be displayed by the cell.
And in the drawRect (of UIView subclass) I do the following
/*
// This piece of code is called when setNeedsDisplay is called
*/
- (void)drawRect:(CGRect)rect
{
self.layer.cornerRadius = 10.0f;
self.layer.backgroundColor = [[UIColor orangeColor] CGColor];
self.layer.borderColor = [[UIColor lightGrayColor] CGColor];
self.layer.borderWidth = 3.0f;
}
However my custom cell is a black square like this
But I do see the intended behavior if I select the row. Like shown below
Whats going on ?
Your drawRect: method does not draw anything; the code that you put in there belongs in your initWithFrame: implementation.
You should manipulate the layer configuration in the initializer; in your drawRect: you should call functions of your CGContextRef based on the state of the view. For example, to draw some text you would use CGContextShowTextAtPoint, to draw some lines you would use CGContextAddLineToPoint, and so on.
See this question for information on the relationship between drawRect: and the CALayer of your UIView.
Try to set self.layer.masksToBounds = YES and (maybe) self.opaque = NO during your UIView's (the one where drawRect is overridden) initialization. (see this question)
Try to disable the selection highlight of the cell by using
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
You are doing one mistake:
Please go to the view in side the UItableViewCell and check the background color it may be black or something others, Reset it to clear color then check your result,
I have tried the two options everybody answers in this forum but nothing works for me... I have tried to override:
- (void)drawPlaceholderInRect:(CGRect)rect
and also:
[self.myTextField setValue:[UIColor redColor] forKeyPath:#"_placeholderLabel.textColor"];
but nothing happens... Still the same gray color... Maybe I have to inherit something, I don't know... Any suggestion?
the simplest way to do this:
UILabel *placeholderAppearance;
if (#available(iOS 9, *)) {
placeholderAppearance = [UILabel appearanceWhenContainedInInstancesOfClasses:#[[UITextField class]]];
} else {
placeholderAppearance = [UILabel appearanceWhenContainedIn:[UITextField class], nil];
}
placeholderAppearance.textColor = [UIColor redColor];
[EDITED]
After using this I got to know another bug, the above did the job but it also reset the color of all other labels in my view to Default Black. Then to overcome this, I had to sub class the UILabel class and use my class in all other labels in my view.
See drawPlaceholderInRect: of UITextField. You need to subclass UITextField and override this method for configuring graphics context with desired text color and call super implementation.
By the time this method is called, the current graphics context is
already configured with the default environment and text color for
drawing. In your overridden method, you can configure the current
context further and then invoke super to do the actual drawing or do
the drawing yourself. If you do render the text yourself, you should
not invoke super.
From iOS6 you can use the attributed placeholder:
textfield.attributedPlaceholder = [[NSAttributedString alloc] initWithString:textfield.placeholder attributes:#{NSForegroundColorAttributeName: [UIColor redColor]}];
I'm trying to add subviews to a UIButton. This is working fine right now. But the button isn't clickable anymore as soon as I add the subviews.
I use the following code:
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(column*100+24, row*80+10, 64, 64);
[button addSubview:asyncImage];
[button addSubview:price];
[button addTarget:self
action:#selector(buttonClicked:)
forControlEvents:UIControlEventTouchUpInside];
The button works again if I remove the 2 addSubview: methods. If anyone knows how to fix this it would be great!
I found a quick solutions. I needed to set the asyncImageView to the following:
asyncImage.userInteractionEnabled = NO;
asyncImage.exclusiveTouch = NO;
After this, it worked!
try:
[UIButton buttonWithType:UIButtonTypeCustom];
instead of:
[UIButton buttonWithType:UIButtonControlType];
The important thing here is to make sure that userInteractionEnabled will be set to NO. Fortunately it works immediately for UIImageView and UILabel (maybe for other subclasses of a UIView but those are the most popular subviews added to button) because by default for this classes it is set to NO by default. Unfortunately it is set to YES in UIView so make sure to change it in that case. Messing around with any other flags shouldn't be necessary. The nature of problem is that many people do not know that default value of this flag is different in subclasses.
Have you tried to put:
[asyncImage setUserInteractionEnabled:YES];
in the same sitiation i make this action:
inherit from UIButton and add all labels and imageview's of button to self, finally put new button to view as last subview and add targets of self button to this last button(also set backgroundColor to clearColor for transparent). now it will be clickable and works fine.
In Swift, test that is you have your UIButton blocked
uibtn.userInteractionEnabled = false
uibtn.exclusiveTouch = false
I added a label to the subview button.
For a very long time I was looking for why my text in the button is not clickable. Solution in this thread:
myLable.isUserInteractionEnabled = false
I want to know if it is possible to subclass UIButton someway to add another component to it such as a preloader or progress indicator.
In pseudo code what I have in mind is something like the following.
UIButtonWithProgress *button =[[UIButtonWithProgress alloc]init]
[button.progressbar setProgress:50%]
In iOS the class for a progress bar is UIProgressView. If you really wanted to add a UIButton to a UIProgressBar (as in the question title). Then you can use the UIView method addSubView: For example:
UIButtonWithProgress* button = [[UIButtonWithProgress alloc] init];
UIProgressView* progressView = [[UIProgressView alloc] init];
[button addSubview:progressView];
progressView.progress = 0.5;
I think what you really want to do is create your own UIControl (so you should subclass that instead). You can override the method drawRect: to use quartz to draw your own progress bar animation, and the touchesBegan:withEvent: to detect the user tapping on your custom control, as well as adding any other methods you wish to control the state of the control (such as the progress level).
Note: In my code example I also give an example of correctly setting the progress of the UIProgressBar, just in case you were unclear.