UITextView未在Swift中显示attributedString

UITextView未在Swift中显示attributedString,swift,string,swift3,uitextview,nsmutableattributedstring,Swift,String,Swift3,Uitextview,Nsmutableattributedstring,当我运行下面的代码时,AttributeText会显示在控制台中,但不会显示在UITextView中。我将AttributeText保存在全局变量scrollViewText中。我试过打印scrollViewText,但它在控制台中仍然显示为空白 public static func getHonorsAdvisorsText(){ Alamofire.request("https://honors.purdue.edu/json/honors-advisors.json").resp

当我运行下面的代码时,AttributeText会显示在控制台中,但不会显示在UITextView中。我将AttributeText保存在全局变量
scrollViewText
中。我试过打印
scrollViewText
,但它在控制台中仍然显示为空白

public static func getHonorsAdvisorsText(){

    Alamofire.request("https://honors.purdue.edu/json/honors-advisors.json").responseJSON { response in
        //check if result has value
        if let value = response.result.value {
            let json = JSON(value)
            let freshmenName = json["first_year_advisors"][0]["name"].string
            let freshmenAssignment = json["first_year_advisors"][0]["assignment"].string
            let freshmenEmail = json["first_year_advisors"][0]["email"].string
            let formattedString = NSMutableAttributedString()
            formattedString
                .bold("Freshmen Advisor", fontSize: 40)
                .bold("\n" + "Name: " , fontSize: 20)
                .normal(freshmenName!, fontSize: 20)
                .bold("\n" + "Assignment: " , fontSize: 20)
                .normal(freshmenAssignment!, fontSize: 20)
                .bold("\n" + "Email: " , fontSize: 20)
                .normal(freshmenEmail!, fontSize: 20)
            scrollViewText = formattedString
            print(formattedString)
        }
    }
}
我使用以下代码调用ThirdViewController中的
GetHonorsadVisorText
函数:

case 1:
AcademicsPage.getHonorsAdvisorsText()
textViewer.attributedText = scrollViewText

当然,你永远不会得到回应。您正在运行以下两个呼叫:

AcademicsPage.getHonorsAdvisorsText()
textViewer.attributedText = scrollViewText
但是,它们紧跟在一起运行,但是“getHonorsAdvisorsText”是异步的。(意味着它不会立即完成)这意味着当设置attributedText时,值仍然为空

解决此问题的最简单方法是删除该行,改为将getHonorsAdvisorsText函数更改为:

public static func getHonorsAdvisorsText(){

    Alamofire.request("https://honors.purdue.edu/json/honors-advisors.json").responseJSON { response in
        //check if result has value
        if let value = response.result.value {
            let json = JSON(value)
            let freshmenName = json["first_year_advisors"][0]["name"].string
            let freshmenAssignment = json["first_year_advisors"][0]["assignment"].string
            let freshmenEmail = json["first_year_advisors"][0]["email"].string
            let formattedString = NSMutableAttributedString()
            formattedString
                .bold("Freshmen Advisor", fontSize: 40)
                .bold("\n" + "Name: " , fontSize: 20)
                .normal(freshmenName!, fontSize: 20)
                .bold("\n" + "Assignment: " , fontSize: 20)
                .normal(freshmenAssignment!, fontSize: 20)
                .bold("\n" + "Email: " , fontSize: 20)
                .normal(freshmenEmail!, fontSize: 20)
            scrollViewText = formattedString

            // SET THE TEXT HERE

            DispatchQueue.main.async {
               textViewer.attributedText = scrollViewText
            }

            print(formattedString)
        }
    }
}
注意文本是如何在“main”调度队列中设置的。这是因为所有接口更改必须在主队列上完成

使用完成处理程序:

public static func getHonorsAdvisorsText(completionHandler : @escaping ((_ formattedString : NSMutableAttributedString) -> Void)){

    Alamofire.request("https://honors.purdue.edu/json/honors-advisors.json").responseJSON { response in
        //check if result has value
        if let value = response.result.value {
            let json = JSON(value)
            let freshmenName = json["first_year_advisors"][0]["name"].string
            let freshmenAssignment = json["first_year_advisors"][0]["assignment"].string
            let freshmenEmail = json["first_year_advisors"][0]["email"].string
            let formattedString = NSMutableAttributedString()
            formattedString
                .bold("Freshmen Advisor", fontSize: 40)
                .bold("\n" + "Name: " , fontSize: 20)
                .normal(freshmenName!, fontSize: 20)
                .bold("\n" + "Assignment: " , fontSize: 20)
                .normal(freshmenAssignment!, fontSize: 20)
                .bold("\n" + "Email: " , fontSize: 20)
                .normal(freshmenEmail!, fontSize: 20)
            scrollViewText = formattedString

            // SET THE TEXT HERE

            DispatchQueue.main.async {
               completionHandler(formattedString)
            }

            print(formattedString)
        }
    }
}
你这样称呼它:

AcademicsPage.getHonorsAdvisorsText { (formattedString) in
    textViewer.attributedText = formattedString
}

您在何处尝试更新文本视图?在一个特定文件中,我运行代码
textView.attributedText=scrollViewText
,您需要更新您的问题,详细说明如何以及何时更新与调用此
GetOnorSadVisorsText
方法相关的内容。@rmaddy我更新了它,并在该行上设置了一个断点
textViewer.AttributeText=scrollViewText
和行
scrollViewText=formattedString
。注意发生了什么。您需要了解异步方法调用。这不是最好的解决方案,因为这意味着此
getHonorsAdvisorsText
的唯一用途是设置特定的文本视图。更好的解决方案是使用完成处理程序设置此函数。然后,该函数可以被任何需要属性字符串的对象使用,而不仅仅是一个特定视图控制器中的一个特定文本视图。具有textView的视图控制器是为另一个类设置的。如何从不同的位置设置textView的文本class@rmaddy如何将完成处理程序添加到Alamofirecode@rmaddy没错,我也想过他想做什么,但是这个函数的唯一效果是更新变量“scrollViewText=formattedString”。这就是为什么仅仅更新界面和副作用似乎并没有那么糟糕的原因。@Pochi简单地“将界面更新为副作用”是一种糟糕的看待方式。永远不要做这样的事。