如何在UITextView中损失保证金/填充?
我的iOS应用程序中有一个UITextView
,它显示大量的文本。 然后我使用UITextView
的偏移量边界参数来分页这个文本。 我的问题是,填充的UITextView
混淆了我的计算,因为它似乎是不同的,取决于我使用的字体大小和字体。
因此,我提出了这样一个问题:是否可以删除UITextView
内容的填充?
期待听到你的回应!
2017年
这是iOS中最荒谬的错误之一。
UITextViewFixed
是一个通常合理的解决scheme:
@IBDesignable class UITextViewFixed: UITextView { override func layoutSubviews() { super.layoutSubviews() setup() } func setup() { textContainerInset = UIEdgeInsets.zero textContainer.lineFragmentPadding = 0 } }
不要忘记在Inspector中closuresscrollEnabled!
这在storyboard中正常工作,因为你在Xcode中工作。
就是这样,你完成了。
一般来说, 在大多数情况下 , 这应该是你所需要的 ,甚至包括即时改变文本视图的高度,例如用户input。
来自Apple的UITextView无法使用…
UITextViewFixed
几乎在所有情况下都是可以修复的:
(为清楚起见,添加了黄色。)请注意,当然您必须
在Inspector中closuresscrollEnabled!
不要忘记closuresscrollEnabled!
而且还有那个“底层空间”的问题
在某些情况下 – 特别是当使用灵活的单元格高度表格视图进行自动布局时,会随着您的变化而变化 – 苹果公司是世界上最令人愤慨的事情,
他们在底部增加额外的空间。
这将是iOS中最令人不快的事情之一。
这是疯狂的“快速解决”。
@IBDesignable class UITextViewFixedWithKludge: UITextView { override func layoutSubviews() { super.layoutSubviews() setup() } func setup() { textContainerInset = UIEdgeInsets.zero textContainer.lineFragmentPadding = 0 // this is not ideal, but you can sometimes use this // to fix the "space at bottom" insanity var b = bounds let h = sizeThatFits(CGSize( width: bounds.size.width, height: CGFloat.greatestFiniteMagnitude) ).height b.size.height = h bounds = b } }
笔记:
(1)有时,为了修复又一个微妙的苹果混乱,你必须添加这个:
override func setContentOffset(_ contentOffset: CGPoint, animated: Bool) { super.setContentOffset(contentOffset, animated: false) }
(2)可以说,我们应该加上:
contentInset = UIEdgeInsets.zero
(只是在textContainer.lineFragmentPadding = 0
之后做)然而…它在当前的iOS中不起作用 ! 在将来的操作系统版本中可能需要添加。
事实上, UITextView
在iOS中完全被破坏是所有移动计算中最奇怪的事情之一。
最后,对于文本字段 ,这里有点类似的提示: https : //stackoverflow.com/a/43099816/294884
对于iOS 7.0,我发现contentInset技巧不再适用。 这是我用来摆脱iOS 7中的边距/填充的代码。
这将文本的左边缘带到容器的左边缘:
self.textView.textContainer.lineFragmentPadding = 0
这会导致文本的顶部与容器的顶部alignment
self.textView.textContainerInset = .zero
两条线都需要完全删除边距/填充。
这个解决方法是在2009年IOS 3.0发布时编写的。 它不再适用。
我遇到了同样的问题,最后我不得不结束使用
nameField.contentInset = UIEdgeInsetsMake(-4,-8,0,0);
其中nameField是一个UITextView
。 我碰巧使用的字体是Helvetica 16点。 它是我绘制的特定字段大小的唯一定制解决scheme。 这使得左侧的偏移量与左侧齐平,并且顶部偏移量在我们希望盒子被吸引的位置处。
此外,这似乎只适用于您使用默认的颜色,即UITextViews
。
nameField.textAlignment = NSTextAlignmentLeft;
例如右边的alignment, UIEdgeInsetsMake
似乎对右边没有任何影响。
至less,使用.contentInset属性允许您将字段放在“正确”的位置,并适应偏差而不会偏移您的UITextViews
。
build立一些已经给出的好的答案,这里是一个纯粹的基于Interface Builder的解决scheme,利用用户定义的运行时属性,并在iOS 7.0+中工作:
在iOS 5上, UIEdgeInsetsMake(-8,-8,-8,-8);
似乎很好。
我肯定会避免涉及硬编码值的任何答案,因为实际边距可能会随用户字体大小设置等而改变。
这里是@ user1687195的答案,没有修改textContainer.lineFragmentPadding
(因为文档状态这不是预期的用法)编写的。
这适用于iOS 7及更高版本。
self.textView.textContainerInset = UIEdgeInsetsMake( 0, -self.textView.textContainer.lineFragmentPadding, 0, -self.textView.textContainer.lineFragmentPadding);
这实际上是相同的结果,只是有点清洁,它不会滥用lineFragmentPadding属性。
所有这些答案都是针对标题问题,但我想就OP的问题提出一些解决办法。
文本内容的大小
计算UITextView
本大小的一种快速方法是使用NSLayoutManager
:
UITextView *textView; CGSize textSize = [textView usedRectForTextContainer:textView.textContainer].size;
这给出了总滚动内容,可能比UITextView
的框架更大。 我发现这比textView.contentSize
更准确,因为它实际上计算了文本占用了多less空间。 例如,给定一个空的UITextView
:
textView.frame.size = (width=246, height=50) textSize = (width=10, height=16.701999999999998) textView.contentSize = (width=246, height=33) textView.textContainerInset = (top=8, left=0, bottom=8, right=0)
线高度
UIFont
有一个属性,可以快速让您获得给定字体的行高。 所以你可以快速find你的UITextView
文本的行高度:
UITextView *textView; CGFloat lineHeight = textView.font.lineHeight;
计算可见文本大小
确定实际可见的文本的数量对于处理“分页”效果是重要的。 UITextView
有一个名为textContainerInset
的属性,它实际上是实际的UITextView.frame
和文本本身之间的边距。 要计算可见框架的实际高度,可以执行以下计算:
UITextView *textView; CGFloat textViewHeight = textView.frame.size.height; UIEdgeInsets textInsets = textView.textContainerInset; CGFloat textHeight = textViewHeight - textInsets.top - textInsets.bottom;
确定寻呼大小
最后,现在你已经有了可见的文本大小和内容,你可以通过从textSize
减去textHeight
来快速确定你的偏移量:
// where n is the page number you want CGFloat pageOffsetY = textSize - textHeight * (n - 1); textView.contentOffset = CGPointMake(textView.contentOffset.x, pageOffsetY); // examples CGFloat page1Offset = 0; CGFloat page2Offset = textSize - textHeight CGFloat page3Offset = textSize - textHeight * 2
使用所有这些方法,我没有碰到我的插页,我可以去插入或我想要的文本中的任何地方。
Storyboard或Interface Builder解决scheme,使用用户定义的运行时属性。 更新。 contentInset = {{-10,-5},{0,0}}添加了iOS7.1和iOS6.1屏幕截图
你可以使用UITextView
textContainerInset
属性:
textView.textContainerInset = UIEdgeInsetsMake(10,10,10,10);
(顶部,左侧,底部,右侧)
对于iOS 10,以下行适用于顶部和底部填充删除。
captionTextView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0)
请注意,将其更改为右侧的UIEdgeInset.zero不起作用
做插入的解决scheme,我仍然有填充右侧和底部。 另外文本alignment导致问题。 我发现的唯一可靠的方法是将文本视图放在另一个视图中,并将其限制在界限内。
textView滚动也会影响文本的位置,并使其看起来不是垂直居中。 我设法通过禁用滚动并将顶部插入设置为0来将文本居中在视图中:
textView.scrollEnabled = NO; textView.textContainerInset = UIEdgeInsetsMake(0, textView.textContainerInset.left, textView.textContainerInset.bottom, textView.textContainerInset.right);
出于某种原因,我还没有弄清楚,在打字开始之前光标仍然不居中,但是当我开始打字时文本立即居中。
对于迅速4,Xcode 9
使用以下函数可以更改UITextView中文本的边距/填充
public func UIEdgeInsetsMake(_ top:CGFloat,_ left:CGFloat,_ bottom:CGFloat,_ right:CGFloat) – > UIEdgeInsets
所以在这种情况下是
self.textView?.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0)
我发现了另一种方法,从UITextView的子视图中获取文本并在子类的layoutSubview方法中设置它:
- (void)layoutSubviews { [super layoutSubviews]; const int textViewIndex = 1; UIView *textView = [self.subviews objectAtIndex:textViewIndex]; textView.frame = CGRectMake( kStatusViewContentOffset, 0.0f, self.bounds.size.width - (2.0f * kStatusViewContentOffset), self.bounds.size.height - kStatusViewContentOffset); }
[firstNameTextField setContentVerticalAlignment:UIControlContentVerticalAlignmentCenter];