I'm making an application for iOS 7 and iOS 8 and I would like to disable word wrapping in my UITextView. I have some ASCII tables and I don't want them broken.
I didn't find the option in the StoryBoard and I tried to do it programatically. I have tried:
[textView setContentSize:[[textView attributedText] size]];
and
[textView.textContainer setSize:[[textView attributedText] size]];
Nothing seems to be working.
The UITextView was created for this exact functionality that you are trying to remove. It might be that the UITextView is not the best option based on your use case. There are many ways to accomplish this without the use of UITextView. Here are a few:
1) If the text is not going to be editable, you could use a UILabel. Set the Number Of Lines = 0 and appropriate settings for Line Breaks and Autoshrink.
2) If the text needs to be editable, you should use a UITextField inside of a UIScrollView.
3) Make a custom UIView that calculates the space needed and draw the text yourself. (This option is the most robust, but usually is not necessary and can introduce and handful of issues. The afore mentioned controls will have this type of logic already worked out for you by Apple).
Hope this helps.
I'm not sure exactly what your interface looks like, but here are a few options:
You could either try this answer to detect a word wrap and go from there.
Word wrap detecting in UITextView
It might work for you. Or try using a bezier path to draw the line how you want it. Or NSTextContainer like here Adding exclusion paths to multiple text views
CGSize txtSize = [editor sizeThatFits:CGSizeMake(0, 0)];
editor.frame = CGRectMake(0, 0, txtSize.width, self.frame.size.height);
self.contentSize = CGSizeMake(txtSize.width, self.frame.size.height);
Here "self" is a UIScrollView and will scroll the UITextView horizontally. "editor" is a UITextView and will scroll itself vertically.
You can also "disable" word-wrap in UITextView by putting it inside UIScrollView and setting
textView.isScrollEnabled = false
The question specifies the need for horizontal scrolling, but if you want to simply disable word wrapping and cut off the text that doesn't fit, you can do this:
let attributedString = NSMutableAttributedString(string: your_string)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = .byClipping // .byTruncatingTail also works
attributedString.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, attributedString.length))
your_text_view.attributedString = attributedString
Related
It seems impossible to get the UILabel to adhere to the constraints in the way that I want it to consistently. The leading and trailing space constraints seem in effect but the label is just truncating the lines instead of expanding to new lines.
I do have the numberOfLines of the UILabel set to 0. I have also tried the suggestion listed here: UILabel not wrapping text correctly sometimes (auto layout) and it didn't seem to work reliably. The last thing I tried was setting the setContentCompressionResistancePriority property to Fitted and Low but it doesn't work for everything in the UITableView at the same time. In fact, depending on if the tableview gets refreshed, it looks like all the wrapping can get undone.
The only thing that I tried that seemed to work well was to set the preferredMaxLayoutWidth of the UILabel to a constant. I was just hoping to use it as a last resort to avoid calculating how wide the label should be at runtime. Surely, there's an out of the box way to get what I want.
The key to getting it to work correctly was to ask the view to reset the layout after the constraints had been applied and all the text had been set. I merely added these lines to my custom UITableViewCell after I had set the data that it needed:
//set data
//set constraints
...
contentView.setNeedsLayout()
contentView.layoutIfNeeded()
}
I realized this was the solution because the view kept reporting their initial frame sizes instead of sizes after being affected by their constraints. For some reason, all the other views looked correct but not the UILabels.
I found the solution in the answer posted here: https://stackoverflow.com/a/13542580/1637033
You can calculate height of of the UILabel runtime as per the content
func heightForLabel(text:String, font:UIFont, width:CGFloat) -> CGFloat
{
let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.ByWordWrapping
label.font = font
label.text = text
label.sizeToFit()
return label.frame.height
}
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.
While typing in a UITextView sometimes it scrolls down to current line(case a) but it doesn't the other times(case b).
There's another problem which is:
The same UITextView sometimes show all the text in it (case 1) but other times it doesn't show the last line of text(case 2).
Whenever case 1 happens case a follows.
and Whenever case 2 happens case b follows.
This is the hierarchy of the view:
Size(variable height-fixed width) of these UITextViews as well as UICollectionViewCells are calculated using sizeWithFont:constrainedToSize:lineBreakMode:
Limits of height are set from 43 to 120.
if height>43 then enableScrolling is set to YES, otherwise to NO(Logic X).
Scrolling is enabled when textViewBeginEditing and Logic X is applied when textViewEnded Editing.
There is no scrolling in case 2.
Please suggest cause and workarounds.
On iOS7, I think that you could leave the UITextView's scrollEnabled property set to YES in all cases. If it contains less text it will just not scroll. If you set the property while configuring the cell, you might get this kind of weird behavior, because UIKit is reusing those cells and probably the UITextView too.
For making the last line visible, I'm guessing you need to calculate the text view size more accurately. Try using the attributedText to set the text, with all the formatting you need. Then, in order to calculate the size, you can do it like this:
NSAttributedString *text = self.yourCellsTextView.attributedText;
UITextView *calculationView = [[UITextView alloc] init];
[calculationView setAttributedText:text];
CGSize size = [calculationView sizeThatFits:CGSizeMake(self.yourCellsTextView.frame.size.width, FLT_MAX)];
CGFloat finalMessageHeight = size.height;
Hope this helps :).
I have a UITextView with Content and frame size widths equal to 348, but word wrapping happens whenever text width on a line exceeds 338.61. Does anyone know why this might be happening? How can I access the width that the UITextView uses for word wrapping dynamically?
As of iOS 7, yes. It's a combination of textContainerInset and lineFragmentPadding.
UITextView *textView = ...;
CGFloat wrappingWidth = textView.bounds.size.width - (textView.textContainerInset.left + textView.textContainerInset.right + 2 * textView.textContainer.lineFragmentPadding);
Which is a nice value to know about. You can use it in boundingRectWithSize: calls, for example:
CGRect boundingRect = [text boundingRectWithSize:CGSizeMake(wrappingWidth, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin // this is important
attributes:#{ NSFontAttributeName: textView.font } // and any other attributes of your text
context:nil];
Also cool is the fact that you can set textContainerInset and lineFragmentPadding, so if you want to increase this or have a UITextView that renders with no insets (so it matches a UILabel, for example), you can.
Nothing wrong with the answer above but I have been researching the UITextView word wrapping behavior and have discovered that although one can adjust the contentSize of the textview and the corresponding size of the textContainer, one additional method of changing the text wrap position (when using Auto Layout) is to make the trailing space to the SuperView into a negative value. This will allow one to push the word wrapping feature outward to the right. Not finished with the research just yet, but this tip should help anyone seeking to better control the UITextView word wrapping behavior.
Will post code once I'm complete but for now adjusting the trailing constraint of a UITextView will move the rightmost position of the word/character wrap.
I'm currently developing an iPad application and want to apply a custom font to the UIButtons on a certain screen. I have noticed similar problems with other screens, namely that the text on some (seemingly random) UIButtons disappears. In this case, the custom font is being applied to some buttons but not others, again there doesn't seem to be any pattern as to which buttons work and which don't. I've attached a screenshot below to try to give you an idea of what exactly I mean.
As I've mentioned, on some other screens I have noticed text completely disappearing from some buttons and have had to replace these with images featuring the text instead.
All buttons are created in Interface Builder. They use attributed text to allow multiple lines and centred alignment. Any help would be much appreciated.
edit - my code is like the following:
for (UIView *sub in view.subviews) {
UIButton *btn = (UIButton *) sub;
UILabel *lbl = [btn titleLabel];
[lbl setFont: myFont size: mySize];
}
To use attributed insure the IB items are set to use attributed text, not plain text.
To set the attributed title for a NSButton use:
- (NSAttributedString *)attributedTitleForState:(UIControlState)state
for a NSLabel use:
#property(nonatomic,copy) NSAttributedString *attributedText
Of course you may not need attributed text is all you are doing is just setting a font and alignment.
For multiple lines of text set:
#property(nonatomic) NSInteger numberOfLines
as appropriate.
From the comments:
You can achieve centered and multiline title labels in UIButtons without using NSAttributedStrings by adding the following lines to your for loop:
lbl.textAlignment = UITextAlignmentCenter;
lbl.numberOfLines = 0;