UItextView text hidden - iphone

I am notes.app like app. I am setting UITextView's contentInset as
myTextView.contentInset = UIEdgeInsetsMake(0, 25, 0, -25);
myTextView.contentSize = CGSizeMake(295, myTextView.contentSize.height);
but that does not seems to work as I expected. Two characters are hidden.
I get this
but if I set
myTextView.contentInset = UIEdgeInsetsMake(0, 25, 0, 0);
myTextView.contentSize = CGSizeMake(295, myTextView.contentSize.height);
I get actual text as
please help.

fibnochi you can use a different approach to do this. I have used this in one of my app and it is working fine
First of all you need to get the size of UItextView which will carry all the data, for this you need to use NSString class delegate function
NSString* str = #"Your Entire string will come here";
CGSize size = [str sizeWithFont:[UIFont systemFontOfSize:17.0] constrainedToSize:CGSize(295, any large digit for maximum height say 10000) lineBreakMode:UILineBreakModeWordWrap];
textView.contentSize = size;
Will this solve your problem or not. Please let me know

Can you please try the below?
myTextView.contentInset = UIEdgeInsetsMake(0, 25, 0, 25);
myTextView.contentSize = CGSizeMake(295, myTextView.contentSize.height);

Apple's discussions
here.
"
Edge inset values are applied to a rectangle to shrink or expand the area represented by that rectangle. Typically, edge insets are used during view layout to modify the view’s frame. Positive values cause the frame to be inset (or shrunk) by the specified amount. Negative values cause the frame to be outset (or expanded) by the specified amount.
"
You can do like UIEdgeInsetsMake(0,25,0,25)

try this code :)
myTextView.contentInset = UIEdgeInsetsMake(0, 25, 0, -25);
myTextView.contentSize = CGSizeMake(270, myTextView.contentSize.height);
May this will help you out :)

Related

Monotouch - calculate UILabel height

I am trying to create a custom cell which consists a few UILabels.
The first label might take one or more rows, so I need to resize the label according to the number of lines (after setting the number of lines to 0, so multi-line will be enabled).
I have tried setting sizeToFit(), but it changed the alignment and width of my label.
I found this answer
but I don't know how to convert it to C#.
Can anyone point me to an example? (I already tried Googling it off-course)
This is the method from the link:
// UILabel *myLabel;
CGSize labelSize = [myLabel.text sizeWithFont:myLabel.font
constrainedToSize:myLabel.frame.size
lineBreakMode:UILineBreakModeWordWrap];
CGFloat labelHeight = labelSize.height;
int lines = [myLabel.text sizeWithFont:myLabel.font
constrainedToSize:myLabel.frame.size
lineBreakMode:UILineBreakModeWordWrap].height/16;
// '16' is font size
var size = myLabel.StringSize("Some really long string", myLabel.Font, myLabel.Frame.Size, UILineBreakMode.CharacterWrap);
var lines = size.Height / myLabel.Font.CapHeight;

iOS: CGRectMake doesn't change position of a UILabel

