Text not visible in circular UIButton iOS - ios

I am adding a circular UIButton like this:
-(void)addInfoButton
{
UIButton *pButton = [UIButton buttonWithType:UIButtonTypeCustom];
[pButton addTarget:self
action:#selector(infoButtonDidTap:)
forControlEvents:UIControlEventTouchUpInside];
pButton.frame = [self getInfoButtonFrame];
pButton.clipsToBounds = NO;
//half of the width
pButton.layer.cornerRadius = BUTTON_HEIGHT/2.0f;
pButton.layer.borderColor = self.tintColor.CGColor;
pButton.layer.borderWidth = 2.0f;
pButton.titleLabel.text = #"F";
pButton.titleLabel.textColor = self.tintColor;
pButton.titleLabel.textAlignment = NSTextAlignmentCenter;
self.filterInfoButton = pButton;
[self addSubview:pButton];
}
The text "F" is not visible when the button gets displayed. What could be the reason?
Edit:
On setting the corner radius as 0, the text is visible. But then, the button is not circular.

You set the title of a UIButton using
- setTitle:forState:
Sets the title to use for the specified state.
Using the attribute titleLabel does not set the text it is used to customize the button's title label.
titleLabel
A view that displays the value of the currentTitle property for a button. (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:
button.titleLabel.font = UIFont.systemFontOfSize(12)

Related

UISegmentController title text is cutting weirdly

see above attached image.
It's programatically written in Objective-C. UISegmentController is cutting title text.
Weird thing is, it shows 'Privacy Policy' full text which is way longer than 'About' and 'Terms', which is cutting.
Can anybody please help in this?
code is given below:
UISegmentedControl *unitsPicker = [[UISegmentedControl alloc] initWithItems:#[#"About", #"Terms", #"Privacy Policy"]];
unitsPicker.frame = CGRectMake(0, CGRectGetMaxY(unitsLabel.frame) + kBottomPaddingConstant, CGRectGetWidth(_unitsContainer.frame), segmentHeightConstant);
unitsPicker.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
unitsPicker.selectedSegmentIndex = ![TemperatureUtility unitIsCelsius];
[unitsPicker addTarget:self action:#selector(onUnitPickerChanged:) forControlEvents:UIControlEventValueChanged];
unitsPicker.layer.cornerRadius = 5.0f;
unitsPicker.layer.borderColor = [UIColorFromRGB(0xE9E9E9) CGColor];
unitsPicker.layer.borderWidth = 1.0f;
unitsPicker.layer.masksToBounds = YES;
unitsPicker.clipsToBounds = YES;
[_unitsContainer addSubview:unitsPicker];
Try setting:
segmentedControl.apportionsSegmentWidthsByContent = YES;
From the docs:
If the value of this property is true, for segments whose width value is 0, the control attempts to adjust segment widths based on their content widths.
The default is false.
Swift 5 and 5+ Solution
Add
mySegmentController.apportionsSegmentWidthsByContent = true
inside viewDidLoad() {}

UIScrollView not scrolling when adding UIButtons as subviews

I'm trying to build a simple UIScrollView with paging to horizontally scroll between 3 images.
The tricky part is that I would like that each image would be clickable and catch the click event.
My technique is to create 3 UIButtons that each consists UIImage. give each button a tag and set an action.
Problem: I can catch the click event - BUT it's not scrollable!
Here is my code:
- (void) viewDidAppear:(BOOL)animated {
_imageArray = [[NSArray alloc] initWithObjects:#"content_01.png", #"content_02.png", #"content_03.png", nil];
for (int i = 0; i < [_imageArray count]; i++) {
//We'll create an imageView object in every 'page' of our scrollView.
CGRect frame;
frame.origin.x = _contentScrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = _contentScrollView.frame.size;
//
//get the image to use, however you want
UIImage* image = [UIImage imageNamed:[_imageArray objectAtIndex:i]];
UIButton* button = [[UIButton alloc] initWithFrame:frame];
//set the button states you want the image to show up for
[button setImage:image forState:UIControlStateNormal];
[button setImage:image forState:UIControlStateHighlighted];
//create the touch event target, i am calling the 'productImagePressed' method
[button addTarget:self action:#selector(imagePressed:)
forControlEvents:UIControlEventTouchUpInside];
//i set the tag to the image #, i was looking though an array of them
button.tag = i;
[_contentScrollView addSubview:button];
}
//Set the content size of our scrollview according to the total width of our imageView objects.
_contentScrollView.contentSize = CGSizeMake(_contentScrollView.frame.size.width * [_imageArray count], _contentScrollView.frame.size.height);
_contentScrollView.backgroundColor = [ENGAppDelegate backgroundColor];
_contentScrollView.delegate = self;
}
Well, since UIButton is an UIControl subclass, it "eats up" the touches of your scroll view:
[UIScrollView touchesShouldCancelInContentView:] The default returned value is YES if view is not a UIControl object; otherwise, it returns NO.
(from https://developer.apple.com/library/ios/documentation/uikit/reference/UIScrollView_Class/Reference/UIScrollView.html#//apple_ref/occ/instm/UIScrollView/touchesShouldCancelInContentView:)
You could influence this by subclassing UIScrollView and overwriting touchesShouldCancelInContentView: (and/or touchesShouldBegin:withEvent:inContentView:). However, for your use case I'd not use buttons in the first place. Why not just add a tap gesture recognizer to the scrollview and use the touch point to determine which image has been tapped? That's much easier and should work without any issues.
This completely solved this issue for me:
scrollview.panGestureRecognizer.delaysTouchesBegan = YES;
Credit goes to https://stackoverflow.com/users/904365/kjuly for providing the right answer in this topic: ScrollView/TableView with UIControl/UIButton subviews not scrollable under iOS 8

Change Color of MPVolumeView Route Button iOS 7

I am designing a Music app for iOS 7 and I want to put the "AirPlay" route selector button directly in my app. I am able to get the button placed just fine, however it doesn't show up because the icon is white and my background is white.
Is there a way to change the color of the Route Button?
Here is the code I'm using to create the button.
self.airPlayButton = [[MPVolumeView alloc] initWithFrame:CGRectZero];
self.airPlayButton.showsVolumeSlider = NO;
[self.airPlayButton sizeToFit];
self.airPlayButton.backgroundColor = [UIColor myGreenColor];
[self addSubview:self.airPlayButton];
Basically the picture below is what I want, except I want the icon green instead of just it's background.
in reviewing Adams answer I like more clarity in that task. So I safe-guarded that code a bit:
Objective-C:
for( UIView *wnd in volumeView.subviews ) {
if( [wnd isKindOfClass:[UIButton class] ]) {
UIButton *button = (UIButton*) wnd;
UIImage *img = button.currentImage;
UIImage *img2 = [img imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[volumeView setRouteButtonImage: img2 forState:UIControlStateNormal];
break;
}
}
Swift:
for view in volumeView.subviews {
if view.isKindOfClass(UIButton) {
let buttonOnVolumeView : UIButton = view as! UIButton
volumeView.setRouteButtonImage(buttonOnVolumeView.currentImage?.imageWithRenderingMode(.AlwaysTemplate), forState: .Normal)
break;
}
}
Now it reacts on the tintColor property of volumeView and if Apple decides to add another button or change the sequence this code will still work.
To expand on lanbo's answer, you can also get the original image of the Route Button and create a copy that uses the UIImageRenderingMode.AlwaysTemplate rendering mode. That way it heeds the current tintColor.
In Swift:
let volumeView = MPVolumeView()
if let routeButton = volumeView.subviews.last as? UIButton,
let routeButtonTemplateImage = routeButton.currentImage?.imageWithRenderingMode(.AlwaysTemplate)
{
volumeView.setRouteButtonImage(routeButtonTemplateImage, forState: .Normal)
}
Create your own image and Try
setRouteButtonImage:forState:
Assigns a button image to the specified control states.
- (void)setRouteButtonImage:(UIImage *)image forState:(UIControlState)state
Parameters
image - The image to associate with the specified states.
state - The control state with which to associate the image.
Discussion
Use this to customize the appearance of the route button when it is enabled, disabled, highlighted, and so on.
Available in iOS 6.0 and later.

AutoResizing a button based on title text content

So I have a strange issue which could be a bug or me being stupid.
I have a button in a cell. The cell shows the logged in users facebook friends. If they are already a user of the app it shows the button as Play, else it shows Invite Me...
UIButton *playButton = (UIButton *)[cell.contentView viewWithTag:30];
playButton.backgroundColor = [UIColor clearColor];
[playButton setBackgroundImage:[[UIImage imageNamed:#"fbCell_Invite_30h"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 5, 15, 5)] forState:UIControlStateNormal];
playButton.titleLabel.text = #"Invite me";
if ([self.fbFriendsUsingApp containsObject:[friend valueForKey:#"id"]]) {
playButton.titleLabel.text = #"Play";
}
This all works fine and not an issue. However, when the button text is invite me it shows as this:
In storyboard interface builder the button is setup like this:
What is strange is that if I click the middle arrow <------> to make the width stretch, the title text stops working and they all show 'Play' ???
Try setting the text of the button using
[playButton setTitle:#"Invite Me" forState:UIControlStateNormal];
instead of
playButton.titleLabel.text = #"Invite Me;
I've found that if I don't use the first approach above the changes to the button text don't show up.
You can find the size of the NSString that you are setting as the button label and then resize the button accordingly:
CGSize labelSize = [labelString sizeWithFont:[UIFont systemFontOfSize:12]];
[button setFrame:CGRectMake(10,0,labelSize.width, labelSize.height)];
You will probably want to add a little to the CGSize as padding, but play with it and find the result you desire.

iOS UIButton with multiple labels

I have a UI button that I'd like to put two labels on it, similar to how a cell has a title text and detail text.
I'd like the button to have a larger font for the main text, and have smaller detail text under that.
Is this possible? I've tried to put multiple lines on a button, but I need to have different text sizes for each line, so setting the lineBreakMode and numberOfLines of the titleLabel doesn't really quite work.
Here's the code we finally used. Assistance from John Wang.
Thanks to everyone for the suggestions!
// Formats a label to add to a button. Supports multiline buttons
// Parameters:
// button - the button to add the label to
// height - height of the label. usual value is 44
// offset - the offset from the top of the button
// labelText - the text for the label
// color - color of the text
// formatAsBold - YES = bold NO = normal weight
// tagNumber - tag for the label
- (void) formatLabelForButton: (UIButton *) button withHeight: (double) height andVerticalOffset: (double) offset andText: (NSString *) labelText withFontSize: (double) fontSize withFontColor: (UIColor *) color andBoldFont:(BOOL) formatAsBold withTag: (NSInteger) tagNumber {
// Get width of button
double buttonWidth= button.frame.size.width;
// Initialize buttonLabel
UILabel *buttonLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, offset, buttonWidth, height)];
// Set font size and weight of label
if (formatAsBold) {
buttonLabel.font = [UIFont boldSystemFontOfSize:fontSize];
}
else {
buttonLabel.font = [UIFont systemFontOfSize:fontSize];
}
// set font color of label
buttonLabel.textColor = color;
// Set background color, text, tag, and font
buttonLabel.backgroundColor = [UIColor clearColor];
buttonLabel.text = labelText;
buttonLabel.tag = tagNumber;
// Center label
buttonLabel.textAlignment = UITextAlignmentCenter;
// Add label to button
[button addSubview:buttonLabel];
[buttonLabel autorelease];
} // End formatLabelForButton
A trick I would recommend is putting a UIButton with a transparent interior on top of UILabels. I've used this trick before and, although it may present some problems in terms of maintenance and i18n, it works like a charm.
Here is a 5 minutes sample using the suggestion above.
Given more time, you can make a better label with round corners.
you should be able to add subviews to it. Since everything is a view, everything can potentially have subviews.
I would subclass it and put the labels on it within the subclass, Then you can extend properties for text and subtext to change their values.
Not saying it can 100% work. But off the top of my head. UIView can have SubViews

Resources