【问题标题】:Update a UILabel using string value from another class in Swift使用 Swift 中另一个类的字符串值更新 UILabel
【发布时间】:2015-10-12 14:14:51
【问题描述】:

如何使用来自另一个类中的函数的字符串值来更新我的 ViewController 上的 UILabel? 这是我的代码:

视图控制器:

导入 UIKit

类 ViewController: UIViewController, dataEnterdDelegate {

@IBOutlet weak var auaTempLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
    let weather2 = WeatherService2()
    weather2.getWeatherData("Oranjestad,AW") 
}

**func userDidEnterInformation(info: NSString)
{
    testLabel!.text = info as String
}**

func setLabel2(information: String)
{
    auaTempLabel.text = information
}

另一个名为 WeatherService2 的类包含以下代码:

**protocol dataEnterdDelegate{
func userDidEnterInformation(info:NSString)
}**

Class WeatherService2{
var currentTempeture:String?
let targetVC = ViewController()
**var delegate: dataEnterdDelegate?**

func getWeatherData(urlString:String)
{
    let url = NSURL(string: urlString)!
    let sqlQuery =  "select * from weather.forecast where woeid in (select woeid from geo.places(1) where text=\"\(url)\")"

    let endpoint = "https://query.yahooapis.com/v1/public/yql?q=\(sqlQuery)&format=json"

    let testString = (String(endpoint))
    getData(testString)
}

func getData(request_data: String)
{
    let requestString:NSString = request_data.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!

    let url_with_data = NSURL(string: requestString as String)!
    let task = NSURLSession.sharedSession().dataTaskWithURL(url_with_data){
        (data, response, error) in dispatch_async(dispatch_get_main_queue(), {
            if data == nil
            {
                print("Failed loading HTTP link")

            }else{
                self.setLabel(data!)
            }
        })
    }
    task.resume()



}

func setLabel(weatherData:NSData)
{
    enum JSONErrors: ErrorType
    {
        case UserError
        case jsonError
    }

    do{
        let jsonResults = try NSJSONSerialization.JSONObjectWithData(weatherData, options: .AllowFragments)

        if let city = jsonResults["query"] as? NSDictionary
        {
            if let name = city["results"] as? NSDictionary
            {
                if let channel = name["channel"] as? NSDictionary
                {
                    if let item = channel["item"] as? NSDictionary
                    {
                        if let condition = item["condition"] as? NSDictionary
                        {
                            if let temp = condition["temp"] as? String
                            {
                                setTemp(temp)
                                **delegate!.userDidEnterInformation(temp)**   
                            }
                        }
                    }
                }

            }
        }
    }

    catch {
        print("Failed to load JSON Object")

    }


}


func setTemp(tempeture:String)
{
    self.currentTempeture = tempeture
}

func getTemp() ->String
{
    return self.currentTempeture!
}

}

代码运行良好,一切正常,但是当我尝试更新 ViewController 中的 UILabel 时,出现错误“致命错误:在展开可选值时意外发现 nil”。 当我在视图控制器类中使用print("The return value is: "+information) 时,它会正确打印返回值。 这就是我现在感到困惑的原因,因为我不知道为什么在尝试使用此值更新我的 UILabel 时仍然收到“致命错误:在展开可选值时意外发现 nil”。

谁能帮我解决这个问题?

提前致谢

