【问题标题】:How to Render large size documents in iOS?如何在 iOS 中渲染大尺寸文档?
【发布时间】:2015-06-18 09:20:11
【问题描述】:

我正在开发一个阅读器项目,目前我正在解析 XML 文件并将其转换为属性字符串,然后在 CoreText 中呈现它(使用苹果 Sample Code)。

XML 文件大小超过 6 MB。文本正确呈现,但我无法呈现图像和表格(如 html 表格)。

同时我需要管理性能。我也试过UITextView,但它只显示四分之一的文本,之后文本消失了。

还有其他技术可以渲染文本、图像和表格吗?

P.S - 客户不想要UIWebView

【问题讨论】:

  • @MustafaIbrahim 这只是一个XML 解析器。我在解析上没有任何问题。我正在使用NSXMLParser。问题是在视图中渲染。
  • 你能确定图片或表格旁边不会有文字,一切都会垂直排列吗?
  • 即使客户不想要 UIWebView(想知道为什么),它也是满足您需求的最佳解决方案!我用它来显示大量的文本和数据,其内存占用比 UITextView 低 20 倍。

标签: ios objective-c uitextview core-text


【解决方案1】:

在处理如此大的文件时,您可能会多次显示数据。以下是几种解决方案:

  • 按页对显示进行分页: 将文件分成 10 个部分(比如说,这是一个示例)并在 UITextView 中显示第一部分。添加两个 UIButton 实例,以便读者可以切换页面。在页面更改时,将第一部分/下一部分加载到您的 UITextView 中。这对用户来说不会特别陌生,因为您正在重现他们阅读电子书的自然方式。 要确定您应该将数据拆分为多少部分,请注意用户不想连续切换页面,您必须注意调整这一点。

  • “平滑”地对显示进行分页:如上所述,您按页面进行分页,但您将始终处理嵌入在 ScrollView 中的两个 UITextView。与 iOS 在 UITableView 中重用单元格并按需加载单元格数据(延迟加载)的方式相同,使用两个 UITextView 实例实现这种可重用机制 - 要快速实现,您可以尝试使用标准 UITableView 实现该机制。李>

希望这会有所帮助!

【讨论】:

  • 客户端要求长时间平滑滚动。这种方法不适合我的项目
  • 你能提供任何例子吗?我在网上搜索,没有找到任何资源
  • 您能否提供一个与您需要显示的文件相同(大小)的大文件? (lipsum.com可以帮到你)
  • 它只创建了 150 个段落,我有 10 倍大的文件
  • 在此基础上,我生成了 150 个段落,然后复制粘贴了 4 次!
【解决方案2】:

UIScrollView 可能是唯一的可能性。将您的文档分成几部分,并将其放入 UITextView、UIImageView 和 UITableView 类的适当子视图中。为了降低内存影响,请仅放置那些实际可见的子视图。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [self removeSubViews];
    [self addSubViews];
}

- (void)removeSubViews {
    for (UIView *subView in documentScrollView.subviews) {
        [subView removeFromSuperview];
    }
}

- (void)addSubViews {
    NSArray* visibleSubViews = [self getAllSubViewsThatAreVisible];
    for (UIView *subView in visibleSubViews) {
        [documentScrollView addSubview:subView];
    }
}

- (NSArray*)getAllSubViewsThatAreVisible {
    NSMutableArray* arrayOfSubViews = [[NSMutableArray alloc] init];
    NSArray* arrayOfVisibleComponents = [self getAllVisibleComponents];
    for (NSDictionary *component in arrayOfVisibleComponents) {
        //there you have to create new UITableView, UITextView, or UIImageView according to what is needed and put this new component into arrayOfSubViews
    }
    return arrayOfSubViews;
}

- (NSArray*)getAllVisibleComponents {
//this is hard to tell how it should be written as I do not know your data. Lets assume, that you have an array of NSDictionary objects. Check all objects in this array, whether they can be visible or not. You shall know their future coordinates in scrollView, while in scrollView, you get visible part by usig property named contentOffset, which will give you top left corner coordinate and by using also property frame.size, you get whole visible rectangle
}

完成此操作并对其进行测试后,您可以通过不删除所有子视图并将那些仍然可见的子视图留在那里来优化它。第二个优化将根据 Y 坐标划分组件数组,因此您不必总是迭代整个巨大的数组。第三个优化可以是,每次小滚动后不会重绘,甚至会放置一些实际上不可见但靠近可见区域的组件,滚动后首先检查是否需要重绘。

【讨论】:

  • 我的文档是XML 格式,而且它太大了。如果我为它们中的每一个创建子视图,应用程序将因内存压力而崩溃。我们可以在UITextView 中显示所有内容
  • 向 UITextView 添加子视图(现在只需要 UITableViews 和 UIImageViews)是否可行?
  • 渲染大文本会导致应用速度变慢。我的文件将有超过 4300000 行。
  • 并在仅放置可见的子视图并在滚动后将其删除时使用 UIScrollView?这可能会很慢,但对于大型文档来说应该是可以预期的。
  • 是的,这可能是一个可能的解决方案。但是没有资源来实现这个方法。我在搜索后尝试过
【解决方案3】:

您尚未详细说明 XML 文件中编码的文档的结构。它可以使用类似 HTML 的层次结构非常复杂,也可以很简单——散布在图像和表格中的线性文本段落。

假设是后者,我喜欢 _sweepy 和 Reconquistador 的方法。但我可能会尝试使用 UITableView 并为每个文档结构创建单元格类型 - 段落、图像、表格。使用 UILabel 和 UIImage 视图来呈现内容很容易实现段落和图像。表格可能更难,但我可能会利用 UIWebView 或 WKWebView 仅呈现表格。

您需要将您的 XML 解析为某种结构或后备存储,您可以在其中通过线性索引查找给定的文档构造。假设文档很大,我会倾向于 SQLite 或 CoreData。

滚动会很流畅。表格将在单元格变得可见时加载它们,并在它们滚动到屏幕外时卸载它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多