textLabel.text 在 UIViewController 中从 NSObject 分配字符串时出现 nil

textLabel.text in UIViewController comes up nil while assigning string from NSObject

我是一个 iOS 编程菜鸟,所以对于任何糟糕的措辞或错误,我深表歉意。

我正在为我的应用程序解析来自 API 的引号,每次单击 UIButton 时它都会在 textLabel 上显示它。为了防止字符串离开 textLabel 或调整为不可读的字体,如果字符串字符数太高,我试图通过调用我的 NSObject 中的函数来请求新的引号。我设置了一个 NSObject 来进行重新获取,但是每当我尝试将字符串从 NSObject 重新分配给 textLabel.text 或尝试将字符串发送回 ViewController 时,qouteLabel.text 就会返回无

这是我的 viewcontroller 初始报价请求

    import UIKit
import Alamofire

class RSQuotesViewController: RSViewController {


    var ronImageView: UIImageView!
    var quoteLabel = UILabel!()


    override func loadView() {
        let frame = UIScreen.mainScreen().bounds
        let view = UIView(frame: frame)
        view.backgroundColor = UIColor.grayColor()



        ronImageView = UIImageView(frame: CGRectMake(frame.width/2-160, frame.height-600, 320, 600))
        let ron = "ron.png"
        let ronImage = UIImage(named: ron)
        ronImageView.image = ronImage
        view.addSubview(ronImageView);

        let labelWidth = ronImageView.frame.width/2
        let quoteLabelX = labelWidth-40

        quoteLabel = UILabel(frame: CGRect(x: quoteLabelX, y: ronImageView.frame.height/4+15, width: labelWidth, height: 160))
        quoteLabel.textAlignment = .Center
        quoteLabel.text = "Click to Start"
        quoteLabel.shadowColor = UIColor.grayColor()
        quoteLabel.adjustsFontSizeToFitWidth = true
        quoteLabel.lineBreakMode = .ByWordWrapping // or NSLineBreakMode.ByWordWrapping
        quoteLabel.numberOfLines = 0
        view.addSubview(quoteLabel)


        self.view = view
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let frame = UIScreen.mainScreen().bounds

        let getQuote = UIButton(frame: CGRect(x: 0, y: 0, width: frame.size.width+50, height: frame.size.height))
        getQuote.backgroundColor = UIColor.clearColor()
        getQuote.setTitle("", forState: UIControlState.Normal)
        getQuote.addTarget(self, action: #selector(RSQuotesViewController.getQuote(_:)), forControlEvents: UIControlEvents.TouchUpInside)

        self.view.addSubview(getQuote)

    }



    //  Gets quote when button is pressed
    func getQuote(sender: UIButton){
        let url = "http://ron-swanson-quotes.herokuapp.com/v2/quotes"
        Alamofire.request(.GET, url, parameters: nil).responseJSON { response in
            if let JSON = response.result.value as? Array<String>{
                let quoteDict = RSQoute()

                // if quote is too large get another one
                if (JSON[0].characters.count > 120){

                    print("greater than 120")
                    quoteDict.fetchQuote()

                } else {

                    self.quoteLabel.text = JSON[0]


                }





        }


    }

}

这是我的模型,我正在尝试重新分配 quoteLabel.text 并得到 nil

import UIKit
import Alamofire

class RSQoute: NSObject {

    var newQuote = String()


    //   fetchs new quote if quote is too large

    func fetchQuote(){

        let url = "http://ron-swanson-quotes.herokuapp.com/v2/quotes"
        Alamofire.request(.GET, url, parameters: nil).responseJSON { response in
            if let JSON = response.result.value as? Array<String>{
            self.newQuote = JSON[0]
                if (self.newQuote.characters.count > 120) {

                    print("Try Again: ---->\(self.newQuote)")
                    return self.fetchQuote()
                } else {
                    let quoteVC = RSQuotesViewController()
                    print("Retry was less than 120: ---->\(self.newQuote)")
                    print("quoteLabelText: ---->\(RSQuotesViewController().quoteLabel.text)")// comes back nil
                    RSQuotesViewController().quoteLabel.text = self.newQuote

                }




        }
    }
    }



}

如果我遗漏了什么或尝试从 API 获取新报价的 easier/better 方法,请告诉我:)

在您的函数 fetchQuote() 中,您使用 let quoteVC = RSQuotesViewController() 将 quoteVC 设置为 RSQuotesViewController() 的新实例。相反,您应该为 RSQuotesViewController() 的应用程序实例设置 quoteLabel.text。您还提出了两个 API 请求。一旦进入 fetchQuote() 函数用于 RSQuotesViewController 并且一旦进入 fetchQuote() 函数用于 RSQuotes


我认为您正在寻找的内容涉及关闭。在 RSQuotes class

中为 fetchQuote() 函数试试这个
    func fetchQuote(completion: (result:String)){

    let url = "http://ron-swanson-quotes.herokuapp.com/v2/quotes"
    Alamofire.request(.GET, url, parameters: nil).responseJSON { response in
        if let JSON = response.result.value as? Array<String>{
        self.newQuote = JSON[0]
            if (self.newQuote.characters.count > 120) {

                print("Try Again: ---->\(self.newQuote)")
                completion(result: self.newQuote)
            } else {
                print("Retry was less than 120: ---->\(self.newQuote)")
                print("quoteLabelText: ---->\(RSQuotesViewController().quoteLabel.text)")// comes back nil
                completion(result: self.newQuote)

            }
    }

然后,我会有一个 setQuote 函数 RSQuotesViewController,您可以在其中执行类似的操作

func setQuote() {
    let quoteObj = RSQuote()
    quoteObj.fetchQuote() {
         result in
         quoteLabel.text = result
    }
} 

我会看一些与 swift 闭包相关的帖子,并查看。 http://goshdarnclosuresyntax.com/


附带说明一下,我不确定您是否打算在 RSQuote class 中操作 quoteString。如果不是,fetchQuote() 成为 static func 可能会更好。这样你就可以调用它而无需初始化 RSQuoteViewController 中的对象。应该是 RSQuote.fetchQuote()