【问题讨论】:

    标签: ios


    【解决方案1】:

    为此,您必须创建委托方法。

    viewController 中创建委托方法并从获得响应的位置调用它并设置viewController.delegate = self

    我无法解释更多,你必须搜索它,它会 100% 工作。

    一切顺利。

    【讨论】:

    • 你的意思是在Viewcontroller类中创建一个String类型的变量吗?
    • 好的,因为我已经这样做了,但仍然没有积极的回应。如果您可以发布一个有关如何完成的示例,我不知道吗?
    • k 什么时候我会比我发布示例有空
    • 从响应中获取字符串后推送哪个类?
    • 我希望“WeatherService2”解析 JSON 文件并获取温度字符串值,并使用该字符串更新“ViewController”类中的 UILabel。
    【解决方案2】:

    我设法通过执行以下操作来解决此问题: 我创建了以下类 - 物品 - 健康)状况 - 渠道 这些类实现 JSONPopulator 协议。 JSONPopulator 协议:

    protocol JSONPopulator 
    {
        func populate(data:AnyObject)
    }
    

    物品类:

    class Item: JSONPopulator
    {
    var condition:Condition?
    
    func getCondition() ->Condition
    {
        return condition!
    }
    
    func populate(data: AnyObject)
    {
        condition = Condition()
        condition?.populate(data)
    }
    }
    

    条件类:

    class Condition:JSONPopulator
    {
    
    var arubaTemp:String?
    
    var channel:NSDictionary!
    
    func getArubaTemp()->String
    {
        return arubaTemp!
    }
    
    func getBonaireTemp() ->String
    {
        return bonaireTemp!
    }
    
    func getCuracaoTemp()->String
    {
        return curacaoTemp!
    }
    
    func populate(data: AnyObject)
    {
        if let query = data["query"] as? NSDictionary
        {
            if let results = query["results"] as? NSDictionary
            {
                if let channel = results["channel"] as? NSDictionary
                {
                    self.channel = channel
                    if let location = channel["location"] as? NSDictionary
                    {
                        if let city = location["city"] as? String
                        {
                            if city.containsString("Oranjestad")
                            {
                                switch city
                                {
                                case "Oranjestad":
                                    arubaTemp = getTemp()
                                    print(arubaTemp)
                                default:
                                    break
                                }
    
                            }
                        }
                    }
                }
            }
        }
    }
    
    
    
    func getTemp() ->String
    {
        var temp:String?
        if let item = self.channel["item"] as? NSDictionary
        {
            if let condition = item["condition"] as? NSDictionary
            {
                if let tempeture = condition["temp"] as? String
                {
                    print(tempeture)
                    temp = tempeture
                }
            }
        }
        print(temp)
        return temp!
    }
    
    }
    

    频道类:

    class Channel: JSONPopulator
    {
        var item:Item?
        var unit:Unit?
        var request_city:String?
    
        func setRequestCity(request_city:String)
        {
            self.request_city = request_city
        }
    
        func getRequestCity() ->String
        {
            return request_city!
        }
    
        func getItem() -> Item
        {
            return item!
        }
    
        func getUnit() -> Unit
        {
            return unit!
        }
    
        func populate(data: AnyObject)
        {
            item = Item()
            item?.populate(data)      
        }
    
    }
    

    WeatherService 类,处理解析 JSON 对象的功能。此类实现 WeatherServiceCallBack 协议。 WeatherServiceCallBack 协议:

    protocol WeatherServiceCallBack
    {
        func arubaWeatherServiceService( channel:Channel)
        func arubaWeatherServiceFailure()
    }
    

    WeatherService 类:

    class WeatherService
    {
        var weatherServiceCallBack:WeatherServiceCallBack
        var requestCity:String?
    
        init(weatherServiceCallBack: WeatherServiceCallBack)
    {
        self.weatherServiceCallBack = weatherServiceCallBack
    }
    
    internal func checkCity(city:String)
    {
        switch (city)
        {
            case "Oranjestad,AW":
            requestCity = city
            getWeatherData(requestCity!)
        default:
            break
        }
    
    }
    
    
    func getWeatherData(urlString:String)
    {
        let url = NSURL(string: urlString)!
    
        let sqlQuery =  "select * from weather.forecast where woeid in (select woeid from geo.places(1) where text=\"\(url)\")"
    
        let endpoint = "https://query.yahooapis.com/v1/public/yql?q=\(sqlQuery)&format=json"
    
    
        let testString = (String(endpoint)
        executeTask(testString)
    }
    
    func executeTask(request_data: String)
    {
        let requestString:NSString = request_data.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
    
        let url_with_data = NSURL(string: requestString as String)!
    
        let task = NSURLSession.sharedSession().dataTaskWithURL(url_with_data){
            (data, response, error) in dispatch_async(dispatch_get_main_queue(), {
                if data == nil
                {
                    print("Failed loading HTTP link")
    
                }else{
                    self.onPost(data!)
                }
            })
        }
        task.resume()
    
    }
    
    func onPost(data:NSData)
    {
        enum JSONErrors: ErrorType
        {
            case UserError
            case jsonError
        }
    
        do{
            let jsonResults = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments)
            print(jsonResults)
    
            if let city = jsonResults["query"] as? NSDictionary
            {
                if let name = city["count"] as? Int
                {
                    if name == 0
                    {
                        weatherServiceCallBack.arubaWeatherServiceFailure()
                    }
                }
    
            }
    
            if let requestCity_check = jsonResults["query"] as? NSDictionary
            {
                if let results = requestCity_check["results"] as? NSDictionary
                {
                    if let channel = results["channel"] as? NSDictionary
                    {
                        if let location = channel["location"] as? NSDictionary
                        {
                            if let city = location["city"] as? String
                            {
                                requestCity = city
                                let channel = Channel()
                                channel.setRequestCity(requestCity!)
                                channel.populate(jsonResults)
                                weatherServiceCallBack.arubaWeatherServiceService(channel)
                            }
    
                        }
    
                    }
    
                }
            }
    
    
        }catch {
            print("Failed to load JSON Object")
        }
    
    }
    
    }
    

    ViewController 类中(我向 UILabel 添加了一些动画,以便它可以从华氏温度翻转到摄氏温度):

    class ViewController: UIViewController, WeatherServiceCallBack
    {
        var weather:WeatherService?
        var aua_Tempeture_in_F:String?
        var aua_Tempeture_in_C:String?
        var timer = NSTimer()
        @IBOutlet var aua_Temp_Label: UILabel!
        let animationDuration: NSTimeInterval = 0.35
        let switchingInterval: NSTimeInterval = 5  //10
    
    
        override func viewDidLoad() {
        super.viewDidLoad()
        weather = WeatherService(weatherServiceCallBack: self)
        weather?.checkCity("Oranjestad,AW")
    
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
        func animateTemptext()
        {
    
    self.timer = NSTimer.scheduledTimerWithTimeInterval(7.0, target: self, selector: Selector("tempConvertionTextSwitch"), userInfo: nil, repeats: true)
    
    
        }
    
    func setTempinCelsius(temp_string:String)
    {
    
        aua_Tempeture_in_F = "\(temp_string)°F"
        let convertedString = convertFahrenheittoCelsius(temp_string)
        aua_Tempeture_in_C = "\(convertedString)°C"
        aua_Temp_Label.text = aua_Tempeture_in_C
        animateTemptext()
    }
    
    func convertFahrenheittoCelsius(currentTemp:String) ->String
    {
        let tempTocelsius = (String(((Int(currentTemp)! - 32) * 5)/9))
        return tempTocelsius
    }
    
    @objc func tempConvertionTextSwitch()
    {
        CATransaction.begin()
        CATransaction.setAnimationDuration(animationDuration)
        CATransaction.setCompletionBlock{
            let delay = dispatch_time(DISPATCH_TIME_NOW,Int64(self.switchingInterval * NSTimeInterval(NSEC_PER_SEC)))
            dispatch_after(delay, dispatch_get_main_queue())
                {
    
            }
    
        }
        let transition = CATransition()
        transition.type = kCATransitionFade
        if aua_Temp_Label.text == aua_Tempeture_in_F
        {
    
            aua_Temp_Label.text = aua_Tempeture_in_C
        }else if aua_Temp_Label.text == aua_Tempeture_in_C
        {
    
            aua_Temp_Label.text = aua_Tempeture_in_F
        }else if aua_Temp_Label == ""
        {
            aua_Temp_Label.text = aua_Tempeture_in_C
        }
        aua_Temp_Label.layer.addAnimation(transition, forKey: kCATransition)
        CATransaction.commit()
    
    }
    
    
    
    func arubaWeatherServiceFailure() {
    
    }
    
    func arubaWeatherServiceService(channel: Channel)
    {
        let requested_city = channel.getRequestCity()
        let items = channel.getItem()
        let aua_Temp = items.getCondition().getArubaTemp()
        setTempinCelsius(aua_Temp)
    
    }
    
    }
    

    参考:

    • iOS 8 Swift Programming Cookbook Solutions Examples for iOS Apps

    • iOS 8 Programming Fundamentals with Swift、Xcode 和 Cocoa Basics

    希望对遇到同样问题的人有所帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 2013-12-31
      • 2019-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多