UIButton with different color text in each line - uibutton

I want to have a UIButton with two lines of text, with each line in different color. Is it possible to have like that ?

There are 2 Approaches I can think of :
Approach 1 (easy) : Make it as an image button
Approach 2 (hard) : Make a custom UIButton, with 2 separate UILabel, such that you can configure different colors for them
To achieve Approach 2, you first create a class with UIButton as superclass. Then, override - (void)drawRect method. In order not to repeat answer in SO, please read this: How to override -drawrect in UIButton subclass?

Hi this answer only applicable in above ios 6...
Use ios 6 's attributed text to achieve this...
NSString* infoString=#"This is an example of Attributed String";
NSMutableAttributedString *attString=[[NSMutableAttributedString alloc] initWithString:infoString];
NSInteger _stringLength=[infoString length];
UIColor *_red=[UIColor redColor];
UIFont *font=[UIFont fontWithName:#"Helvetica-Bold" size:20.0f];
[attString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, _stringLength)];
[attString addAttribute:NSForegroundColorAttributeName value:_red range:NSMakeRange(0, _stringLength/2)];
[self.attribButton setAttributedTitle:attString forState:UIControlStateNormal];
self.attribButton.titleLabel.numberOfLines=2;
Try like this...

In Swift
var main_string = "Hello World"
var string_to_color = "World"
var range = (main_string as NSString).rangeOfString(string_to_color)
var attributedString = NSMutableAttributedString(string:main_string)
attributedString.addAttribute(NSForegroundColorAttributeName, value: appSingleton.appRedColor , range: range)
self.celciusButton.setAttributedTitle(attributedString, forState: UIControlState.Normal)

yes sure..!!! make an image what you exactly want to show then set the image as an background of that button..! its simple...

First, make your button of "custom" type. If you need to do that programmatically:
UIButton* myButton = [UIButton buttonWithType: UIButtonTypeCustom];
myButton.frame = CGRectMake (x,y,width,height);
Now make your labels:
UILabel* line1 = [[UILabel alloc] initWithFrame:CGRectMake(0,0,buttonWidth,buttonHeight/2)];
UILabel* line2 = [[UILabel alloc] initWithFrame:CGRectMake(0,buttonHeight/2,buttonWidth,buttonHeight/2)];
And assign the text colors you want:
line1.textColor = [UIColor blueColor];
line2.textColor = [UIColor redColor];
Then add the labels to the button, and the button to your view:
[myButton addSubview:line1];
[myButton addSubview:line2];
[self.view addSubview:myButton]; // only if you've created the button programmatically

Related

Font change on selecting NSTextField

