Styling a button that was created in interface builder - ios

If you have a button that was created in Interface Builder and already points to another viewController how do you target that button in code to give it a custom background for normal and selected state in code?
UIImage *registerButtonNormal = [[UIImage imageNamed:#"yellowRegisterButton"]resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
[self.registerButton setBackgroundImage:registerButtonNormal forState:UIControlStateNormal];
UIImage *registerButtonSelected = [[UIImage imageNamed:#"yellowRegisterButtonSelected"]resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
[self.registerButton setBackgroundImage:registerButtonSelected forState:UIControlStateSelected];

This is actually really easy.
You just have to create a #property and connect the button you want to style by control dragging from the button to the newly created property.
The property should look something like this:
#property (nonatomic, strong) IBOutlet UIButton *registerButton;
Then in the viewDidLoad, you put the above code that targets your button:
- (void)viewDidLoad
{
[super viewDidLoad];
// code for styling button goes here.
}
You can see the code for styling the button in the question.

Related

How to put text on left and right side of UIButton

I am new to iOS development and I recently got stucked with a problem where I am not able to set text on both sides of a button. Also I wish to add multi-line text in a button (as shown below). I have gone through lot of answers but none of them satisfied my requirement.
Any suggestion or help would greatly be appreciated, thanks!
You should definitely go with a custom UIButton class. The reason for this is that UIButton has other properties that you will want, like being recognized by iOS as a button, conform to Accessibility as a button, show up in storyboard as a button class, let your co-workers see that it actually is a button, have same/similar interface as a button, and so on.
Creating a custom button isn't that hard. Basically, just sub-class UIButton and implement awakeFromNib to set up the internals and layoutSubviews to position and size everything.
Here is an outline of how to do it...
1. Create a UIButton sub-class (.h)
Add the custom interface to the header file. It could look something like this.
#interface MyButton : UIButton
- (void)setServiceText:(NSString *)serviceText;
- (void)setPriceText:(NSString *)priceText;
- (void)setTimeText:(NSString *)timeText;
#end
2. Add controls to hold the internals of your button (.m)
The three labels and a view to use as the red sidebar. From here on you add to the code file.
#interface MyButton ()
#property (strong, nonatomic) UILabel *serviceLabel;
#property (strong, nonatomic) UILabel *priceLabel;
#property (strong, nonatomic) UILabel *timeLabel;
#property (strong, nonatomic) UIView *redSideBarView;
#end
3. Add code corresponding to the interface (.m)
Since UILabel redraws itself when we set the text property, we do not need to do more to make it appear on the button.
- (void)setServiceText:(NSString *)serviceText {
_serviceLabel.text = serviceText;
}
- (void)setPriceText:(NSString *)priceText {
_priceLabel.text = priceText;
}
- (void)setTimeText:(NSString *)timeText {
_timeLabel.text = timeText;
}
4. Implement awakeFromNib (.m)
This method will be called when Storyboard instantiate your button, so here is a good place to create your labels and do other stuff that only needs to be done once.
- (void)awakeFromNib {
[super awakeFromNib];
_sideBarView = [[UIView alloc] initWithFrame:CGRectZero];
_sideBarView.backgroundColor = [UIColor redColor];
[self addSubview:_sideBarView];
_serviceLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_serviceLabel.font = [UIFont systemFontOfSize:18.0];
[self addSubview:_serviceLabel];
_priceLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_priceLabel.textColor = [UIColor greenColor];
_priceLabel.font = [UIFont systemFontOfSize:16.0];
_priceLabel.textAlignment = NSTextAlignmentRight;
[self addSubview:_priceLabel];
_timeLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_timeLabel.font = [UIFont systemFontOfSize:14.0];
[self addSubview:_timeLabel];
self.clipsToBounds = YES;
}
5. Add code to layout your button (.m)
This is the final piece of the custom button code. Note that layoutSubviews will usually be called several times during the controls lifetime, so do not add sub-views here. Use it to position and size the internals of your button. self.bounds.size represents the current size of your button, so this is a good reference for all other elements.
- (void)layoutSubviews {
// Layout sub-elements
CGFloat buttonWidth = self.bounds.size.width;
CGFloat buttonHeight = self.bounds.size.height;
_serviceLabel.frame = CGRectMake(30.0, 2.0, buttonWidth * 0.7, buttonHeight * 0.5);
_priceLabel.frame = CGRectMake(buttonWidth - 40, 5.0, 30.0, buttonHeight * 0.4);
_timeLabel.frame = CGRectMake(30.0, buttonHeight * 0.5, buttonWidth * 0.7, buttonHeight * 0.4);
_sideBarView.frame = CGRectMake(0.0, 0.0, 10.0, buttonHeight);
self.layer.cornerRadius = 10.0;
}
6. Use it!
To use it you create a regular button in Storyboard, then in the Identity Inspector, select your new button class. As usual, tie the button to a variable in your view controller class. The variable should be of your button class, of course. That's it for the design!
#property (weak, nonatomic) IBOutlet MyButton *button;
Now don't forget to set the properties.
self.button.backgroundColor = [UIColor lightGrayColor];
[self.button setServiceText:#"FULL SERVICE HAIRCUT"];
[self.button setPriceText:#"$30"];
[self.button setTimeText:#"30 minutes"];
A couple of things I didn't address here was the gradient and the drop shadow. The gradient is probably best done with a CAGradientLayer added to the button's view's layer. The drop shadow needs a bit more coding, since you are clipping the button to have rounded corners. Probably you need to add one more UIView in between to contain everything that you then clip, and then add shadow to the button view.
I wouldn't go with a UIButton but with a UIView with Labels from Xib. Tutorial on that can be found here: link.
Then you may add a target to your UIView, so that when tapping it will call some method (as would UIButton do):
yourView.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(buttonTapped))
yourView.addGestureRecognizer(tap)
And method:
#objc func buttonTapped() {
// do what you need on tap here
}
Hope it helps! Please comment if you have questions.
PS. I'm not sure but from what I see you are probably building a UITableView. is it? Can you please show a design of the full screen? If you have many "buttons" like that then it's not a single "button" but a Table View.
To display multiple lines use below code
button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.numberOfLines = 2; // or 0(Zero)
And you need to add UIView and add tap gesture to that view and design that view like above image.
For Gestures
//Create tap gustures for view
UITapGestureRecognizer *viewTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(onClickView:)];
[self.yourViewName addGestureRecognizer: viewTap];
- (void) onClickView:(UITapGestureRecognizer *)recognizer {
//Write your code
}
This is one approach.
And second one is...
For this use UITableViewCell and design that cell.
This is second approach.

Create Checkbox using Storyboard in Xcode

I am new to Objective-C so i am mostly using Storyboard, Someone Please tell me how to create a checkbox using Xcode in iOS.
UISwitch is the standard control used in iOS for indicating an on/off, selected/unselected state. Why not use that?
UISwitch is the standard control used in IOS applications for making binary choices but if you want to use checkbox you can create a UIButton
#property (weak, nonatomic) IBOutlet UIButton *CheckBox;
- (IBAction)CheckBoxClick:(id)sender
and change its background image on click event of UIButton
- (IBAction)CheckBoxClick:(id)sender {
if(!checked){
[_CheckBox setImage:[UIImage imageNamed:#"checked.png"] forState:UIControlStateNormal];
checked = YES;
}
else if(checked){
[_CheckBox setImage:[UIImage imageNamed:#"unchecked.png"] forState:UIControlStateNormal];
checked = NO;
}
}
also there are more detailed answers to this question at
How to create a simple checkbox in iOS?
and if you dont want to use images you can check the following
Checkbox in iOS application
CheckBox is not available in object library. You can use third party library for that purpose or you can create it by your self.
There is the working code for checkbox.
create a class level variable and property of button in #inteface
#interface testViewController (){
BOOL checkBoxSelected;
}
#property (weak, nonatomic) IBOutlet UIButton *checkBox;
#end
in viewdidload set images for the button states.
[_checkBox setBackgroundImage:[UIImage imageNamed:#"checkBoxUnChecked.png"]
forState:UIControlStateNormal];
[_checkBox setBackgroundImage:[UIImage imageNamed:#"checkBoxChecked.png"]
forState:UIControlStateSelected];
and after create a button action in that button Action.
checkBoxSelected = !checkBoxSelected; /* Toggle */
[_checkBox setSelected:checkBoxSelected];
Hope it helps
1) Create Prototype cell in UITableView.
2) Add one button inside the cell and set button style to Custom.
3) Set the image for checkbox.
ios language doesn't use checkbox controller.
but you are use checkbox that you are inport two image select & unselect
Step 1> Create button and set image.
Step 2> Create button touch object method and put if condition for check & uncheck.
for example:
- (IBAction)btnLogin:(id)sender {
UIButton *btn = (UIButton *)sender;
if (btn.tag == 0) {
btn.tag = 1;
//set image checked.
}
else{
btn.tag = 0;
//set image unchecked.
}
}
You shouldn't need to subclass the UIButton class. By design, Objective-C favors composition over inheritance.
UIButton is a subclass of UIControl, which has a selected property. You can use this property to toggle the on/off behaviour of a checkbox, just the same way a UISwitch does.
You can attach an action to the button's touched up inside event, and perform the toggling in there, something like this:
// when you setup your button, set an image for the selected and normal states
[myCheckBoxButton setImage:nonCheckedImage forState:UIControlStateSelected];
[myCheckBoxButton setImage:nonCheckedImage forState:UIControlStateNormal];
- (void)myCheckboxToggle:(id)sender
{
myCheckboxButton.selected = !myCheckboxButton.selected; // toggle the selected property, just a simple BOOL
}

Changing Button Text - Xcode 6

I'm currently developing my first app, and I'm having a bit of an issue. I've made a custom button using JavaScript, then by screenshotting I've been able to import it as a custom button into XCode. However, I'm unable to put any text on it; anything I do appears to the side. I've searched through other threads and found the following code:
[_Button setTitle:#"ClickMe!" forState:UIControlStateNormal];
However, this just causes text to appear to the side of the custom button. Can anyone help me fix this?
EDIT:
Here's my code in ViewController.h:
#property (strong, nonatomic) IBOutlet UIButton * RoadMap;
#property (weak, nonatomic) IBOutlet UILabel * myLabel;
And.. relevant code in ViewController.m
_myLabel.text=#"Road Map";
[_RoadMap removeFromSuperView];
[_RoadMap setBackgroundImage:[UIImage imageNamed:#"button.PNG"] forState:UIControlStateNormal];
Looks like you using foreground image for button.
Try to use background image:
[_Button setBackgroundImage:[UIImage imageNamed:#"imageName"] forState:UIControlStateNormal];
In this case text will rendered above the image.
Update:
Just remove these two lines of code:
_myLabel.text=#"Road Map";
[_RoadMap removeFromSuperView];
And add this line:
[_RoadMap setTitle:#"RoadMap" forState:UIControlStateNormal];

Displaying UIButton programmatically

I'm trying to display a button to the view programmatically with this code:
- (void)viewDidLoad {
_detailButton = [UIButton buttonWithType:UIButtonTypeCustom];
_detailButton.frame = CGRectMake(23, 294, 72, 37);
[_detailButton setTitle:#"UIButton!" forState:UIControlStateNormal];
[_detailButton addTarget:self
action:#selector(showPop:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_detailButton];
}
I have the button declared in the .h file like this:
#property (strong, nonatomic) UIButton *detailButton;
The code does not throw any errors or warnings, but when I run there is no button displayed.
I check your code in my project its working fine i think in your case there are some other view that cover this button so check that your code has no problem at all.
Your button probably covered by another view. Just make sure its on top of other views.
In viewWillAppear add the following line of code:
[self.view bringSubviewToFront:self.detailButton];
If your button's type is of UIButtonTypeCustom, the button's default title color is white, so you can't see it if your view's background color is white.
[_detailButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

UIButton image only changes for one button

I have written some code which toggles 2 buttons depending on which one is selected. If the UK one is selected it becomes ticked and the BR one becomes unticked, and vice versa. However, this only seems to be the case for the UK button. If I select the BR button than the UK button unticks, the BR button briefly ticks but then it unticks again.
I have linked up my buttons correctly (I have triple checked), and as the BR button briefly ticks it is definitely linked up. The code I am using is below:
.h
#property (weak) IBOutlet UIButton *btUK;
#property (weak) IBOutlet UIButton *btBR;
.m
- (IBAction)changePortal:(id)sender
{
UIButton *button = (UIButton *)sender;
if (button.tag == kUKButton)
{
self.btUK.imageView.image = [UIImage imageNamed:#"tick_box.png"];
self.btBR.imageView.image = [UIImage imageNamed:#"tick_box_empty.png"];
[Singleton sharedSingleton].bUseUKPortal = YES;
}
else if (button.tag == kBRButton)
{
self.btBR.imageView.image = [UIImage imageNamed:#"tick_box.png"];
self.btUK.imageView.image = [UIImage imageNamed:#"tick_box_empty.png"];
[Singleton sharedSingleton].bUseUKPortal = NO;
}
}
I have set break points within the code and have confirmed that both the buttons go in to their relevant sections when clicked. I can also confirm that no other code is using the btUK and btBR variables as I have just written it all.
Both buttons have changePortal set as their action, and the function is only called once per click.
I have also tried cleaning the code but this did not fix my issue.
If anyone can shed any light as to why this is happening then I would be very grateful.
The correct way to set the image of a UIButton is to call setImage:forState:.
So try to alter your code to something like this:
// Follow this pattern for every button image change
[self.btUK setImage:[UIImage imageNamed:#"tick_box.png"] forState:UIControlStateNormal];
Now regarding the imageView property the documentation states that:
The button’s image view. (read-only)
#property(nonatomic, readonly, retain) UIImageView *imageView
Discussion
Although this property is read-only, its own properties are
read/write. Use these properties to configure the appearance and
behavior of the button’s view. For example:
UIButton *button = [UIButton buttonWithType: UIButtonTypeRoundedRect];
button.imageView.exclusiveTouch = YES;
The imageView property returns a value even if the button has not been
displayed yet. The value of the property is nil for system buttons.

Resources