我的iOS应用程序中有一个UITextView,它显示大量文本.

然后,我使用UITextView的偏移页边距参数对此文本进行分页.

我的问题是,UITextView的填充混淆了我的计算,因为根据我使用的字体大小和字样,它似乎是不同的.

是否可以移除UITextView的内容物周围的填充物?

推荐答案

Up-to-date for 2021

它是iOS中最愚蠢的漏洞之一.

这里给出的类,UITextViewFixed,使用广泛,通常是most reasonable solution overall.

下面是班级:

@IBDesignable class UITextViewFixed: UITextView {
    override func layoutSubviews() {
        super.layoutSubviews()
        setup()
    }
    func setup() {
        textContainerInset = UIEdgeInsets.zero
        textContainer.lineFragmentPadding = 0
    }
}

别忘了在判断器中关闭ScrollEnabled!

  1. 该解决方案在情节提要中正常工作

  2. 该解决方案在运行时正常工作

That's it, you're done.

一般来说,that should be all you need in most cases.

即使您要更改文本视图的高度,on the flyUITextViewFixed通常也能满足您的所有需要.

(飞翔上更改高度的一个常见示例是随着用户的键入而更改高度.)

这是苹果公司损坏的UITextView...

Screenshot of Interface Builder with UITextView

下面是UITextViewFixed条:

Screenshot of Interface Builder with UITextViewFixed

请注意,您当然必须...

...turn off scrollEnabled in the Inspector!

(打开scroll Enabled意味着"通过尽可能扩大底部页边距,使此视图在垂直方向上尽可能地展开".)


Some further issues

(1) 在一些非常罕见的动态变化高度的情况下,苹果做了一件奇怪的事情:100.

不,真的!这肯定是iOS中最令人恼火的事情之一.

如果你遇到问题,这里有一个"快速解决方案",通常会有帮助:

...
        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) 在极少数情况下,要解决苹果的另一个微妙问题,你必须补充:

override func setContentOffset(_ contentOffset: CGPoint, animated: Bool) {
    super.setContentOffset(contentOffset, animated: false) // sic
}

(3)可以说,我们should增加了:

contentInset = UIEdgeInsets.zero

UITextViewFixed年刚过.lineFragmentPadding = 0.

然而信不信由你...在当前的iOS中是100!(判断2021)将来可能有必要增加这一行.

在iOS中打破UITextView是所有移动计算中最奇怪的事情之一.这个问题已经十周年了,现在还没有解决!

最后,这里是针对TextField的一个有点类似的提示:100

Completely random tip: how to add the "..." on the end

通常,您使用的UITextView"就像UILabel一样".所以你想让它用省略号来截断文本,"…"

如果是,请添加:

 textContainer.lineBreakMode = .byTruncatingTail

Handy tip if you want zero height, when, there's no text at all

通常,您使用文本视图仅显示文本.因此,您使用行"0"表示文本视图将根据文本的行数自动更改高度.

太好了.但是if there is no text at all,那么不幸的是你会得到同样高的as if there is one line of text!文本视图永远不会"消失".

Enter image description here

如果你想让它"消失",只需添加这个

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
}

Enter image description here

(我把它设为"1"高,所以很清楚演示中发生了什么,"0"就可以了.)

What about UILabel?

当只显示文本时,UILabel比UITextView有很多优点.UILabel不存在本问答页面中描述的问题.

事实上,我们通常都会"放弃"而只使用UITextView的原因是UILabel很难使用.尤其是,要在UILabel中正确地添加padding是非常困难的.

事实上,这里有关于如何"最终"正确地向UILabel:100添加填充的完整讨论.在某些情况下,如果您正在使用动态高度单元格进行困难的布局,有时使用UILabel进行困难的布局会更好.

Ios相关问答推荐

如何在进行滑动删除操作时保持自定义视图背景静态

Flutter WebRTC:GetUserMedia()不适用于Safari和IOS设备

我想在expo 中使用useSafeAreaInsets来获取paddingbottom,但我得到了一个错误

当重新呈现UI时,嵌套的 struct 值如何与@Observable一起工作?

SwiftUI图表-默认情况下,X轴数据点的间距不相等

SwiftUI-工作表不显示导航标题

Swift - 缺少函数参数在编译期间不会失败,甚至会导致不同的数据类型?

如何在 Mac OS Ventura 中使用 Xcode 13

我正在try 制作一种 Select 器样式,例如设置中的外观 Select 器

小部件链接有效,但不执行任何操作

转换在 NavigationView 中不起作用

无法结合 UIImageView 旋转动画和 tableView 部分重新加载

iOS,Swift 5,AppDelegate open url / .onOpenUrl - 如何找到调用我的自定义方案的调用应用程序

将flutter android项目导入iOS

快速禁用 UITextfield 的用户输入

UICollectionView - 动态单元格高度?

Watchkit AppIcon - 名为AppIcon的应用图标集没有任何适用的内容

如何更新推送通知服务证书

UIView 动画与 CALayers

在 React Native 中保存敏感数据