iOS API - sizeThatFits: does not work - ios

UPDATE:
Sorry I didn't describe it enough and incorrectly before.
I did some code like this:
UIView *view = [[UIView alloc] initWithFrame:someFrame];
CGSize size = [view sizeThatFits:CGSizeMake(100, 100)];
But when I observe size, it got nothing: {0, 0}.
Do I use it wrong?
Even I passed in an initial frame to my view, the size still returned nothing.
I searched some posts and someone said UILabel may also gets affected.

Your view does't contain any content and it does't have any intristic content size, so it will have zero size.
Try these and you will see that it works:
UILabel *label [UILabel new];
label.text = #"test test test test";
CGSize size = [label sizeThatFits:CGSizeMake(20, CGFLOAT_MAX)];

As a #Konstantin said:
Your view does't contain any content and it does't have any inartistic
content size
So try to use this code
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
CGSize size = view.size;

Check the description of sizeThatFits, it states,
Asks the view to calculate and return the size that best fits the
specified size. A new size that fits the receiver’s subviews.
So, your view should have some subview or content otherwise it will return 0,0.

Related

how to programmatically align a label to an x, y coordinate

below are some other properties of the label. obviously nstextalignmentleft is not what i'm going for. having trouble understanding where to enter coordinates.
self.lblTimer = [[UILabel alloc] init];
self.lblTimer.translatesAutoresizingMaskIntoConstraints = NO;
self.lblTimer.textAlignment = NSTextAlignmentLeft;
self.lblTimer.font = [UIFont systemFontOfSize:10];
self.lblTimer.textColor = [UIColor redColor];`self.lblTimer = [[UILabel alloc] init];
I think you're misunderstanding what textAlignment does. This simply controls the alignment within the label, not on the screen. If you want to position the label on screen you must change its frame property:
self.lblTimer.frame = CGRectMake(x,y,width,height);
As you've set self.lblTimer.translatesAutoresizingMaskIntoConstraints to NO I am guessing you want to use Auto Layout and if so, I highly recommend taking a look at Masonry.
An alternative is to set the frame property on the label with requires a CGRect where you give it the x and y coordinates as well as the width and height.

Scrolling UILabel like a marquee in a subview

I have a UILabel in the main view with text - "Very Very long text". The proper width to this would be 142, but i've shortened it to 55.
Basically I want to implement a marquee type scroll, so I wrote code to add it onto a subview and animate it within the bounds of that view.
CODE --
CGRect tempLblFrame = _lblLongText.frame;
UIView *lblView = [[UIView alloc] initWithFrame:tempLblFrame];
//Add label to UIView at 0,0 wrt to new UIView
tempLblFrame.origin.x = 0;
tempLblFrame.origin.y = 0;
[_lblLongText setFrame:tempLblFrame];
[_lblLongText removeFromSuperview];
[lblView addSubview:_lblLongText];
//SetClipToBounds so that if label moves out of bounds of its superview, it wont be displayed
[lblView setClipsToBounds:YES];
[lblView setBackgroundColor:[UIColor cyanColor]];
[self.view addSubview:lblView];
After this I get this output on the simulator -->
The problem occurs when i try the Animation with this code -
tempLblFrame.origin.x = -_lblLongText.intrinsicContentSize.width;
[UIView animateWithDuration:2.0 delay:1.0 options:UIViewAnimationOptionCurveLinear
animations:^{
[_lblLongText setFrame:tempLblFrame];
}
completion:^(BOOL finished) {
NSLog(#"completed");
}];
I was hoping I would see the entire "Very Very long text", rather only "Very..." scrolls from left to right.
To solve this I added one line of code --
//Add label to UIView at 0,0 wrt to new UIView
tempLblFrame.origin.x = 0;
tempLblFrame.origin.y = 0;
tempLblFrame.size.width = _lblLongText.intrinsicContentSize.width; //THIS LINE WAS ADDED
[_lblLongText setFrame:tempLblFrame];
[_lblLongText removeFromSuperview];
[lblView addSubview:_lblLongText];
I thought the full text will be set inside the newly added UIView and it would scroll properly. But running in the simulator gave me this --
And again, only "Very..." was scrolling from left to right.
What am I doing wrong? Please help!!
EDIT
Apparently the culprit was AutoLayout.
I have no clue why, but once I unchecked "Use Autolayout" for the view
in the XIB, everything started working as expected. Setting
tempLblFrame.origin.x = -_lblLongText.intrinsicContentSize.width; was
working properly and so was the scroll.
Any explanation on this!!?
This question is possibly Duplicate of.
Although there is nice code snippet written by Charles Powell for MarqueeLabel,
also take a look at This link.
I hope this will help you and will save your time by giving a desired output.
Make the UILabel the width (or longer) of the text and the UIView the scroll area you want to see. Then set the UIView's clipToBounds to YES (which you are doing). Then when you animate left to right you will only see the the text the width of the UIView, since it is cutting any extra subviews. Just make sure you scroll the entire length of the UILabel.
Right now you are setting the view and label's height and width to the same thing. This is why you are getting clipped text, not a clipped label.
You add In your view scrollview and add this label in your scroll view .Use this code
scroll.contentSize =CGSizeMake(100 *[clubArray count],20);
NSString *bname;
bname=#"";
for(int i = 0; i < [clubArray count]; i++)
{
bname = [NSString stringWithFormat:#"%# %# ,",bname,[[clubArray objectAtIndex:i] objectForKey:#"bottle_name"]];
[bname retain];
}
UILabel *lbl1 = [[UILabel alloc] init];
[lbl1 setFrame:CGRectMake(0,5,[clubArray count]*100,20)];
lbl1.backgroundColor=[UIColor clearColor];
lbl1.textColor=[UIColor whiteColor];
lbl1.userInteractionEnabled=YES;
[scroll addSubview:lbl1];
lbl1.text= bname;
This is implemented code.Thanks
Apparently the culprit was AutoLayout.
I have no clue why, but once I unchecked "Use Autolayout" for the view in the XIB, everything started working as expected. Setting tempLblFrame.origin.x = -_lblLongText.intrinsicContentSize.width; was working properly and so was the scroll.
Still, a better explanation for this would surely help!!
EDIT: Solution with AutoLayout -
//Make UIView for Label to sit in
CGRect tempLblFrame = _lblLongText.frame;
UIView *lblView = [[UIView alloc] initWithFrame:tempLblFrame];
//#CHANGE 1 Removing all constraints
[_lblLongText removeConstraints:_lblLongText.constraints];
//Add label to UIView at 0,0 wrt to new UIView
tempLblFrame.origin.x = 0;
tempLblFrame.origin.y = 0;
//Set Full length of Label so that complete text shows (else only truncated text will scroll)
tempLblFrame.size.width = _lblLongText.intrinsicContentSize.width;
//#CHANGE 2 setting fresh constraints using the frame which was manually set
[_lblLongText setTranslatesAutoresizingMaskIntoConstraints :YES];
[_lblLongText setFrame:tempLblFrame];
[_lblLongText removeFromSuperview];
[lblView addSubview:_lblLongText];

Adding additional space to UILabel to insert image

I have an issue with adding image in the end of the text of the UILabel. How can I detect the size of the text in the label, then add additional space and insert image into it?
i write a little code for this:
-(void) labelSizeGetter
{
UILabel * mylabel=[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
float heigth=25.0;//max height value of label.
NSString *yourString = #"My great text";
mylabel.font =[UIFont fontWithName:#"Helvetica-Bold" size:12];
[mylabel setText:yourString];
CGSize s = [mylabel.text sizeWithFont:[UIFont systemFontOfSize:12]
constrainedToSize:CGSizeMake(MAXFLOAT,heigth)
lineBreakMode:NSLineBreakByWordWrapping];
// s is a size for text of label. just add 10 pix to width to make it more beautiful.
NSLog(#"%#", NSStringFromCGSize(s));
mylabel.frame=CGRectMake(0, 0, s.width+10, s.height);
[self.view addSubview:mylabel];
UIView * myimage=[[UIView alloc] initWithFrame:CGRectMake(mylabel.frame.origin.x+mylabel.frame.size.width , mylabel.frame.origin.y, 30, 30)];//create your images frame according to frame of your label
myimage.backgroundColor =[UIColor colorWithPatternImage:[UIImage imageNamed:#"arti.png"]];
[self.view addSubview:myimage];
}
i hope it helps
Best Way is take one UIView.
And Add Both UILabel And UIImageView on This UIView (give Fram as per your Requirement).
And This UIView to your MainView of UIViewController.
If you dont want to use a UIView. Why not check the length of the string in the label. then add some additional space for your image using frame. [UILabel.text length] returns the length.
Create some container UIView if you need or just use superview
Put there UILabel and UIImageView
Calculate a size of the text using [NSString sizeWithFont:] or similar sizeWith... method
Calculate position of your UIImageView according to a size of the text
Here is a code snippet which gives you size adjustable for specific font and specific font size. Accordingly you can set frame for your label and then image view as well.
- (CGSize)getSizeFromText:(NSString*)text {
CGSize constrainedSize;
constrainedSize.width = give maximum allowable width limit;
constrainedSize.height = MAXFLOAT;
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:fontSize] constrainedToSize:constrainedSize lineBreakMode: UILineBreakModeWordWrap];
return size;
}
Hope this would help you to solve your problem.
There is a category on NSString that returns the size of a string when rendered with a given font. There are several methods, the most complete on being - (CGSize)sizeWithFont:(UIFont *)font minFontSize:(CGFloat)minFontSize actualFontSize:(CGFloat *)actualFontSize forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode (see Apple Docs).
With that information you might be able to achieve what you want to do.

iOS: sizeWithFont: for custom font

I've been plugging away and I need to use the sizeWithFont: method to properly line up my layout, but it doesn't seem to work with custom fonts. Is there a way to get it to work, or maybe another method I can use?
I'm pretty stumped on this. Any help is appreciated.
sizeWithFont should definitely work, but if it's giving you a problem then there is a workaround. You can put the text in a UITextView, add it to your layout, and then retrieve the actual text size and adjust accordingly. Here's some sample code from one of my projects:
// Put in the title in
self.titleView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 195, 195)];
self.titleView.font = [UIFont fontWithName:#"Bliss Pro" size:20.0];
[self addSubview:self.titleView];
self.titleView.text = #"Add your text here";
// Now get the actual size of the text and resize the title view's frame
CGRect frame = self.titleView.frame;
frame.size.height = self.titleView.contentSize.height;
self.titleView.frame = frame;
It's a bit hackish, but it certainly works.
#define kFontSize 14.0 //modify your font size
CGSize size = [yourView sizeWithFont:[UIFont boldSystemFontOfSize:kFontSize]];

Applying transform to UITextView - prevent content resizing

When I apply a rotation transform to a UITextView and then click inside to begin editing, it appears that the content size is automatically being made wider. The new width of the content view is the width of the rotated view's bounding box. For example, given a text box of width 500 and height 400, and rotated by 30 degrees, the new content width would be:
(500 * cos(30)) + (400 * sin(30)) = 633
Or graphically:
Interestingly, if you are already editing the text view and THEN apply the transform, then it appears that no modification is made to the content size. So it appears that sometime around the start of text editing, the text view looks at its frame property and adjusts the content size based on the frame width. I imagine the solution to this is to tell it to use the bounds property instead, however I don't know where to do this, as I'm not sure exactly where the text view is deciding to modify the content size.
I have googled but can't seem to find any references to using transformed UITextViews. Does anybody have any ideas about this?
EDIT (button action from test project):
- (IBAction)rotateButtonTapped:(id)sender {
if (CGAffineTransformIsIdentity(self.textView.transform)) {
self.textView.transform = CGAffineTransformMakeRotation(30.0 * M_PI / 180.0);
}
else {
self.textView.transform = CGAffineTransformIdentity;
}
NSLog(#"contentsize: %.0f, %.0f", textView.contentSize.width, textView.contentSize.height);
}
I was also stuck with this problem.
The only solution which I found was to create an instance of UIView and add the UITextView as a subview. Then you can rotate the instance of UIView and UITextView will work just fine.
UITextView *myTextView = [[UITextView alloc] init];
[myTextView setFrame:CGRectMake(0, 0, 100, 100)];
UIView *myRotateView = [[UIView alloc] init];
[myRotateView setFrame:CGRectMake(20, 20, 100, 100)];
[myRotateView setBackgroundColor:[UIColor clearColor]];
[myRotateView addSubview:myTextView];
myRotateView.transform = CGAffineTransformMakeRotation(0.8);
[[self view] addSubview:myRotateView];
Have you tried applying the rotation by doing a layer transform rather than a transform on the view?
#import <QuartzCore/QuartzCore.h>
mytextField.layer.transform = CATransform3DMakeRotation (angle, 0, 0, 1);
This might be enough to trick whatever broken logic exists inside the core text field code.

Resources