I am wanting to create a simple label with an attributed string. I do this like this:
NSDictionary *noNotificationsAttrs = [NSDictionary dictionaryWithObjectsAndKeys:centredStyle,
NSParagraphStyleAttributeName,
[NSFont fontWithName:#"Raleway-Bold" size:30],
NSFontAttributeName,
_grey,
NSForegroundColorAttributeName,
nil];
NSMutableAttributedString *noNotificationsString =
[[NSMutableAttributedString alloc] initWithString:#"No Notifications"
attributes:noNotificationsAttrs];
NSTextField* title_field = [[NSTextField alloc] initWithFrame:
CGRectMake(
0,
0,
200,
200
)
];
[title_field setWantsLayer:true];
[title_field setSelectable:YES];
[title_field setAllowsEditingTextAttributes:true];
[title_field setAttributedStringValue:noNotificationsString];
[title_field setEditable:false];
[title_field setBordered:false];
title_field.tag = 1;
Which turns out like this:
and
Unfortunately when clicking (selecting) this label it appears like this:
and
Which is a bit bolder and pixelated around the corners. This is happening with lots of other labels with different strings, sizes and colours. How can I fix it?!
Please note these labels are nested inside nsscrollview -> nstableview -> viewForTableColumn
Stack on selection:
I believe the problem is that NSCell calls an edit function on mousedown.
The font is also different on selection!!
Edit:
Interestingly if I remove wantslayer:YES from the (2) parent view it does not do this. But they both need wantslayer or else I can't have curved corners etc...
Add this line to your code.
NSTextView *textEditor = (NSTextView *)[[[NSApplication sharedApplication] keyWindow] fieldEditor:YES forObject:title_field];
[textEditor setSelectedTextAttributes:noNotificationsAttrs];
Thus adding the attributes to NSTextView associated with window while selection.
What you're getting now like bold and font changes after selection will get overrided.
Edit:
Working code
Have changed NSForegroundColorAttributeName to NSBackgroundColorAttributeName
and _grey to [NSColor clearColor]
NSDictionary *noNotificationsAttrs = [NSDictionary dictionaryWithObjectsAndKeys:centredStyle,
NSParagraphStyleAttributeName,
[NSFont fontWithName:#"Raleway-Bold" size:30],
NSFontAttributeName,
[NSColor clearColor],
NSBackgroundColorAttributeName,
nil];
To fix this I made a custom NSTextField where on select it updates like this:
- (void)textViewDidChangeSelection:(NSNotification *)a{
[self setNeedsDisplay:YES];
[self setNeedsLayout:YES];
[self.superview setNeedsLayout:YES];
[self.superview setNeedsDisplay:YES];
}
but still acts funny some times
This behaviour seems to be solved by allowing editing text attributes:
let textField = NSTextField()
textField.allowsEditingTextAttributes = true
textField.isSelectable = true

ios7 - how do I set uibutton title to superscript?

I have tried to use this question to create a UIButton that has a title of 2 squared.But I can't get it to work. What am I missing?
My code is virtually identical:
if (button.tag == 200)
[button setTitle: #"x\u00B3 + x\u00B2 + x\u00B9 + k" forState: UIControlStateNormal | UIControlStateHighlighted | UIControlStateSelected];
Thanks in advance
Refere Unicode Charactor it will make subscripts and superscripts
Click for Unicode reference
Here is an example,
for,
x² - U+00Bx2 -> X\u00B2
x³ - U+00Bx3 -> X\u00B3
x⁶ - U+207x6 -> X\u2076
, etc.....
[button setTitle:#"X\u00B2" forState:UIControlStateNormal];
[button setTitle:#"X\u00B3" forState:UIControlStateNormal];
[button setTitle:#"X\u2076" forState:UIControlStateNormal];
like that...
As of iOS 6, you can supply a button's label as anNSAttributedString. The kCTSuperscriptAttributeName attribute name sets the superscript level (negative values give subscripts as well). Note that you need to import CoreText/CTStringAttributes.h to get it.
#import <CoreText/CTStringAttributes.h>
// ...
NSMutableAttributedString *attributedTitle = [[NSMutableAttributedString alloc]initWithString:#"22"];
[attributedTitle addAttribute:(NSString*)kCTSuperscriptAttributeName value:#"1" range:NSMakeRange(1, 1)];
[button setAttributedTitle:attributedTitle forState:UIControlStateNormal];
Let me give you two approaches:
A) Use the character viewer to type in the superscript into an NSString literal.
The character viewers is normally next to the date in the menu bar.
Type the number you want into the search box. It will display under related characters the superscript version. Double click on that to insert.
If character viewer is not there, go to settings>Languages & Text>Input Sources and check "keyboard & character viewer"
B) Use an attributed string for the button label.
This is the general purpose solution for all formatting. It's more difficult but works for nearly everything.
I am getting the best results using a NSAttributedString.
Change font size for superscript text (using NSFontAttributeName).
Move superscript text up (using NSBaselineOffsetAttributeName).
Works for all types of fonts and all values of sub/superscript.
//input parameters
NSString *title = #"e";
NSString *superscript = #"x";
UIFont *font = [UIFont systemFontOfSize:20.0f];
//our buffer
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init];
//just append the title and set its font
[attributedString appendString:title];
NSRange titleRange = NSMakeRange(0, title.length);
[attributedString addAttribute:NSFontAttributeName
value:font
range:titleRange];
//append the superscript
[attributedString appendString:superscript];
NSRange superscriptRange = NSMakeRange(title.length, superscript.length);
//start of the important code - change font and move baseline of the superscript
[attributedString addAttribute:NSFontAttributeName
value:[font fontWithSize:(font.pointSize / 2.0f)]
range:superscriptRange];
[attributedString addAttribute:NSBaselineOffsetAttributeName
value:[NSNumber numberWithFloat:(font.ascender / 2.0f)]
range:superscriptRange];
//end of the important code
[button setAttributedTitle:attributedString forState:UIControlStateNormal];
Result:
Could you please use this code in place of title:
[NSString stringWithUTF8String:"foot\u00b2"];
This is working for me:
UIBarButtonItem *btnOffer=[[UIBarButtonItem alloc] initWithTitle:[NSString stringWithUTF8String:"foot\u00b2"] style:UIBarButtonItemStylePlain target:self action:#selector(btnOffer_clicked)];
self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:34.0/255.0f green:182.0/255.0f blue:226.0/255.0f alpha:1.0];
[self.navigationItem setRightBarButtonItem:btnOffer];

title of a custom button

I am creating a custom UIButton like this :
U
IButton *buttonDetailCarte = [UIButton buttonWithType:UIButtonTypeCustom];
buttonDetailCarte.frame = CGRectMake(8, 223, 304, 44);
[buttonDetailCarte setBackgroundImage:[UIImage imageNamed:#"cellule.png"] forState:UIControlStateNormal];
buttonDetailCarte.titleLabel.text = #" my Text";
buttonDetailCarte.titleLabel.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size:17];
buttonDetailCarte.titleLabel.textColor = [UIColor colorWithRed:84.0/255 green:84.0/255 blue:84.0/255 alpha:1.0f];
buttonDetailCarte.backgroundColor = [UIColor clearColor];
buttonDetailCarte.titleLabel.textAlignment = UITextAlignmentLeft;
the problem that my Text don't appear in my button and when i create the same button with IB, it appear ? what's the problem
You should use the setTitle:forControlState: method to change the button text, not manipulate the button's titleLabel directly.
Manipulating other properties of the titleLabel, as you are doing, is also no recommended. Try using the setTitleColor: instead. However, other properties like font of the titleLabel are fine to change. It's confusing at first but you get used to it!

How to programmatically add text to a UIView

I have a UIView that I'd like to add several bits of text to. I have used a UITextView but I think that's overkill as it doesn't need to be editable. I thought about using a UILabel or a UITextField, but I don't see how you tell the superview where to position the UILabel or UITextField within itself. I want the lowest footprint object that will let me put text of a font/color/size of my choosing in my UIView where I want it. Not too much to ask, eh?
The simplest approach for you would be:
UILabel *yourLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 20)];
[yourLabel setTextColor:[UIColor blackColor]];
[yourLabel setBackgroundColor:[UIColor clearColor]];
[yourLabel setFont:[UIFont fontWithName: #"Trebuchet MS" size: 14.0f]];
[yourSuperView addSubview:yourLabel];
Building or populating Views in your code will probably require you to use CGRectMake a lot.
As its name says, it creates a rectangle that you can use to set the relative position (relative to the borders of your superview) and size of your UIView-Subclass (in this case a UILabel).
It works like this:
yourLabel.Frame = CGRectMake(x, y, width, height); //x,y,width,height are float values.
x defines the spacing between the left hand border of the superview and the beginning of the subview your about to add, same applies to y but relating to the spacing between top-border of your superview.
then width and height are self-explanatory i think.
Hope this gets you on the track.
Instead of finding a way to tell the view where to position the UILabel, you can tell the UILabel where to position itself in the view by using "center".
E.g.
myLabel.center = CGPointMake(0.0, 0.0);
Hope you'll be able to use UILabel, for me it's the basic form of a flexible non editable text.
For Swift:
let yourLabel = UILabel(frame: CGRectMake(100, 100, 100, 100))
yourLabel.textColor = UIColor.whiteColor()
yourLabel.backgroundColor = UIColor.blackColor()
yourLabel.text = "mylabel text"
yoursuperview.addSubview(yourLabel)
This question is old, but for a pure UIView text option without using UILabel or UITextField (as all the other answers describe, but the question is how to do it without them), drawRect in a subclassed UIView works for me. Like so:
- (void)drawRect:(CGRect)rect{
NSString *string = #"Hello World!";
[string drawAtPoint:CGPointMake(100, 100) withFont:[UIFont boldSystemFontOfSize:16.0]];
}
This routine displays a text at a X-Y position
-(void)placeText:(NSString *)theText:(int)theX:(int)theY {
UILabel *textLabel;
// Set font and calculate used space
UIFont *textFont = [UIFont fontWithName:#"Helvetica" size:14];
CGSize textStringSize = [theText sizeWithFont:textFont constrainedToSize:CGSizeMake(300,50) lineBreakMode:NSLineBreakByTruncatingTail];
// Position of the text
textLabel = [[UILabel alloc] initWithFrame:CGRectMake(theX+OFFSETIMAGEX-(textStringSize.width/2), theY+OFFSETIMAGEY-(textStringSize.height/2), textStringSize.width,textStringSize.height)];
// Set text attributes
textLabel.textColor = [UIColor blackColor];
textLabel.backgroundColor = [UIColor orangeColor];
textLabel.font = textFont;
textLabel.text = theText;
// Display text
[self.view addSubview:textLabel];
}
It might be late but here is what I use:-
CGRect labelFrame = CGRectMake(120,300, 530, 100);
UILabel *myLabel = [[UILabel alloc] initWithFrame:labelFrame];
//If you need to change the color
[myLabel setTextColor:[UIColor whiteColor]];
//If you need to change the system font
[myLabel setFont:[UIFont fontWithName:NULL size:23]];
//If you need alignment
[myLabel setTextAlignment:NSTextAlignmentCenter];
// The label will use an unlimited number of lines
[myLabel setNumberOfLines:0];
//Add label view to current view
[self.view addSubview:myLabel];
NSString *someString = #"Sample String, Yarp!";
myLabel.text = someString;
add a UILabel to your View. then override the View's layoutSubviews method.

Is it possible to change a UIButtons background color?

This one has me stumped.
Is it possible at all to change the background color of a UIButton in Cocoa for iPhone.
I've tried setting the background color but it only changes the corners. setBackgroundColor: seems to be the only method available for such things.
[random setBackgroundColor:[UIColor blueColor]];
[random.titleLabel setBackgroundColor:[UIColor blueColor]];
This can be done programmatically by making a replica:
loginButton = [UIButton buttonWithType:UIButtonTypeCustom];
[loginButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
loginButton.backgroundColor = [UIColor whiteColor];
loginButton.layer.borderColor = [UIColor blackColor].CGColor;
loginButton.layer.borderWidth = 0.5f;
loginButton.layer.cornerRadius = 10.0f;
edit: of course, you'd have to #import <QuartzCore/QuartzCore.h>
edit: to all new readers, you should also consider a few options added as "another possibility". for you consideration.
As this is an old answer, I strongly recommend reading comments for troubleshooting
I have a different approach,
[btFind setTitle:NSLocalizedString(#"Find", #"") forState:UIControlStateNormal];
[btFind setBackgroundImage:[CommonUIUtility imageFromColor:[UIColor cyanColor]]
forState:UIControlStateNormal];
btFind.layer.cornerRadius = 8.0;
btFind.layer.masksToBounds = YES;
btFind.layer.borderColor = [UIColor lightGrayColor].CGColor;
btFind.layer.borderWidth = 1;
From CommonUIUtility,
+ (UIImage *) imageFromColor:(UIColor *)color {
CGRect rect = CGRectMake(0, 0, 1, 1);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
// [[UIColor colorWithRed:222./255 green:227./255 blue: 229./255 alpha:1] CGColor]) ;
CGContextFillRect(context, rect);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Don't forget to #import <QuartzCore/QuartzCore.h>
I assume you're talking about a UIButton with UIButtonTypeRoundedRect?
You can't change the background color of that. When you try changing it's background color you're rather changing the color of the rect the button is drawn on (which is usually clear).
So there are two ways to go. Either you subclass UIButton and overwrite its -drawRect: method or you create images for the different button states (which is perfectly fine to do).
If you set the background images in Interface Builder you should notice that IB doesn't support setting images for all the states the button can have, so I recommend setting the images in code like this:
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setBackgroundImage:[UIImage imageNamed:#"normal.png"] forState:UIControlStateNormal];
[myButton setBackgroundImage:[UIImage imageNamed:#"disabled.png"] forState:UIControlStateDisabled];
[myButton setBackgroundImage:[UIImage imageNamed:#"selected.png"] forState:UIControlStateSelected];
[myButton setBackgroundImage:[UIImage imageNamed:#"higligted.png"] forState:UIControlStateHighlighted];
[myButton setBackgroundImage:[UIImage imageNamed:#"highlighted+selected.png"] forState:(UIControlStateHighlighted | UIControlStateSelected)];
The last line shows how to set an image for the selected & highlighted state (that's the one IB can't set).
You don't need the selected images (line 4 & 6) if you're button dosn't need a selected state.
Another possibility:
Create a UIButton in Interface builder.
Give it a type 'Custom'
Now, in IB it is possible to change the background color
However, the button is square, and that is not what we want. Create an IBOutlet with a reference to this button and add the following to the viewDidLoad method:
[buttonOutlet.layer setCornerRadius:7.0f];
[buttonOutlet.layer setClipToBounds:YES];
Don't forget to import QuartzCore.h
Subclass UIButton and override setHighlighted and setSelected methods
-(void) setHighlighted:(BOOL)highlighted {
if(highlighted) {
self.backgroundColor = [self.mainColor darkerShade];
} else {
self.backgroundColor = self.mainColor;
}
[super setHighlighted:highlighted];
}
-(void) setSelected:(BOOL)selected {
if(selected) {
self.backgroundColor = [self.mainColor darkerShade];
} else {
self.backgroundColor = self.mainColor;
}
[super setSelected:selected];
}
My darkerShade method is in a UIColor category like this
-(UIColor*) darkerShade {
float red, green, blue, alpha;
[self getRed:&red green:&green blue:&blue alpha:&alpha];
double multiplier = 0.8f;
return [UIColor colorWithRed:red * multiplier green:green * multiplier blue:blue*multiplier alpha:alpha];
}
If you are not wanting to use images, and want it to look exactly like the Rounded Rect style, try this. Just place a UIView over the UIButton, with an identical frame and auto resize mask, set the alpha to 0.3, and set the background to a color. Then use the snippet below to clip the rounded edges off the colored overlay view. Also, uncheck the 'User Interaction Enabled' checkbox in IB on the UIView to allow touch events to cascade down to the UIButton underneath.
One side effect is that your text will also be colorized.
#import <QuartzCore/QuartzCore.h>
colorizeOverlayView.layer.cornerRadius = 10.0f;
colorizeOverlayView.layer.masksToBounds = YES;
Another possibility (the best and most beautiful imho):
Create a UISegmentedControl with 2 segments in the required background color in Interface Builder. Set the type to 'bar'. Then, change it to having only one segment. Interface builder does not accept one segment so you have to do that programmatically.
Therefore, create an IBOutlet for this button and add this to the viewDidLoad of your view:
[segmentedButton removeSegmentAtIndex:1 animated:NO];
Now you have a beautiful glossy, colored button with the specified background color.
For actions, use the 'value changed' event.
(I have found this on http://chris-software.com/index.php/2009/05/13/creating-a-nice-glass-buttons/). Thanks Chris!
Well I'm 99% percent positive that you cannot just go and change the background color of a UIButton. Instead you have to go and change the background images yourself which I think is a pain. I'm amazed that I had to do this.
If I'm wrong or if theres a better way without having to set background images please let me know
[random setBackgroundImage:[UIImage imageNamed:#"toggleoff.png"] forState:UIControlStateNormal];
[random setTitleColor:[UIColor darkTextColor] forState:UIControlStateNormal];
[random setBackgroundImage:[UIImage imageNamed:#"toggleon.png"] forState:UIControlStateNormal];
[random setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
Per #EthanB suggestion and #karim making a back filled rectangle, I just created a category for the UIButton to achieve this.
Just drop in the Category code: https://github.com/zmonteca/UIButton-PLColor
Usage:
[button setBackgroundColor:uiTextColor forState:UIControlStateDisabled];
Optional forStates to use:
UIControlStateNormal
UIControlStateHighlighted
UIControlStateDisabled
UIControlStateSelected
You can also add a CALayer to the button - you can do lots of things with these including a color overlay, this example uses a plain color layer you can also easily graduate the colour. Be aware though added layers obscure those underneath
+(void)makeButtonColored:(UIButton*)button color1:(UIColor*) color
{
CALayer *layer = button.layer;
layer.cornerRadius = 8.0f;
layer.masksToBounds = YES;
layer.borderWidth = 4.0f;
layer.opacity = .3;//
layer.borderColor = [UIColor colorWithWhite:0.4f alpha:0.2f].CGColor;
CAGradientLayer *colorLayer = [CAGradientLayer layer];
colorLayer.cornerRadius = 8.0f;
colorLayer.frame = button.layer.bounds;
//set gradient colors
colorLayer.colors = [NSArray arrayWithObjects:
(id) color.CGColor,
(id) color.CGColor,
nil];
//set gradient locations
colorLayer.locations = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0f],
[NSNumber numberWithFloat:1.0f],
nil];
[button.layer addSublayer:colorLayer];
}
add a second target for the UIButton for UIControlEventTouched and change the UIButton background color. Then change it back in the UIControlEventTouchUpInside target;
For professional and nice looking buttons, you may check this custom button component. You can use it directly in your views and tableviews or modify the source code to make it meet your needs. Hope this helps.
This isn't as elegant as sub-classing UIButton, however if you just want something quick - what I did was create custom button, then a 1px by 1px image with the colour I'd want the button to be, and set the background of the button to that image for the highlighted state - works for my needs.
I know this was asked a long time ago and now there's a new UIButtonTypeSystem. But newer questions are being marked as duplicates of this question so here's my newer answer in the context of an iOS 7 system button, use the .tintColor property.
let button = UIButton(type: .System)
button.setTitle("My Button", forState: .Normal)
button.tintColor = .redColor()
[myButton setBackgroundColor:[UIColor blueColor]];
[myButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
It's possible change this way or going on Storyboard and change background on options in right side.
Swift 3:
static func imageFromColor(color: UIColor, width: CGFloat, height: CGFloat) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: width, height: height)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()!
context.setFillColor(color.cgColor)
context.fill(rect)
let img = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return img
}
let button = UIButton(type: .system)
let image = imageFromColor(color: .red, width:
button.frame.size.width, height: button.frame.size.height)
button.setBackgroundImage(image, for: .normal)
For iOS 15+ Apple provides a simple button configuration to accomplish this.
Objective-C:
randomButton.configuration = [UIButtonConfiguration filledButtonConfiguration];
Swift:
randomButton.configuration = .filled()