UITextView not being shown in iOS versions below 7.1
Well, this was a tricky one. By reading through some questions of the time of the switch from iOS 6 to iOS 7 I figured that setting [self.textView setScrollEnabled:NO]
solved the problem in iOS 7.0, but apparently this 'feature' got fixed in 7.1, so having that line of code broke everything in 7.1, the outer view didn't even load. So I had to include a version check to support iOS 7.0 and 7.1 at the same time:
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7.1f) {
[self.textView setScrollEnabled:NO];
}
It would also most likely not work on iOS 6, but my app doesn't support it anyway.
Customise embedded hyperlink in UITextView using Swift iOS13
Changing the extension to this:
extension UITextView {
func hyperLink(originalText: String, hyperLink: String, urlString: String) {
let style = NSMutableParagraphStyle()
style.alignment = .center
let attributedOriginalText = NSMutableAttributedString(string: originalText)
let linkRange = attributedOriginalText.mutableString.range(of: hyperLink)
let fullRange = NSMakeRange(0, attributedOriginalText.length)
attributedOriginalText.addAttribute(NSAttributedString.Key.link, value: urlString, range: linkRange)
attributedOriginalText.addAttribute(NSAttributedString.Key.paragraphStyle, value: style, range: fullRange)
attributedOriginalText.addAttribute(NSAttributedString.Key.font, value: UIFont.systemFont(ofSize: 11), range: fullRange)
self.linkTextAttributes = [
kCTForegroundColorAttributeName: UIColor.black,
kCTUnderlineStyleAttributeName: NSUnderlineStyle.single.rawValue,
] as [NSAttributedString.Key : Any]
self.attributedText = attributedOriginalText
}
}
Is working for me. I simply removed the attributed text attributes that changed the foreground and background colors. I'm not sure why they were there to begin with.
UITextView text not starting from top
Set the Content Inset like this in your UITextView
youtextView.contentInset = UIEdgeInsetsMake(-7.0,0.0,0,0.0);
Adjust the Top value the way you want. this shoud fix your problem.
EDIT:
If you're having issues with iOS7 or above, try using...
[yourTextView setContentOffset: CGPointMake(x,y) animated:BOOL];
Redrawing UITextView selection after changing paragraph style
It is a bit late, but maybe it helps you or others....
You can change the selection through the UITextInput-Protocol by setting the selectedTextRange .
let beginning: UITextPosition = textView.beginningOfDocument
let start: UITextPosition = textView.positionFromPosition(beginning, offset: textView.selectedRange.location)
let end: UITextPosition = textView.positionFromPosition(start!, offset: textView.selectedRange.length)
textView.selectedRange = NSMakeRange(0, 0)
textView.selectedTextRange = textView.textRangeFromPosition(start!, toPosition: end!)
P.S. My code is written in Swift, but I think it is no problem to convert that to objective c, or?
How to lose margin/padding in UITextView
Up-to-date for 2021
It is one of the silliest bugs in iOS.
The class given here, UITextViewFixed
, is used widely, and is usually the most reasonable solution overall.
Here is the class:
@IBDesignable class UITextViewFixed: UITextView {
override func layoutSubviews() {
super.layoutSubviews()
setup()
}
func setup() {
textContainerInset = UIEdgeInsets.zero
textContainer.lineFragmentPadding = 0
}
}
Don't forget to turn off scrollEnabled in the Inspector!
The solution works properly in storyboard
The solution works properly at runtime
That's it, you're done.
In general, that should be all you need in most cases.
Even if you are changing the height of the text view on the fly, UITextViewFixed
usually does all you need.
(A common example of changing the height on the fly, is changing it as the user types.)
Here is the broken UITextView from Apple...
Here is UITextViewFixed
:
Note that of course you must...
...turn off scrollEnabled in the Inspector!
(Turning on scrollEnabled means "make this view expand as much as possible vertically by expanding the bottom margin as much as possible.")
Some further issues
(1) In some very unusual cases dynamically changing heights, Apple does a bizarre thing: they add extra space at the bottom.
No, really! This would have to be one of the most infuriating things in iOS.
If you encounter the problem, here is a "quick fix" which usually helps:
...
textContainerInset = UIEdgeInsets.zero
textContainer.lineFragmentPadding = 0
// this is not ideal, but sometimes this "quick fix"
// will solve the "extra space at the bottom" insanity:
var b = bounds
let h = sizeThatFits(CGSize(
width: bounds.size.width,
height: CGFloat.greatestFiniteMagnitude)
).height
b.size.height = h
bounds = b
...
(2) In rare cases, to fix yet another subtle mess-up by Apple, you have to add:
override func setContentOffset(_ contentOffset: CGPoint, animated: Bool) {
super.setContentOffset(contentOffset, animated: false) // sic
}
(3) Arguably, we should be adding:
contentInset = UIEdgeInsets.zero
just after .lineFragmentPadding = 0
in UITextViewFixed
.
However ... believe or not ... that just doesn't work in current iOS! (Checked 2021.) It may be necessary to add that line in the future.
The fact that UITextView
is broken in iOS is one of the weirdest things in all of mobile computing. Ten year anniversary of this question and it's still not fixed!
Finally, here's a somewhat similar tip for TextField: Set the maximum character length of a UITextField in Swift
Completely random tip: how to add the "..." on the end
Often you are using a UITextView "like a UILabel". So you want it to truncate text using an ellipsis, "..."
If so, add:
textContainer.lineBreakMode = .byTruncatingTail
Handy tip if you want zero height, when, there's no text at all
Often you use a text view to only display text. So, you use lines "0" to mean the text view will automatically change height depending on how many lines of text.
That's great. But if there is no text at all, then unfortunately you get the same height as if there is one line of text!!!! The text view never "goes away".
If you want it to "go away", just add this
override var intrinsicContentSize: CGSize {
var i = super.intrinsicContentSize
print("for \(text) size will be \(i)")
if text == "" { i.height = 1.0 }
print(" but we changed it to \(i)")
return i
}
(I made it '1' height, so it's clear what's going on in that demo, '0' is fine.)
What about UILabel?
When just displaying text, UILabel has many advantages over UITextView. UILabel does not suffer from the problems described on this Q&A page.
Indeed the reason we all usually "give up" and just use UITextView is that UILabel is difficult to work with. In particular it is ridiculously difficult to just add padding, correctly, to UILabel.
In fact here is a full discussion on how to "finally" correctly add padding to UILabel: Adding space/padding to a UILabel. In some cases if you are doing a difficult layout with dynamic height cells, it is sometimes better to do it the hard way with UILabel.
Related Topics
Segues Initiated Directly from View Controllers Warning in Storyboard Xcode
iOS Autolayout - Frame Size Not Set in Viewdidlayoutsubviews
How to Find Out the Objective-C Generics Type
In-App Purchase Sandbox Environment Loop
How to Evaluate the String Equation in iOS
Game Engine Collison Bitmask... Why 0X01 etc
Swift Unsafemutablepointer<Unmanaged<Cfstring>> Allocation and Print
How to Check Text Field Input at Real Time
Change Pin Image on Mkmapview in Swift
Swiftui: How to Get Continuous Updates from Slider
Remove Uiwebview's Internal Cache
Pass Uicollectionview Touch Event to Its Parent Uitableviewcell
Autolayout: Origin and Size Should Change According to Width and Height Factor
Understanding Model-View-Controller
Uiwebview Not Go to Didfailloadwitherror When Weblink Not Found