Multiple lines of text in UISegmentedControl - ios

is there an easy way, such that each item in my UISegmentedControl for instance,
has multiple lines of text?
Thanks.
ps. I've also checked there's no easy way to change the height of UISegmentedControl?
Say in Code? Changing the style to "Bar" does not suit me, and setFrame does not
seem to work in my case too... :((
pps. This is the approach I tried as recommended by Siba but still have some issues.
for (id segment in [segmentedControl subviews])
{
for (id label in [segment subviews])
{
if ([label isKindOfClass:[UILabel class]])
{
UILabel *label2 = label;
//hear u add any of delegate function to increase the height and other label functionality in this
[label2 setTextAlignment:UITextAlignmentCenter];
[label2 setFont:[UIFont boldSystemFontOfSize:12]];
//to adjust the label size manually with respect to text use below code
CGSize labelSize = CGSizeMake(100, 80);
CGSize theStringSize = [label2.text sizeWithFont:label2.font constrainedToSize:labelSize];
CGRect frame = label2.frame;
frame.size = theStringSize;
label2.lineBreakMode = UILineBreakModeWordWrap;
label2.numberOfLines = 0;
[label2 setText:#"text \n 10%"];
}
}
}

1.You can try the following.
create a multiline UILabel
fill the label with N lines of text
convert the label into an UIImage
set the image as a segments content
Like one Done in This Answer :
UISegmentedControl text with multiple lines?
2.You can Take An ImageView in the back of Segmented Control with Same frame And Change images as per SelectedSegmentedIndex Like below.
But Don't forget to set Alpha of SegmentedControl to 0.05. At ViewDidLoad.
segment_Control.alpha=0.05;
The Coding will be Like this.
- (IBAction)segmented_Changed:(id)sender {
if (segmented_control.selectedSegmentIndex==0) {
segment_image.image=[UIImage imageNamed:#"tab_Act1.png"];
}else
if (segmented_control.selectedSegmentIndex==2) {
segment_image.image=[UIImage imageNamed:#"tab_Act3.png"];
}
else if (segmented_control.selectedSegmentIndex==1) {
segment_image.image=[UIImage imageNamed:#"tab_Act2.png"];
}
}
3.Also You Can try This :
for (id segment in [segmentedControl subviews])
{
for (id label in [segment subviews])
{
if ([label isKindOfClass:[UILabel class]])
{
//hear u add any of delegate function to increase the height and other label functionality in this
[label setTextAlignment:UITextAlignmentCenter];
[label setFont:[UIFont boldSystemFontOfSize:12]];
//to adjust the label size manually with respect to text use below code
CGSize labelSize = CGSizeMake(100, 80);
CGSize theStringSize = [label.text sizeWithFont:label.font constrainedToSize:labelSize];
CGRect frame = label.frame;
frame.size = theStringSize;
}
}
}
Source : Multiline Text On UIsegment Control

Related

Two lines of text in a UISegmentedControl

Try as I might, I can't solve a UISegmentedControl bug for an iOS7 iPhone app.
When I create the segmented control, I use this code:
NSArray *segmentedControlItemArray = [NSArray arrayWithObjects: #"Nominal:\n27 inch", #"Actual:\n700c x 23mm", #"Actual:\n700c x 20mm", nil];
_wheelDiameterSegmentedControl = [[UISegmentedControl alloc] initWithItems:segmentedControlItemArray];
_wheelDiameterSegmentedControl.frame = CGRectMake(0, 102, 290, 50);
_wheelDiameterSegmentedControl.selectedSegmentIndex = 0;
_wheelDiameterSegmentedControl.tintColor = [UIColor colorWithRed:0.35 green:0.4 blue:0.9 alpha:1.0];
for (id segment in [_wheelDiameterSegmentedControl subviews]) {
for (id label in [segment subviews]) {
if ([label isKindOfClass:[UILabel class]]) {
UILabel *titleLabel = (UILabel *) label;
titleLabel.numberOfLines = 0;
}
}
}
[_wheelDiameterSegmentedControl addTarget:self
action:#selector(pickOne:)
forControlEvents:UIControlEventValueChanged];
[_wheelDiameterMenuContainer addSubview:_wheelDiameterSegmentedControl];
Sadly, I can't post images, or I would show you a picture of exactly the control I want: each of the segments in the UISegmented Control has two lines of text, with a line break exactly where I asked for it.
On rotation, though, I'd like to keep the segmented control full-width, and the line breaks look silly in segments that wide. So, in willAnimateRotationToInterfaceOrientation, I've included the following code, with no line breaks in the strings:
[_wheelDiameterSegmentedControl setFrame:CGRectMake(0, 102, 450, 50)];
[_wheelDiameterSegmentedControl setTitle:#"Nominal: 27 inch" forSegmentAtIndex:0];
[_wheelDiameterSegmentedControl setTitle:#"Actual: 700c x 23mm" forSegmentAtIndex:1];
[_wheelDiameterSegmentedControl setTitle:#"Actual: 700c x 20mm" forSegmentAtIndex:2];
And once again, if I could insert an image, I would show you an image of exactly what I want: a wide UISegmented Control with no line breaks in the labels (1 line of text per label).
Here's where I run in to trouble. My choices, when I rotate back to portrait, seem to be:
1 line of label text, truncated, with the format
"Actual: 7..."
when I just reset the size of the UISegmentedControl using
[_wheelDiameterSegmentedControl setFrame:CGRectMake(0, 102, 290, 50)];
2 lines of label text, truncated, with the format
"Actual:
700c x ..."
when I reset the size and also reset the string values and rerun the loop of code that sets the label's numberOfLines to 2, using
NSArray *segmentedControlItemArray = [NSArray arrayWithObjects: #"Nominal:\n27 inch", #"Actual:\n700c x 23mm", #"Actual:\n700c x 20mm", nil];
[_wheelDiameterSegmentedControl setTitle:[segmentedControlItemArray objectAtIndex:0] forSegmentAtIndex:0];
[_wheelDiameterSegmentedControl setTitle:[segmentedControlItemArray objectAtIndex:1] forSegmentAtIndex:1];
[_wheelDiameterSegmentedControl setTitle:[segmentedControlItemArray objectAtIndex:2] forSegmentAtIndex:2];
for (id segment in [_wheelDiameterSegmentedControl subviews]) {
for (id label in [segment subviews]) {
if ([label isKindOfClass:[UILabel class]]) {
UILabel *titleLabel = (UILabel *) label;
titleLabel.numberOfLines = 2;
}
}
}
[_wheelDiameterSegmentedControl setFrame:CGRectMake(0, 102, 290, 50)];
3 lines of label text, with the format
"Actual:
700c x
20mm"
which is what I get when I replace the forced numberOfLines = 2 above with the numberOfLines = 0 that worked when I set up the UISegmentedControl in the first place.
What I'd like is what I get when I create the control, which is
"Actual:
700c x 20mm"
But no matter what I've tried (putting the string and numberOfLines code into willRotateToInterfaceOrientation or didRotateFromInterfaceOrientation; re-setting the frame of the UISegmentedControl before changing the text; re-setting the frame after changing the text...), I can't get my nice, neat, two-line label back. What am I missing here?
Aha! Something about how the OS is handling the size of the label when it rotates is different from how it handles the label when it's created. So I forced the size of the frame of the label, using
for (id segment in [_wheelDiameterSegmentedControl subviews]) {
for (id label in [segment subviews]) {
if ([label isKindOfClass:[UILabel class]]) {
UILabel *titleLabel = (UILabel *) label;
//inserting line here, to make the frame behave nicely:
//
titleLabel.frame = CGRectMake(0, 0, 97, 50);
//
//continuing as before
titleLabel.numberOfLines = 0;
}
}
}
and now it displays exactly as I want/expect. Huzzah!
If you're just trying to get two (or more) lines of text in your UISegmentedControl. Using Herzian's amazing technology! Here's just another code example, that may help people...
self.yourSlider .. set the height manually (can't easily do it in XIB)
// now use amazing Herzian technology...
for (id segment in [self.yourSlider subviews])
for (id label in [segment subviews])
{
if ([label isKindOfClass:[UILabel class]])
{
UILabel *titleLabel = (UILabel *) label;
titleLabel .. set the width to say 80, per your layout;
(the width us typically too low)
titleLabel.numberOfLines = 0;
}
}
thank you so much, again.
working code in ios 7 :
I have a segment controller with four segments and I need it in 2 lines for text. So I have added UILabel as a subview in segment of UISegmentedControl and it is working good. I have tried all other ways but in ios 7 and ios 8 it is working good right now.
for(int k =0;k<4;k++)
{
NSString *text = #"title name";
UILabel *label = [[UILabel alloc] init];
label.frame = CGRectMake(10,2, (self.segmentcontroll.frame.size.width/4), 34);
label.font = [UIFont fontWithName:#"HelveticaNeue" size:12.0];
label.textColor = [UIColor whiteColor];
label.text = text;
label.numberOfLines = 0;
label.textAlignment = NSTextAlignmentCenter;
[label sizeToFit];
[[[self.segmentcontroll subviews] objectAtIndex:k] addSubview:label];
}
And Herzian's solution as a category if anyone wants it. Remember to call it in VWA instead of VDL so it happens after autosizing / rotation
#import "UISegmentedControl+MultiLine.h"
#implementation UISegmentedControl (MultiLine)
-(void)setupMultiLine
{
self.frame = CGRectMake(self.frame.origin.x,
self.frame.origin.y,
self.frame.size.width,
self.frame.size.height*1.6);
for (id segment in self.subviews)
{
for (id label in [segment subviews])
{
if ([label isKindOfClass:[UILabel class]])
{
UILabel *titleLabel = (UILabel*) label;
titleLabel.frame = CGRectMake(0,
0,
titleLabel.frame.size.width,
titleLabel.frame.size.height*1.6);
titleLabel.numberOfLines = 0;
}
}
}
}
#end

Center vertically in UILabel with autoshrink

This is a little different from all the other "How do I center the text in a UILabel" questions here...
I have a UILabel with some text in it, I want to center the text vertically in the UILabel. What's the big deal, right? That's the default. The problem comes because my text is dynamic and I have autoshrink turn on. As the text grows larger, the font size shrinks. You get this behavior.
Notice that the font baseline has not moved, I want it to move so the numbers are centered vertically in the UILabel's frame.
Easy, right? I just remember the frame's original center in viewDidLoad
self.workoutTimeCenter = _workoutTimeLabel.center;
and then I call sizeToFit after I change the the text, right?
[_workoutTimeLabel sizeToFit];
_workoutTimeLabel.center = _workoutTimeCenter;
Well, sizeToFit did, I guess, exactly what it was supposed to do, resize the frame so the text fits without shrinking!
How can I vertically center the text in a UILabel while respecting baselines and autoshrink? (Note, an iOS5 and later solution is fine and I can even deal with an iOS6 and later solution.)
In my experience you can just set the -[UILabel baselineAdjustment] property to UIBaselineAdjustmentAlignCenters to achieve the effect you're describing.
From the docs:
baselineAdjustment
Controls how text baselines are adjusted when text
needs to shrink to fit in the label.
#property(nonatomic) UIBaselineAdjustment baselineAdjustment
Discussion
If the adjustsFontSizeToFitWidth property is set to YES,
this property controls the behavior of the text baselines in
situations where adjustment of the font size is required. The default
value of this property is UIBaselineAdjustmentAlignBaselines. This
property is effective only when the numberOfLines property is set to
1.
and
UIBaselineAdjustmentAlignCenters
Adjust text based relative to the center of its bounding box.
EDIT: adding a full view-controller that demonstrates this:
#interface TSViewController : UIViewController
#end
#implementation TSViewController
- (void) addLabelWithFrame: (CGRect) f baselineAdjustment: (UIBaselineAdjustment) bla
{
UILabel* label = [[UILabel alloc] initWithFrame: f];
label.baselineAdjustment = bla;
label.adjustsFontSizeToFitWidth = YES;
label.font = [UIFont fontWithName: #"Courier" size: 200];
label.text = #"00";
label.textAlignment = NSTextAlignmentCenter;
label.backgroundColor = [UIColor lightGrayColor];
label.userInteractionEnabled = YES;
[self.view addSubview: label];
UIView* centerline = [[UIView alloc] initWithFrame: CGRectMake(f.origin.x, f.origin.y+(f.size.height/2.0), f.size.width, 1)];
centerline.backgroundColor = [UIColor redColor];
[self.view addSubview: centerline];
UITapGestureRecognizer* tgr = [[UITapGestureRecognizer alloc] initWithTarget: self action: #selector(onTap:)];
[label addGestureRecognizer: tgr];
}
- (void) viewDidLoad
{
[super viewDidLoad];
[self addLabelWithFrame: CGRectMake(0, 0, 320, 200)
baselineAdjustment: UIBaselineAdjustmentAlignCenters];
[self addLabelWithFrame: CGRectMake(0, 220, 320, 200)
baselineAdjustment: UIBaselineAdjustmentAlignBaselines];
}
- (void) onTap: (UITapGestureRecognizer*) tgr
{
UILabel* label = (UILabel*)tgr.view;
NSString* t = [label.text stringByAppendingString: #":00"];
label.text = t;
}
#end
when working in IB, be sure to set align baselines to center
Note: line break CANNOT be word wrap for this to work, so it will NOT work multiline (good to set the line break to Truncate tail)
-(void)fitVerticallyToLabel:(UILabel *)lbl
{
CGFloat fontSize = lbl.frame.size.width / lbl.text.length;
[lbl setFont:[UIFont fontWithName:#"Helvetica-Bold" size:fontSize]];
CGRect rect = lbl.frame;
rect.origin.y += rect.size.height - fontSize;
rect.size.height = fontSize;
[lbl setFrame:rect];
}
How to Use: Call this method after setting the text to your label.
label.text = #"text";
[self fitVerticallyToLabel:label];
Note: I ahev taken UILabel from xib. You can take it programmatically too in that case you will have to set its text alignment NSTextAlignMentCenter
Try to implement this logic:
-(void)adjustLabel1Text1:(NSString *)text1
{
UILabel *lbl_first = [UIFont fontWithName:#"Helvetica" size:12];
text1 = [text1 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
float hedingLblHeight = [self calculateHeightOfTextFromWidth:text1 : [UIFont fontWithName:#"Helvetica" size:12] :118 :UILineBreakModeWordWrap];
lbl_first.text=text1;
[lbl_first setFrame:CGRectMake(lbl_first.frame.origin.x, lbl_first.frame.origin.y, 118, hedingLblHeight)];
lbl_first.lineBreakMode = UILineBreakModeWordWrap;
lbl_first.numberOfLines = 0;
[lbl_first sizeToFit];
//////////Adjust the lable or any UIControl below this label accordingly.
float endResultHeight=[self calculateHeightOfTextFromWidth:text2 : [UIFont fontWithName:#"Helvetica" size:15] :299 :UILineBreakModeWordWrap];
if(hedingLblHeight>secondImgTitleHeight)
{
[lbl_endResult setFrame:CGRectMake(lbl_endResult.frame.origin.x, lbl_first.frame.origin.y+lbl_first.frame.size.height+5, 299, endResultHeight)];
}
else
{
[lbl_endResult setFrame:CGRectMake(lbl_endResult.frame.origin.x, lbl_first.frame.origin.y+lbl_first.frame.size.height+5, 299, endResultHeight)];
}
lbl_endResult.lineBreakMode=UILineBreakModeWordWrap;
lbl_endResult.numberOfLines = 0;
[lbl_endResult sizeToFit];
}
-(float) calculateHeightOfTextFromWidth:(NSString*)text : (UIFont*) withFont:(float)width :(UILineBreakMode)lineBreakMode
{
CGSize suggestedSize = [text sizeWithFont:withFont constrainedToSize:CGSizeMake(width, FLT_MAX) lineBreakMode:lineBreakMode];
return suggestedSize.height;
}
It has helped me a lot.Hope it works for you.
Try
yourLabel.textAlignment = UITextAlignmentCenter;

Resize text in a UILabel (subview of UITableViewCell) to fit width

I have a UITableViewCell that is customized, sometime, text in UILabel (UILabel is subview in UITableViewCell) is exceeds size, and it get some dots (like ...) in label.
I want to adjust font size to fit width. But it does not work.
Here is my code
In Class implement for UITableviewCell
-(void) awakeFromNib{
myLabel.minimumFontSize = 8;
myLabel.adjustsFontSizeToFitWidth = YES;
}
Please help me!!!
Try this simple code
UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
label.backgroundColor=[UIColor clearColor];
label.text= yourString;
label.numberOfLines=0;
label.adjustsFontSizeToFitWidth=YES;
label.minimumFontSize=6;
label.textAlignment=UITextAlignmentCenter;
[self.View addSubview:label];
CGFloat fontSize = 20;
while (fontSize > 0.0)
{
CGSize size = [yourString sizeWithFont:[UIFont fontWithName:#"Rockwell-Bold" size:fontSize] constrainedToSize:CGSizeMake(label.frame.size.width, 10000) lineBreakMode:UILineBreakModeWordWrap];
if (size.height <= label.frame.size.height) break;
fontSize -= 1.0;
}
//set font size
label.font = [UIFont fontWithName:#"Rockwell-Bold" size:fontSize];
[label release];
try this one...
myLabel.numberOfLines=0;
[myLabel sizeToFit];
at First. In your TableViewClass, in heightForRowAtIndexPath you have to calculate the height of your text according to your label and return it.
and make your label's autoLayout property flexible height. You do not need to reset your label's frame. try this it will work....

Determine custom section header frame when tableView mode grouped

I provide a custom section header via the tableView's delegate method. It works fine in plane mode but I can't figure out the correct margin in grouped style.
Does anyone know how to make the section header aligned with the tableView cells?
You can create a custom label and adjust its frame accordingly.
For eg.
- (UIView *)tableView:(UITableView *)aTableView viewForHeaderInSection:(NSInteger)section
{
UIView *view=[[UIView alloc] initWithFrame:aTableView.tableHeaderView.frame];
UILabel *label=[[UILabel alloc] initWithFrame: CGRectMake(//set frame of the label as you want)];
[label setFont:[UIFont fontWithName: size:]];
[label setTextColor:[UIColor blackColor]];
[label setShadowOffset:CGSizeMake(0.0f, 1.0f)];
[label setShadowColor:[UIColor redColor];
label.backgroundColor=[UIColor clearColor];
if(section==0)
{
[label setText://set your section0 title];
}
else if(section ==1)
{
[label setText://set your section1 title];
}
[view addSubview:label];
[label release];
return [view autorelease];
}
Hope this helps :)
Not tested in every flavor but a good starting point.
In
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
pass the tableView.style parameter to your own method providing the header.
Create a view a frame like
CGRect(0,0,CGRectGetWidth(tableView.frame), CGRectGetHeight(tableView.frame)
but add a subview with a frame
CGRectInset(frame, 30,0)
if you have a grouped tableView style. Set a the autoresizingMask to flexible width and it works.
Slightly modified in a way that I had to give an additional parameter to the creation method for the SectionHeaderView as the margin is different for presentationStyle FullScreen and Formsheet.
CGFloat margin = 0;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
margin = style == UITableViewStyleGrouped ? modalStyle == UIModalPresentationFormSheet ? 28 : 38 : 0;
}
else {
margin = style == UITableViewStyleGrouped ? 5 : 0;
}
UIView *view = [[UIView alloc] initWithFrame:CGRectInset(frame, margin, 0)];
view.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self addSubview:view];

Changing an embedded UITextView width on rotation?

I have a UITextView embedded inside a grouped table view cell that I can't seem to update on rotation. It basically keeps the same width (assumed portrait) when it becomes landscape, causing about 40% of the view to be blank on the left side.
Is there a way to update this easily? I was looking at willRotateToInterfaceOrientation but I wasn't sure if that was the right thing to update the view on rotation.
Specifically, I'm thinking the width value should be updated, since it's based on the width.
if (indexPath.section == 1) {
switch (indexPath.row) {
case 0:
{
NSString *label = [self.pedal detail];
CGFloat width = [UIScreen mainScreen].bounds.size.width * .95;
CGSize stringSize = [label sizeWithFont:[UIFont systemFontOfSize:15]
constrainedToSize:CGSizeMake(320, 9999)
lineBreakMode:UILineBreakModeWordWrap];
UITextView *textField = [[UITextView alloc] init];
[textField setFrame:CGRectMake(50,0, width-10, stringSize.height+55)];
[textField setEditable:NO];
textField.backgroundColor = [UIColor clearColor];
textField.font = [UIFont systemFontOfSize:15];
textField.textAlignment = UITextAlignmentLeft;
cell.accessoryView = textField;
textField.text = [self.pedal detail];
[textField release];
break;
}
}
}
You need to set textField.autoresizingMask = UIViewAutoresizingFlexibleWidth, which streches the object on its width on view size change.
Read more at the UIView documentation
You have tried setting the sizing properties in IB right? The way the object scales and what points are anchors should be able to be set there.

Resources