NSAttributedString 未按时呈现 - Swift
NSAttributedString not rendering on time - Swift
所以,我在一个项目中遇到了一些问题,其中某些字符串在某些具有某些 iOS 版本的旧 iPhone 中无法正确呈现(特别是它不适用于 iPhone 5 和 iOS10,而它对 iOS9.3 有效,这很奇怪)。为了减少这个问题,我写了这段代码:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Long HTML, although we'll make it even larger to prove a point
let string = "<h1>Thing 1</h1><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </p><h1>Thing 2</h1><p>Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. </p><h1>Thing 3</h1><p>Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. </p><h1>Thing 4</h1><p>Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. </p><h1>Thing 5</h1><p>Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor, cursus quis, aliquet eget, justo. Sed pretium blandit orci. </p><h1>Thing 6</h1><p>Ut eu diam at pede suscipit sodales. Aenean lectus elit, fermentum non, convallis id, sagittis at, neque. Nullam mauris orci, aliquet et, iaculis et, viverra vitae, ligula. Nulla ut felis in purus aliquam imperdiet. Maecenas aliquet mollis lectus. Vivamus consectetuer risus et tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. </p>"
let attrStr = try! NSAttributedString(
data: (string + string + string + string + string + string + string + string).data(using: String.Encoding.unicode,allowLossyConversion: true)!,
options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
documentAttributes: nil)
label.attributedText = attrStr
label.backgroundColor = UIColor(red:0.00, green:1.00, blue:0.00, alpha:1.0)
}
}
很简单。当然实际问题比这更复杂,但是思路是一样的。
因此,在 iPhone 7 中,一切正常:
然而,在 iPhone 4s 上加载时:
调试时,attrStr
似乎在两种情况下都已正确设置。
有什么想法吗?我的理论是旧手机太慢无法按时呈现,但我不太确定如何解决这个问题。
谢谢!
编辑:对于那些提问的人,这是故事板:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="JzW-qG-LFG">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="9PR-d2-hNU">
<objects>
<viewController id="JzW-qG-LFG" customClass="ViewController" customModule="things" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="VGp-YT-QQN"/>
<viewControllerLayoutGuide type="bottom" id="SeT-t7-CD0"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="gtg-CO-E9d">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Id1-A1-RaT">
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="trailingMargin" secondItem="Id1-A1-RaT" secondAttribute="trailing" id="0qp-Rk-PC2"/>
<constraint firstItem="Id1-A1-RaT" firstAttribute="leading" secondItem="gtg-CO-E9d" secondAttribute="leadingMargin" id="3Vc-he-HqH"/>
<constraint firstItem="Id1-A1-RaT" firstAttribute="top" secondItem="VGp-YT-QQN" secondAttribute="bottom" id="7IE-fY-4H0"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="Opz-px-hsl"/>
<connections>
<outlet property="label" destination="Id1-A1-RaT" id="TNv-G9-ASE"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="qlV-6d-ISJ" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2848.8000000000002" y="-280.20989505247377"/>
</scene>
</scenes>
</document>
您没有提供任何关于故事板的详细信息,或者 label
的设置或限制。
所以我以编程方式启动了标签,这个解决方案适用于 iPhone 4s 运行 iOS 9.3:
这是工作源代码:
override func viewDidLoad() {
super.viewDidLoad()
label = UILabel(frame: CGRect(x: 0.0, y: 44.0, width: view.frame.size.width, height: view.frame.size.height - 88.0))
label.numberOfLines = 0
label.isUserInteractionEnabled = false
label.contentMode = .left
label.textAlignment = .natural
label.lineBreakMode = .byTruncatingTail
label.baselineAdjustment = .alignBaselines
label.adjustsFontSizeToFitWidth = false
// label.translatesAutoresizingMaskIntoConstraints = false //setting this causes the text to be layout wrong
label.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
view.addSubview(label)
// Long HTML, although we'll make it even larger to prove a point
let string = "<h1>Thing 1</h1><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </p><h1>Thing 2</h1><p>Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. </p><h1>Thing 3</h1><p>Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. </p><h1>Thing 4</h1><p>Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. </p><h1>Thing 5</h1><p>Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor, cursus quis, aliquet eget, justo. Sed pretium blandit orci. </p><h1>Thing 6</h1><p>Ut eu diam at pede suscipit sodales. Aenean lectus elit, fermentum non, convallis id, sagittis at, neque. Nullam mauris orci, aliquet et, iaculis et, viverra vitae, ligula. Nulla ut felis in purus aliquam imperdiet. Maecenas aliquet mollis lectus. Vivamus consectetuer risus et tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. </p>"
let attrStr = try! NSAttributedString(
data: (string + string + string + string + string + string + string + string).data(using: String.Encoding.unicode,allowLossyConversion: true)!,
options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
documentAttributes: nil)
label.attributedText = attrStr
label.backgroundColor = UIColor(red:0.00, green:1.00, blue:0.00, alpha:1.0)
}
可以从 here 下载完整的工作项目。
你绝对是对的。这是一个时间问题。
NSDocumentTypeDocumentAttribute
的 NSHTMLTextDocumentType
是 notorious for taking very long times。当您增加 attrStr
字符串长度(在 data 中添加几个 + 字符串)时,您将能够在一定的字符串长度后为更高端的设备复制错误。我可以使用 iOS 10.1
在 iPhone 6 plus
模拟器中重现它,因为模拟器的处理能力低于实际设计。
如果可行,您可以尝试使用 DTCoreText 来解决这个问题。该库使用内置方法以外的方法处理 html 字符串,从而减少了渲染时间。这将使该错误在低端手机中不那么明显。
这里的问题是 UIView
有一个未记录的 8192 点高度限制。一旦标签达到 8192 点高(或更高),它就不再更新帧缓冲区。 (据推测,一旦层太大,window 服务器就会简单地忽略标签的 CALayer
。)帧缓冲区中已经存在的内容仍保留在那里。据推测,该行为是未定义的,并且可能因 iOS.
的设备和版本而异
(编辑:再考虑一下,我怀疑限制是 16,384 像素,而不是 8,192 点。我不认为 window 服务器以点数交易。)
为了演示,我使用了您的代码和情节提要并添加了三件事:
- 我限制了你标签的高度小于等于8185点。
- 我添加了一个滑块来更新该高度约束的常量。滑块允许范围为 8185 到 8200。
- 我添加了另一个显示高度约束常数的标签。
这是 iPhone SE 模拟器 运行ning iOS 10.2 中发生的事情:
在演示中,您可以看到一旦高度限制超过 8192 点,滑块的拇指开始看起来有污迹,并且高度标签的文本明显地覆盖了自己。这是因为绿色标签不再更新帧缓冲区,所以之前存在的内容(由滑块和高度标签绘制)仍然存在,仅在滑块和高度标签重新绘制它们自己的地方被覆盖。一旦高度回落到 8192 点阈值,绿色标签就会再次绘制自己,清理混乱。
我认为您在 iPhone 7 测试中没有看到这一点,因为 iPhone 7 的屏幕比 iPhone SE 更宽。所有3.5英寸和4英寸屏幕的iPhone都是320点宽。 iPhone 4.7 英寸屏幕的宽度为 375 点,iPhone 5.5 英寸屏幕的宽度为 414 点。
更宽的屏幕意味着更宽 UILabel
。这意味着每行可以容纳更多文本,因此标签不必那么高就可以容纳所有文本。我怀疑在较大的屏幕上,您的标签短于 8192 点,因此它们不会遇到未定义的行为。
解决方法:
如果您不打算让用户滚动查看整个文本,只需在标签上设置高度限制即可。
如果您想让用户滚动,请尝试使用 UIWebView
或 WKWebView
而不是 UILabel
来显示文本。我相信这些视图可以处理超过 8192 点的内容。
顺便说一下,您不是第一个 运行 进入这个问题的人:UILabel view disappear when the height greater than 8192。但是,您的问题目前有一个开放的赏金,这可以防止它作为重复项被关闭。
所以,我在一个项目中遇到了一些问题,其中某些字符串在某些具有某些 iOS 版本的旧 iPhone 中无法正确呈现(特别是它不适用于 iPhone 5 和 iOS10,而它对 iOS9.3 有效,这很奇怪)。为了减少这个问题,我写了这段代码:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Long HTML, although we'll make it even larger to prove a point
let string = "<h1>Thing 1</h1><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </p><h1>Thing 2</h1><p>Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. </p><h1>Thing 3</h1><p>Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. </p><h1>Thing 4</h1><p>Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. </p><h1>Thing 5</h1><p>Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor, cursus quis, aliquet eget, justo. Sed pretium blandit orci. </p><h1>Thing 6</h1><p>Ut eu diam at pede suscipit sodales. Aenean lectus elit, fermentum non, convallis id, sagittis at, neque. Nullam mauris orci, aliquet et, iaculis et, viverra vitae, ligula. Nulla ut felis in purus aliquam imperdiet. Maecenas aliquet mollis lectus. Vivamus consectetuer risus et tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. </p>"
let attrStr = try! NSAttributedString(
data: (string + string + string + string + string + string + string + string).data(using: String.Encoding.unicode,allowLossyConversion: true)!,
options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
documentAttributes: nil)
label.attributedText = attrStr
label.backgroundColor = UIColor(red:0.00, green:1.00, blue:0.00, alpha:1.0)
}
}
很简单。当然实际问题比这更复杂,但是思路是一样的。
因此,在 iPhone 7 中,一切正常:
然而,在 iPhone 4s 上加载时:
调试时,attrStr
似乎在两种情况下都已正确设置。
有什么想法吗?我的理论是旧手机太慢无法按时呈现,但我不太确定如何解决这个问题。
谢谢!
编辑:对于那些提问的人,这是故事板:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="JzW-qG-LFG">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="9PR-d2-hNU">
<objects>
<viewController id="JzW-qG-LFG" customClass="ViewController" customModule="things" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="VGp-YT-QQN"/>
<viewControllerLayoutGuide type="bottom" id="SeT-t7-CD0"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="gtg-CO-E9d">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Id1-A1-RaT">
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="trailingMargin" secondItem="Id1-A1-RaT" secondAttribute="trailing" id="0qp-Rk-PC2"/>
<constraint firstItem="Id1-A1-RaT" firstAttribute="leading" secondItem="gtg-CO-E9d" secondAttribute="leadingMargin" id="3Vc-he-HqH"/>
<constraint firstItem="Id1-A1-RaT" firstAttribute="top" secondItem="VGp-YT-QQN" secondAttribute="bottom" id="7IE-fY-4H0"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="Opz-px-hsl"/>
<connections>
<outlet property="label" destination="Id1-A1-RaT" id="TNv-G9-ASE"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="qlV-6d-ISJ" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2848.8000000000002" y="-280.20989505247377"/>
</scene>
</scenes>
</document>
您没有提供任何关于故事板的详细信息,或者 label
的设置或限制。
所以我以编程方式启动了标签,这个解决方案适用于 iPhone 4s 运行 iOS 9.3:
这是工作源代码:
override func viewDidLoad() {
super.viewDidLoad()
label = UILabel(frame: CGRect(x: 0.0, y: 44.0, width: view.frame.size.width, height: view.frame.size.height - 88.0))
label.numberOfLines = 0
label.isUserInteractionEnabled = false
label.contentMode = .left
label.textAlignment = .natural
label.lineBreakMode = .byTruncatingTail
label.baselineAdjustment = .alignBaselines
label.adjustsFontSizeToFitWidth = false
// label.translatesAutoresizingMaskIntoConstraints = false //setting this causes the text to be layout wrong
label.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
view.addSubview(label)
// Long HTML, although we'll make it even larger to prove a point
let string = "<h1>Thing 1</h1><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </p><h1>Thing 2</h1><p>Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. </p><h1>Thing 3</h1><p>Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. </p><h1>Thing 4</h1><p>Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. </p><h1>Thing 5</h1><p>Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor, cursus quis, aliquet eget, justo. Sed pretium blandit orci. </p><h1>Thing 6</h1><p>Ut eu diam at pede suscipit sodales. Aenean lectus elit, fermentum non, convallis id, sagittis at, neque. Nullam mauris orci, aliquet et, iaculis et, viverra vitae, ligula. Nulla ut felis in purus aliquam imperdiet. Maecenas aliquet mollis lectus. Vivamus consectetuer risus et tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. </p>"
let attrStr = try! NSAttributedString(
data: (string + string + string + string + string + string + string + string).data(using: String.Encoding.unicode,allowLossyConversion: true)!,
options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
documentAttributes: nil)
label.attributedText = attrStr
label.backgroundColor = UIColor(red:0.00, green:1.00, blue:0.00, alpha:1.0)
}
可以从 here 下载完整的工作项目。
你绝对是对的。这是一个时间问题。
NSDocumentTypeDocumentAttribute
的 NSHTMLTextDocumentType
是 notorious for taking very long times。当您增加 attrStr
字符串长度(在 data 中添加几个 + 字符串)时,您将能够在一定的字符串长度后为更高端的设备复制错误。我可以使用 iOS 10.1
在 iPhone 6 plus
模拟器中重现它,因为模拟器的处理能力低于实际设计。
如果可行,您可以尝试使用 DTCoreText 来解决这个问题。该库使用内置方法以外的方法处理 html 字符串,从而减少了渲染时间。这将使该错误在低端手机中不那么明显。
这里的问题是 UIView
有一个未记录的 8192 点高度限制。一旦标签达到 8192 点高(或更高),它就不再更新帧缓冲区。 (据推测,一旦层太大,window 服务器就会简单地忽略标签的 CALayer
。)帧缓冲区中已经存在的内容仍保留在那里。据推测,该行为是未定义的,并且可能因 iOS.
(编辑:再考虑一下,我怀疑限制是 16,384 像素,而不是 8,192 点。我不认为 window 服务器以点数交易。)
为了演示,我使用了您的代码和情节提要并添加了三件事:
- 我限制了你标签的高度小于等于8185点。
- 我添加了一个滑块来更新该高度约束的常量。滑块允许范围为 8185 到 8200。
- 我添加了另一个显示高度约束常数的标签。
这是 iPhone SE 模拟器 运行ning iOS 10.2 中发生的事情:
在演示中,您可以看到一旦高度限制超过 8192 点,滑块的拇指开始看起来有污迹,并且高度标签的文本明显地覆盖了自己。这是因为绿色标签不再更新帧缓冲区,所以之前存在的内容(由滑块和高度标签绘制)仍然存在,仅在滑块和高度标签重新绘制它们自己的地方被覆盖。一旦高度回落到 8192 点阈值,绿色标签就会再次绘制自己,清理混乱。
我认为您在 iPhone 7 测试中没有看到这一点,因为 iPhone 7 的屏幕比 iPhone SE 更宽。所有3.5英寸和4英寸屏幕的iPhone都是320点宽。 iPhone 4.7 英寸屏幕的宽度为 375 点,iPhone 5.5 英寸屏幕的宽度为 414 点。
更宽的屏幕意味着更宽 UILabel
。这意味着每行可以容纳更多文本,因此标签不必那么高就可以容纳所有文本。我怀疑在较大的屏幕上,您的标签短于 8192 点,因此它们不会遇到未定义的行为。
解决方法:
如果您不打算让用户滚动查看整个文本,只需在标签上设置高度限制即可。
如果您想让用户滚动,请尝试使用
UIWebView
或WKWebView
而不是UILabel
来显示文本。我相信这些视图可以处理超过 8192 点的内容。
顺便说一下,您不是第一个 运行 进入这个问题的人:UILabel view disappear when the height greater than 8192。但是,您的问题目前有一个开放的赏金,这可以防止它作为重复项被关闭。