I have a subclass of UITextField. In my instance the text is right align. I have rightView to show money sign at the end, so when user enters data the sign for money will be always visible. I decided that this solution is better than to take text and manually add money sign after each text change.
My problem is that the text and the rightView slightly overlap each other. How can I fix that?
Calculate width according to text and font size. Use this width as max width and than arrange money sign view.
Below is method to calculate max width for text.
- (CGFloat) widthWithFont:(NSString *)string font:(UIFont *)font {
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil];
return [[[NSAttributedString alloc] initWithString:string attributes:attributes] size].width;
}
Related
I am working on Tableview with dynamic cell height.
Due to my requirement, i have to show 40 types of different cell.Each cell is different.
For ex.
one cell having 2 labels,1 imageview
another cell having only 2 imageview
another cell having 5 labels,1 textview,2 buttons, 2 imageview
My problem is i cant able to define the height statically.ie. labels and textview in each cell is based on the text at run time.So according to the individual elements i need to adjust the height.So i have calculated the label and textview height based on below coding,
CGSize constrainedSize = CGSizeMake((IS_IPAD)?765:285 , 9999);
NSDictionary *dict=[array objectAtIndex:indexPath.row];
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"Lucida Sans" size:(IS_IPAD)?18.0:12.0], NSFontAttributeName,
nil];
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:[dict valueForKey:#"response"]attributes:attributesDictionary];
CGRect requiredHeight = [string boundingRectWithSize:constrainedSize options:NSStringDrawingUsesLineFragmentOrigin context:nil];
return requiredHeight.size.height;
The above code works fine.But it's little bit difficult to calculate for 5-10 labels for a cell.Because i need to call 10 times for every cell.So it causes slow scrolling on tableview.Also after that i need to change every label/textview and imageview's y position frame.Is there any alternate to achieve this? Any help would be highly appreciated.
Thanks.
Initially set a placeholder height for all your cells. later try to reload cells with exact heights.
Write a method that is capable of calculating the approx height for a specific cell. And pass some parameters into it.
I have 3 UILabels stacked on top of each other like so:
The top label can be 2 lines, but isn't all of the time. I'm trying to vertically center all 3 labels between the top and bottom lines in picture. I'm just not sure how to go about doing it. I've tried setting the space between them equal and give ≥ margins on the top and bottom but it doesn't seem to work.
Trying to do this without code, all in the interface builder if possible.
You could try putting the three labels inside a UIView, and then assigning that UIView to align to the center of the UIImageView.
You can easily do this by selecting all three UILabels, and going to Editor->Embed In->UIView. Select the new view and Shift Click on the image and select Editor->Align->Vertical Centers
Forget about using different labels for this, it's nightmare. Use NSAttributedString with one UILabel it'll automatically center the text.
NSString *name = #"John\nMultiline\nSmith"; // your multiline string
NSString *title = #"Salesguy"; // some more strings
NSString *phone = #"555-55-55";
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:#"%#\n%#\n%#", name, title, phone] attributes:#{NSFontAttributeName: [UIFont fontWithName:#"HelveticaNeue" size:17.0]}]; // construct the label with default parameters
[attributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"HelveticaNeue-Bold" size:17.0] range:[attributedString.string rangeOfString:name]]; // add bold selection to the name part
myLabel.attributedText = attributedString;
I currently have a custom UITableViewCell with a number of labels in it. Not all of those labels will necessarily have a value but they could do - and they may be multiline (At least 2 labels will always be visible). If there isn't any text then the label should collapse. What I'm trying to achieve is that each label only takes up the height it needs and they all butt up to each other. I've got all of this working, except I finally want a bottom margin of 11 between the last label and the cells content view with the cell height adjusted accordingly. This is the only bit where I can't seem to get my constraints working correctly.
I correctly return the right height by creating a dummy cell, and in my cellForRowAtIndexPath method I try to set the cell and the cell's contentview frame accordingly. But the cell height that is rendered on the screen is always the same as it was defined in the xib.
I know there's a lack of code here, but all my constraints have been define in IB and each label has a trailing and leading space for with and a top space of 0 to the label above it. The top label has a top space to create a top margin to the content view, but as soon as I do this on the bottom label it stretches the height of the labels to accommodate all the constraints.
I've seen various tutorials and questions on here that relate to 2 labels where 1 might be a variable size, but I haven't been able to adapt any solutions for what I'm trying to achieve.
Okay,
Get as many labels you want (suppose you want 2 labels inside the cell,)
Create 2 labels with height 1 in storyboard, or if you are programmatically adding them, then you can do.
UILabel *myLabel1 = [[UILabel alloc]initWithFrame:[CGRectMake:(x,y,width,1)]; // assuming you know their x,y and width respectively as you need them.
Now add constraints to the labels (Be sure you make them ambiguous or else orientation would mess it up, ):
3 a. Height -(should be equalto OR greater than => 1).
b. Width - [Set it a width],Make sure it has a priority more than others but less than height
c. Pin to trailing and leading space, as well as superview top and bottom.
d. If there are two Labels make sure you click both of them and add a Vertical or horizontal space according to your needs.
I think that would make it ambiguous. (I am telling these as you wrote its about autolayout, so despite of orientation this would never get any layout problems).
Add a snippet that would calculate the height of the Label when you know the string.
CGSize constrainedSizeOfMessege = CGSizeMake(widthOfLabel, 9999);//150,180 anything you like
NSDictionary *attributesDictionaryMessege = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"System Italics" size:16.0], NSFontAttributeName,
nil];
NSMutableString *myString = [[NSMutableString alloc]initWithString:[[friendsInstanceArray objectAtIndex:indexPath.row] myString] attributes: attributesDictionaryMessege];
CGRect requiredHeightMessege = [myString boundingRectWithSize:constrainedSizeOfMessege options:NSStringDrawingUsesLineFragmentOrigin context:nil];
Add the above code in
(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
Now, calculate the height of the Cell, the height of all the labels if they are 1 height then
Return the height of the Cell in storyboard + height of the Expected Label Size.
So The method would look like.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGSize constrainedSizeOfMessege = CGSizeMake(widthOfLabel, 9999);//150,180 anything you like
NSDictionary *attributesDictionaryMessege = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"System Italics" size:16.0], NSFontAttributeName,
nil];
NSMutableString *myString = [[NSMutableString alloc]initWithString:[[friendsInstanceArray objectAtIndex:indexPath.row] myString] attributes: attributesDictionaryMessege];
CGRect requiredHeightMessege = [myString boundingRectWithSize:constrainedSizeOfMessege options:NSStringDrawingUsesLineFragmentOrigin context:nil];
int heightOfMessege = requiredHeightMessege.size.height;
//if cell height is 50 then return 50+heightOfMessege
return 50+heightOfMessege;
}
And YES POSITIVELY set, mylabel.numberOfLines = 0;
Hope this helps you out
If you want to stick labels on their position including with the empty space than give a single space in label's title text which will not make their text empty and than label will stick to positions.
My iOS app is not showing long attributed strings. I have a cell in a tableview which contains this textView. When the text is very long the tableview is unresponsive for a while but when it loads the text is not shown. All other cells are displayed fine. And the textView works fine with small text strings.
Here's the code:
descriptionCell = [tableView dequeueReusableCellWithIdentifier:#"CellAdDetailDescription"];
descriptionCell.bodyTextView.delegate = self;
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:self.ad.body];
UIFont *cellFont;
cellFont = [UIFont fontWithName:#"HelveticaNeue" size:16.0];
NSDictionary *attributesDictionary;
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 10;
attributesDictionary = #{NSParagraphStyleAttributeName : paragraphStyle , NSFontAttributeName: cellFont};
[str addAttributes:attributesDictionary range:NSMakeRange(0, str.length)];
descriptionCell.bodyTextView.attributedText = str;
I pasted the long string here. I debugged and str is being loaded fine containing the desired text.
Whats wrong here?
What is the max allowed string length in UITextView?
EDIT: very odd, when trying selection in the textView, the text is being shown in the magnifying glass. I posted a video here.
Is it a bug in UITextView?
Here is the screenshot. The blank white at the bottom is the textView.
It could have something to do with the scrolling. If you are showing all the text (i.e. the text view is expanded to be as high as it needs to be, and so is the table view cell), the scrolling is done by the table view. If the text view is smaller, you have to scroll to see all the text - this might cause a conflict with the table view, which is also a scroll view.
It has been suggested that you disable the scrolling of the text view before adding the attributed text and reenable it afterwards. If you are showing the whole text in the table view, you can leave the text view scrolling disabled. In some cases, it will only work if scrolling is enabled. You should check this possibility as well.
I also had this issue (= very long attributed text didn't show up in the UITextView within an autosized UITableViewCell). I tried all accepted answers from here and from this question: UITextView not loading/showing the large text?. None did work.
However I then found out that - in my case - it just works fine on the device. So if you're still struggling with this kind of problem, don't rely on the iOS Simulator.
The reason that you UITextView not show all text because it Frame is too small so it truncates the text to fit with its frame. you can do follow step to show all text:
In your CustomUITableCell, override layoutSubView:
Use this function to calculate size of TextView that fit it content
[textView sizeThatFits:CGSizeMake(textView.frame.size.width, CGFLOAT_MAX)].height
After that, calculate and set new frame for TExtView (in uitableCell custom)
In the tableView:heightForCellAtIndexPath, calculate new size of textView (also height of cell) similar like above and return right height for cell.
UITextView scrolls even when all the text fits within its frame. It scrolls as if there are two new lines at the bottom of the text, but there aren't. So, its contentSize.height seems to be a couple lines larger than the text. How do I get rid of this? I.e., how do I tighten up the content size?
You can set up the contentSize for that UITextView so that it tightens to the text.
You can make use of NSString methods named sizeWithFont.... You can check full list here: http://developer.apple.com/library/ios/#documentation/uikit/reference/NSString_UIKit_Additions/Reference/Reference.html
I've noticed some issues working with some of them, but one that never fails me is:
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size
I suppose you have a fixed width and want to find out the correct height. Considering a fixed 200px width, it would be something like:
NSString *myText = #"Some text...";
CGSize tightContentSize = [mytext sizeWithFont:[UIFont fontWithName:#"Helvetica" size:12] constrainedToSize:CGSizeMake(200, 10000000)].height;
[myTextView setContentSize:tightContentSize];
Take into consideration that your UITextView has an 8px padding in all directions, so if your UITextView frame is 200 width, you would actualy have a 184px width for text.
It's late but, for other people, try with:
self.textView.contentInset = UIEdgeInsetsZero;
That's work for me.