由于NSAttributedString,UITableView滚动不顺畅

时间:2017-05-02 10:56:40

标签: ios uitableview swift3 nsattributedstring smooth-scrolling

我正在使用NSAttributedString将html字符串转换为attributedString。我已将其转换为label,但我在cellForRowAtIndex中编写了以下代码,当我应用此代码表视图时,滚动不顺畅。如果我用简单的文本删除它,它会顺利滚动。

 cell.lblDescription.setHTMLFromString(htmlText: model.strItineraryDescription)

我已将html string转换为attributed string

extension UILabel {

    func setHTMLFromString(htmlText: String) {
        let modifiedFont = NSString(format:"<span style=\"font-family: '-apple-system', 'HelveticaNeue'; font-size: \(self.font!.pointSize)\">%@</span>" as NSString, htmlText) as String


        //process collection values
        let attrStr = try! NSAttributedString(
            data: modifiedFont.data(using: .unicode, allowLossyConversion: true)!,
            options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue],
            documentAttributes: nil)


        self.attributedText = attrStr
    }

}

我的html string

<strong><u>Featured Program</u></strong></p>
\n<ol>
\n  <li>Arrival at Delhi airport. You will receive by our representative.</li>
\n  <li>Driving to Agra and exploring the city.</li>
\n  <li>Back to Hotel for Overnight stay.</li>
\n</ol>
\n<p><strong>City Features</strong></p>
\n<ol>
\n  <li><strong>Visit to Agra Fort \U2013 </strong>Former Name Badalgarh, Shah-Jahan spent his last eight years here. You can watch the mesmerizing view of Taj Mahal from this fort just like Shah Jahan.</li>
\n  <li><strong>Visit to Taj Mahal \U2013</strong> It took 21 years to build and stood in 1653. The palace is considered as the symbol of love. Shah Jahan built this wonder in the memory of his wife Mumtaj Mahal.</li>
\n</ol>
\n<p><strong>(Both Agra Fort and Taj Mahal are UNESCO Declared world heritage site)</strong>

2 个答案:

答案 0 :(得分:3)

html2AttributedString做了什么?它会在cellForRowAtIndexPath上动态地将HTML转换为属性字符串吗?如果是,这实际上需要时间。我们可以在内存上妥协,通过在模型中的另一个变量中缓存HTML的等效属性字符串来加速。因此,这种重新加载方式将在创建或重用单元格期间获取准备好的属性字符串。

例如,Psuedocode:

class MyModel
{
    var myHTML: String = ""
    var myHTML2AttributedString: String = ""
}


class ModelMapping
{
  ...
  myModel.myHTML = responseFromJSON["htmlText"]
  myModel.myHTML2AttributedString = customFuncToConvertHTMLToAttributed(myModel.myHTML)
  ...
}

class ViewController
{
  ...
  cell.lblDescription.attributedText = myModel.myHTML2AttributedString // This one would be cached Attributed string equivalent of HTML string.
  ...
}

希望有所帮助!

修改

class MyModel
{
    var myAttributedHTML: NSMutableAttributedString = ""
    var strItineraryDescription: String = ""

    func prepareHTMLFromString() {
        let modifiedFont = NSString(format:"<span style=\"font-family: '-apple-system', 'HelveticaNeue'; font-size: \(self.font!.pointSize)\">%@</span>" as NSString, self.strItineraryDescription) as String


        //process collection values
        let attrStr = try! NSAttributedString(
            data: modifiedFont.data(using: .unicode, allowLossyConversion: true)!,
            options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue],
            documentAttributes: nil)


        myAttributedHTML = attrStr.mutableCopy()
    }
}

class MyViewController
{
   ...
   cell.lblDescription.attributedText = myModel.myAttributedHTML
   ...
}

class ResponseHandler
{
   ...
   myModel.strItineraryDescription = responseFromServer["myHTML"]
   myModel.prepareHTMLFromString()
   ...
}

答案 1 :(得分:1)

您需要使用Dispatch queue

DispatchQueue.global(qos: .background).async {
    print("This is run on the background queue")
    let strmy = model.strItineraryDescription.html2AttributedString            

    DispatchQueue.main.async {
        cell.lblDescription.attributedText = strmy

    }
}