A button can be added by:
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
myButton.frame = CGRectMake(100, 100, 160, 50);
[myButton setTitle:#"click me" forState:UIControlStateNormal];
[self.view addSubview:myButton];
but can we go with the initWithFrame method:
UIButton *myButton2 = [[UIButton alloc] initWithFrame:CGRectMake(100, 300, 160, 50)];
//myButton2.buttonType = UIButtonTypeRoundedRect;
myButton2.titleLabel.text = #"click me";
[self.view addSubview:myButton2];
but line 2 above is commented out because it causes an error for a "read only" property, and with that line commented out, still no button shows up at all... can a UIButton be added if using initWithFrame to begin with?
(update: I set a yellow background to see the view's area, and found that the label text of button 2 actually shows up as "click me" in white... but touching it has no visual effect... so I wonder how to change code sample 2 to make it work...)
Yes of course it can. I got into a little bit of a discussion as to that readonly buttonType property a while back. The general concensus is that there is neither a safe way, nor a good reason, for anyone to switch the type of a button. And besides, +buttonWithType returns an instance of UIButton just as well as +Alloc and -init do, so it isn't a problem.
Related
I have seen a bunch of similar questions, but noone got the answer I am looking for. When I use this code to make a UIButton and set it's titleLabel, the UIButton appear, but the titleLabel won't appear.
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
[button setBackgroundImage:[UIImage imageNamed:#"button.png"] forState:UIControlStateNormal];
button.titleLabel.text = #"Title";
button.titleLabel.font = [UIFont fontWithName:#"System-Bold" size:25.0f];
[self.view addSubview:button];
This code displays the button, but not the titleView, it's title. Why can that be? I am developing for iOS 6 and higher.
NOTE 1: I am not looking for an option like this:
[button setTitle:#"Title" forState:UIControlStateNormal];
Because I have to use the titleLabel to set it's font and fontSize.
NOTE 2: I can't create a UILabel and add it as a subView of the button. Since the button is later animating.
You always need to specify ControlState when updating button's title!
There are four possible values for UIButtons:
UIControlStateNormal
UIControlStateHighlighted
UIControlStateDisabled
UIControlStateSelected
so for example:
[button setTitle:#"Title" forState:UIControlStateNormal];
and then you can set custom settings for titleLabel:
[button.titleLabel setFont:[UIFont fontWithName:#"Zapfino" size:20.0]];
[button.titleLabel setTextColor:[UIColor blueColor]];
[button setTitle:#"Title" forState:UIControlStateNormal];
Is the correct way to set the title string.
titleLabel is used to set the font and color.
Try using...
[button setNeedsLayout];
[button layoutIfNeeded];
It will force button to update the layout.
If in the storyboard with a custom button image from assets like me
Check-in Attribute inspector
Check-in Attribute inspector set asset image as a background
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 = NSLineBreakByTruncatingTail;
Do not use the label object to set the text color or the shadow color. Instead, use the setTitleColor(:for:) and setTitleShadowColor(:for:) methods of this class to make those changes. To set the actual text of the label, use setTitle(_:for:) (button.titleLabel.text does not let you set the text).
The titleLabel property returns a value even if the button has not been displayed yet. The value of the property is nil for system buttons.
in swift :
button.setTitle("your text", for: .normal)
button.setTitleColor(.white, for: .normal)
TLDR - try this saveButton.titleLabel?.layer.zPosition = 10
This was a frustrating one for me. I created a UIButton programmatically, added constraints, and added a gradient background (this is what caused my problem...I think). Then I needed to update the font:
saveButton.titleLabel?.font = UIFont.systemFont(ofSize: 20, weight: .semibold)
saveButton.setTitle("Save", for: .normal)
Notice I'm setting the title in the correct way. But still, no title showing. The craziest part - when I clicked "Debug View Hierarchy" I could see the title right there! If I didn't change the font, the title showed as well. Confusing. Then I added this (literally flinging spaghetti and seeing what stuck):
saveButton.titleLabel?.layer.zPosition = 10
It worked. It seems like some combination of gradient background, setting the font, etc was putting the button's internal title label at the bottom of its layers.
I have a tableview that contains a row with a custom cell that contains a UIButton. However, the button doesn't always fire the action. Here's my code:
submitButton = [[UIButton alloc] init];
[[submitButton layer] setBorderColor:[[UIColor whiteColor] CGColor]];
[submitButton setClipsToBounds: YES];
submitButton.backgroundColor = [UIColor grayColor];
[submitButton setTitle:#"Send" forState:UIControlStateNormal];
[self.contentView addSubview:submitButton];
[submitButton addTarget:self action:#selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
[submitButton release];
This is called in the custom cell's -(id)initWithStyle:
The buttonAction method looks like this:
-(void)buttonAction
{
NSLog(#"Button Clicked!");
}
It seems that the only way I can get the buttonAction to fire is if I press down on the button and release somewhere inside the cell's frame, but not inside the button itself. Why would that be?
*UPDATE*
Problem still exists, but I found that the more consistent way to get the button to fire is to click and drag to the left or right and then let go, as long as I let go within the bounds of the cell/row.
UPDATE #2
It looks like if I use iOS 6.0, it works as intended. But on 5.0 or 5.1 it does not.
Try assigning the same method call to TouchUpOutside as well - you should then see it work every time. TouchUpInside is only fired if you lift your finger while still within the bounds of the button.
Try [submitButton sizeToFit]. I'm wondering whether your button has any size (since I don't see you giving it any).
Also: Create your button with [UIButton buttonWithType: UIButtonTypeCustom] instead of alloc-init.
something strange happened during the development of my app. I have a view with several UIButtons in it. All are using custom artwork and are UIButton with CostumType.
For me everything felt right. In the simulator and on the phone.
But when I give the app in someone else's hand the person taps on a button and it won't work. It feels like the button is just reaction to a certain tap which in fact doesn't feel right (if you compare it to normal behavior).
What can I do to make it behave normal? Normal means that somebody who is used to iOS Apps can use it like he except it works.
Here is an example code for a button:
focusButton = [UIButton buttonWithType:UIButtonTypeCustom];
[focusButton setFrame:CGRectMake(self.bounds.size.width-(self.bounds.size.width/widthFactor)+108, self.bounds.origin.y+(self.bounds.size.height/(heightFactor*2))+2, 36, 40)];
focusButton.contentHorizontalAlignment = false; // I think these lines doesn't effect the behavior
focusButton.contentVerticalAlignment = false;
[focusButton setBackgroundImage:[UIImage imageNamed:#"arrowUp.png"] forState:UIControlStateNormal];
[focusButton setBackgroundImage:[UIImage imageNamed:#"arrowUpH.png"] forState:UIControlStateHighlighted];
[focusButton addTarget:self action:#selector(focusOrDefocusCourse) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:focusButton];
The Button Background looks like this:
this is woking fine.. Once just test with the frame..
UIButton *btn_foucs = [UIButton buttonWithType:UIButtonTypeCustom];
[btn_foucs setFrame:CGRectMake(20, 20, 200, 40)];
[btn_foucs setImage:[UIImage imageNamed:#"btn_erase.png"] forState:UIControlStateNormal];
[btn_foucs setImage:[UIImage imageNamed:#"btn_erase_h.png"] forState:UIControlStateHighlighted];
[self.view addSubview:btn_foucs];
You may like to take a look at the UIButton property imageEdgeInsets. This allows you to make the image draw into only part of the frame, so that the touchable area is bigger than the image itself (reducing the chance of 'missing' the button). You could do the following, for example:
int touch_offset = 10;
[focusButton setFrame:CGRectMake(self.bounds.size.width-(self.bounds.size.width/widthFactor)+108-touch_offset, self.bounds.origin.y+(self.bounds.size.height/(heightFactor*2))+2-touch_offset, 36+(touch_offset*2), 40+(touch_offset*2))];
focusButton.imageEdgeInsets = UIEdgeInsetsMake(touch_offset, touch_offset, touch_offset, touch_offset);
This should make the touchable area 10 pixels wider than the image on each side, adjustable by changing the touch_offset value. As a general guideline, Apple recommend using touchable areas no smaller than 44x44 pixels.
I am developing a Universal app, and there is a UIButton in it which works fine with iPhone but when I click it in iPad it requires many click attempts to get the touch event occur.
e.g. after 5-6 clicks it executes click event.
Below is UIButton code. Please help.
UIView *footer = [[[UIView alloc] initWithFrame:(CGRectMake(0, 0, self.tableView.frame.size.width, 54))] autorelease];
float buttonWidth = (int)((self.tableView.frame.size.width - 12 - 12) / 3);
float buttonHeight = 44;
if (clientState.Devicetype == 1) // 1=Ipad
buttonHeight = 90;
cash = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
cash.frame = CGRectMake(6, 10, buttonWidth, buttonHeight);
[cash setTitle:#"Cash" forState:UIControlStateNormal];
[cash setTitleColor:[UIColor lightGrayColor] forState:UIControlStateDisabled];
[cash addTarget:self action:#selector(handleCash:) forControlEvents:UIControlEventTouchUpInside];
cash.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin;
if (clientState.Devicetype == 1) // 1=Ipad
{
cash.titleLabel.font = [UIFont systemFontOfSize:28];
}
[footer addSubview:cash];
self.tableView.tableFooterView = footer;
You should check to make sure that your buttons are the correct size:
[cash sizeToFit]
I've experienced that if some other view is blocking it (and you click on that part of your button it won't fire off the event) it will take several clicks because you eventually press the button where it's not being covered. So make sure no other frame/bounds is over the top of your button and make sure your button is sized correctly.
I agree with #Inturbidus that it's probably another transparent view covering part of the button. I find the best way to troubleshoot this is to change the background color on all my other views (scrollviews, etc) to make sure they are behaving like I think they are. Sometimes it will surprise you when you see where they are actually positioned with background color turned on.
I receive some JSON from the net and based on that data, I must create 2 or 3 buttons. Part of my gui is static and created in NIB (won't change), only the number of buttons will change. I found this code for making buttons in code:
//create the button
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//set the position of the button
button.frame = CGRectMake(100, 170, 100, 30);
//set the button's title
[button setTitle:#"Click Me!" forState:UIControlStateNormal];
Is this the right way? In which method of my viewcontroller should I put this code?
You can add the button whenever you want, as long as the view has been loaded already. The one thing you'd need to add to the above code is
[[self view] addSubview:button];
Using this code, you have a button on the screen, but it won't be able to trigger any actions. You'll probably also want to add:
[button addTarget:self action:#selector(someMethod:) forControlState:UIControlEventTouchUpInside];
You should add the buttons in the delegate/method that parses the JSON data.
Don't forget to add the created buttons to your view:
[containerView addSubview:button];