如何在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无法使用…

IB与UITextView截图

UITextViewFixed几乎在所有情况下都是可以修复的:

IB和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];