I've created a label via storyboard. The order is like this:
View -> Scroll View -> Bunch of labels.
Here is the text output I want to achieve:
2 December <30 days left>
the <> enclosed text is in smaller letters an in a different UI Label.
Since the month name is dynamic and the width changes I've tried using CGRectMake to alter the position of the <> enclosed text.
But it isn't working. I tried changing the parameters of the function but the label stays put. It doesn't move from its initial position set in storyboard.
label_days_left.frame = CGRectMake(50, 10, 100, 99);
EDIT:
- (void) alignDaysLeft{
//code to align the label just after the match date
CGFloat dateLabelWidth = [label_date.text sizeWithFont:label_date.font].width;
CGFloat dateLabelHeight = [label_date.text sizeWithFont:label_date.font].height;
CGFloat someGap = 0;
CGFloat daysLeftX = label_date.frame.origin.x + dateLabelWidth + someGap;
CGFloat daysLeftY = label_date.frame.origin.y;
[label_date sizeToFit];
//label_days_left.frame = CGRectMake(daysLeftX, daysLeftY, 100, dateLabelHeight);
label_days_left.frame = CGRectMake(50, 10, 100, 99);
label_days_left.text = [NSString stringWithFormat:#"lolo"];
NSLog(#"date width - %f", daysLeftX);
}
label_date is the variable which contains the month and day.
label_days_left is the label variable which I am trying to place next to the month.
EDIT 2:
EDIT 3:
I created a new project.
Dragged a label on the view.
Created an outlet.
Synthesized it.
And used the following code to move it -
[labia setFrame:CGRectMake(0, 100, 5, 99)];
It didn't work. What mistake am I doing?
Do you have AutoLayout turned on? If so then that might be your problem, as you are not supposed to worry about setting the frame with AutoLayout, and instead set constraints.
NSString *someString = [NSString stringWithFormat:#"%#",label_date.text]
UIFont *yourFont = [UIFont systemFontOfSize:22.0];
CGSize stringBoundingBox = [someString sizeWithFont:yourFont];
[label_days_left setFrame:CGRectMake(label_days_left.frame.origin.x, 10, stringBoundingBox.width, 99)];
[label_days_left setText:someString];
Pls try this once....

UITextView visually changing content position when pasting in text

I have a UITextView which is designed to enlarge to fit the contentView when needed. When I paste in a paragraph of text, however, it puts the start and end points of the content vertically in the wrong places. Entering or deleting a character resets it back to the correct position.
Any ideas why this is?
-(void)textViewDidChange:(UITextView *)textView {
self.textView.frame = CGRectMake(
self.textView.frame.origin.x,
self.textView.frame.origin.y,
self.textView.frame.size.width,
self.textView.contentSize.height + HEADER_ADDITIONAL_HEIGHT);
self.textView.contentOffset = CGPointMake(0, 0);
self.previousContentSize = textView.contentSize;
}
When I used:
textView.contentSize = textView.frame.size;
textView.contentOffset = CGPointZero;
It solved my issue, but created a new issue where we sometimes get weird scrolling while typing or deleting text. So, I used this:
textView.contentSize = CGSizeMake( textView.contentSize.width,
textView.contentSize.height+1);
This also solved the issue. I think what we all need here is the effect which we get whenever the contentSize of a textview is changed. Unfortunately, I do not know what this effect is. If somebody knows, please tell.
Update:
I have found a method which you can use to solve your issue (I used this to resolve mine).
You can ask NSLayoutMAnager to refresh the entire layout:
[textView.textStorage edited:NSTextStorageEditedCharacters range:NSMakeRange(0, textView.textStorage.length) changeInLength:0];
NSLayoutManager attempts to avoid refreshing the layout because it's time consuming and takes a lot of work, so it's set up to only do it when absolutely necessary (lazily).
There are a number of invalidateLayout functions related to this class but none of them cause an actual re-layout when called.
I know this comes late, but I ran into this issue and thought I should share what I came up with in case others find themselves in the same situation.
You are on the right track, but in textViewDidChange: you are missing one important thing: setting the contentSize after updating the frame height.
// I used 0.f for the height, but you can use another value because according to the docs:
// "the actual bounding rectangle returned by this method can be larger
// than the constraints if additional space is needed to render the entire
// string. Typically, the renderer preserves the width constraint and
// adjusts the height constraint as needed."
CGSize size = CGSizeMake(textview.frame.size.width, 0.f);
CGRect rect = [string boundingRectWithSize:size
options:OptionsYouNeedIfAny // NSStringDrawingOptions
context:nil];
// Where MinTextViewHeight is the smallest height for a textView that
// your design can handle
CGFloat height = MAX(ceilf(rect.size.height), MinTextViewHeight);
CGRect rect = textView.frame;
rect.size.height = height;
textView.frame = rect;
// Adjusting the textView contentSize after updating the frame height is one of the things you were missing
textView.contentSize = textView.frame.size;
textView.contentOffset = CGPointZero;
I hope this helps!
See the docs for more info about using boundingRectWithSize:options:context:.

How to get the size of a NSString

A "quicky": how can I get the size (width) of a NSString?
I'm trying to see if the string width of a string to see if it is bigger than a given width of screen, case in which I have to "crop" it and append it with "...", getting the usual behavior of a UILabel. string.length won't do the trick since AAAAAAAA and iiiiii have the same length but different sizes (for example).
I'm kind of stuck.
Thanks a lot.
This is a different approach. Find out the minimum size of the text so that it won't wrap to more than one line. If it wraps to over one line, you can find out using the height.
You can use this code:
CGSize maximumSize = CGSizeMake(300, 9999);
NSString *myString = #"This is a long string which wraps";
UIFont *myFont = [UIFont fontWithName:#"Helvetica" size:14];
CGSize myStringSize = [myString sizeWithFont:myFont
constrainedToSize:maximumSize
lineBreakMode:self.myLabel.lineBreakMode];
300 is the width of the screen with a little space for margins. You should substitute your own values for font and size, and for the lineBreakMode if you're not using IB.
Now myStringSize will contain a height which you can check against the height of something you know is only 1 line high (using the same font and size). If it's bigger, you'll need to cut the text. Note that you should add a ... to the string before you check it again (adding the ... might push it over the limit again).
Put this code in a loop to cut the text, then check again for the correct height.
Use below method.
Objective-C
- (CGSize)findHeightForText:(NSString *)text havingWidth:(CGFloat)widthValue andFont:(UIFont *)font {
CGSize size = CGSizeZero;
if (text) {
CGRect frame = [text boundingRectWithSize:CGSizeMake(widthValue, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:#{ NSFontAttributeName:font } context:nil];
size = CGSizeMake(frame.size.width, frame.size.height + 1);
}
return size;
}
Swift 3.0
func findHeight(forText text: String, havingWidth widthValue: CGFloat, andFont font: UIFont) -> CGSize {
var size = CGSizeZero
if text {
var frame = text.boundingRect(withSize: CGSize(width: widthValue, height: CGFLOAT_MAX), options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
size = CGSize(width: frame.size.width, height: frame.size.height + 1)
}
return size
}
You need to use Core Graphics to measure the string, as rendered in your specified font and size. See the answers to Measuring the pixel width of a string for a walkthrough.
sizeWithFont:constrainedToSize:lineBreakMode
is deprecated now. Use below code snippet,
UIFont *font=[UIFont fontWithName:#"Arial" size:16.f];
NSString *name = #"APPLE";
CGSize size = [name sizeWithAttributes:#{NSFontAttributeName:font}];
For whatever its worth --- I think the OP takes the wrong way to get there... if the measurement of width only serves to find the place where text should be clipped, and followed by ellipsis --- then OP should be aware of that this facility is implemented in all Text Views in Cocoa...
Pay attention to this enumeration:
typedef NS_ENUM(NSUInteger, NSLineBreakMode) {
NSLineBreakByWordWrapping = 0, // Wrap at word boundaries, default
NSLineBreakByCharWrapping, // Wrap at character boundaries
NSLineBreakByClipping, // Simply clip
NSLineBreakByTruncatingHead, // Truncate at head of line: "...wxyz"
NSLineBreakByTruncatingTail, // Truncate at tail of line: "abcd..."
NSLineBreakByTruncatingMiddle // Truncate middle of line: "ab...yz"
} API_AVAILABLE(macos(10.0), ios(6.0), watchos(2.0), tvos(9.0));
By setting the line breaking mode of your text-field or text view to NSLineBreakByTruncatingTail, you'll achieve what you want, and probably at higher quality, without implementing yourself.

NSString sizeWithFont: returning inconsistent results? known bug?

I'm trying to create a simple custom UIView wich contain a string drawn with a single font, but where the first character is slightly larger.
I thought this would be easily implemented with two UILabel:s placed next to eachother.
I use NSString sizeWithFont to measure my string to be able to lay it out correctly.
But I noticed that the font baseline in the returned rectangle varies with +/- 1 pixel depending on the font size I set.
Here is my code:
NSString* ctxt = [text substringToIndex:1];
NSString* ttxt = [text substringFromIndex:1];
CGSize sz = [ctxt sizeWithFont: cfont ];
clbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, sz.width, sz.height)];
clbl.text = ctxt;
clbl.font = cfont;
clbl.backgroundColor = [UIColor clearColor];
[contentView addSubview:clbl];
CGSize sz2 = [ttxt sizeWithFont: tfont];
tlbl = [[UILabel alloc] initWithFrame:CGRectMake(sz.width, (sz.height - sz2.height), sz2.width, sz2.height)];
tlbl.text = ttxt;
tlbl.font = tfont;
tlbl.backgroundColor = [UIColor clearColor];
[contentView addSubview:tlbl];
If I use 12.0 and 14.0 as sizes, it works fine.
But if I instead use 13.0 and 15.0, then the first character is 1 pixel too high.
Is this a known problem?
Any suggestions how to work around it?
Creating a UIWebView with a CSS and HTML page seems way overkill for this. and more work to handle dynamic strings. Is that what I'm expected to do?
Found the answer...
Ofcourse, I also have to check the descender value on the font, and compensate for that in the layout.
New rect for the second label is:
CGRectMake(sz.width, (sz.height - sz2.height) + floor(cfont.descender - tfont.descender), sz2.width, sz2.height)
floor() is to make sure it snaps to pixel position, or the font will look blurry