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

Posted

技术标签:

【中文标题】UIViewController 中的 textLabel.text 在从 NSObject 分配字符串时出现 nil【英文标题】:textLabel.text in UIViewController comes up nil while assigning string from NSObject 【发布时间】:2016-04-16 20:43:38 【问题描述】:

我是一名 ios 和编程菜鸟,因此对于任何不好的措辞或错误,我深表歉意。

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

这是我的视图控制器,我在其中提出了最初的报价请求

    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 获取新报价的更简单/更好的方法,请告诉我 :)

【问题讨论】:

【参考方案1】:

在您的函数fetchQuote() 中,您将quoteVC 设置为带有let quoteVC = RSQuotesViewController() 的RSQuotesViewController() 的新实例。相反,您应该为RSQuotesViewController() 的应用程序实例设置quoteLabel.text。您还发出了两个 API 请求。一次在fetchQuote() 函数中为RSQuotesViewController 一次在你的fetchQuote() 函数中为RSQuotes 一次


我认为您正在寻找的将涉及闭包。在 RSQuotes 类中为您的 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
    
 

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


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

【讨论】:

以上是关于UIViewController 中的 textLabel.text 在从 NSObject 分配字符串时出现 nil的主要内容,如果未能解决你的问题,请参考以下文章

Swift - 从 NavigationController 中的 UIViewController 转到 TabBarController 中的 UIViewController

UIViewController 中的 UITableView - 将单元格连接到 UIViewController

UIViewControllers 中的 UIViewController

如何从创建的 UIViewController 中的另一个 UIViewController 执行功能

故事板中的 UIViewController 容器

从 swiftUI 中的一个嵌入式 UIViewController 导航到 swift UI 中的另一个嵌入式 UIViewcontroller