【问题标题】:Set Title of UIButton from Selected Row of UIPickerView in swift快速从 UIPickerView 的选定行设置 UIButton 的标题
【发布时间】:2019-02-28 08:33:36
【问题描述】:

我正在尝试从 uipickerview 的选定行中设置我的按钮标题。但是,我似乎找不到有效的解决方案。

我已将变量设置为全局变量,因此我可以访问选定变量。但是,我似乎无法准确指出用户何时单击退出按钮并能够更新我的按钮标题。

我尝试过的事情:

  • 全局函数(无法工作,因为您无法指定要更改名称的按钮)
  • Dispatchqueue.main.async - 没有更新我的标题。这里的想法是让它不断检查字符串的变化。

我在这里找到的解决方案是在 Obj-C 中。我尝试将其转换为 swift https://objectivec2swift.com/#/converter/code/,但没有成功。 Set Title of UIButton from Selected Row of UIPickerView

@IBAction func CountryPickButton(_ sender: UIButton) {

        Global.setPickerDataSource(data:["Test","test2","test3"])
        Global.setPickerCompletionHandler(int:0)
        let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PickerViewPopUpId") as! PickerViewController
        //CountryPickButtonDetector = sender as? UIButton
        self.addChild(popOverVC)
        popOverVC.view.frame = self.view.frame
        self.view.addSubview(popOverVC.view)
        popOverVC.didMove(toParent: self)
        popOverVC.callback { value in
        //CountryPickButton.title.text = value
        sender.setTitle(value, for: UIControl.State)
    }
    }

import UIKit
var test = ""

class PickerViewController: UIViewController {
    @IBOutlet weak var PickerView: UIPickerView!
    var callback : ((String) -> Void)?
    override func viewDidLoad() {
        super.viewDidLoad()
        //self.view.backgroundColor = UIColor.black.withAlphaComponent(0.8)
        PickerView.dataSource = self
        PickerView.delegate = self
        // Do any additional setup after loading the view.
    }
    @IBAction func ExitButton(_ sender: Any) {
        switch Global.pickerCompletionHandler {

        case 0:
            callback?(Global.pickerResult ?? "")
            Global.setProfileCountry(string:
                Global.pickerResult ?? "")
        default:
            print("nothing")

        }
        self.view.removeFromSuperview()
    }

}

extension PickerViewController: UIPickerViewDelegate, UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1 // can be more than 1 component like time/date/year
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return Global.pickerDataSource?.count ?? 1
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        //Global.pickerResult = Global.pickerDataSource?[row]
        Global.setPickerResult(result: Global.pickerDataSource?[row] ?? "Test" )
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return Global.pickerDataSource?[row]
    }


}

全局

import Foundation

struct Global {
    static var pickerDataSource:[String]? = nil
    static var pickerResult:String? = nil
    static var pickerCompletionHandler:Int? = 0
    static var profileCountry:String? = nil

    static func setPickerDataSource(data:[String]) {
        Global.pickerDataSource = data
    }
    static func setPickerResult(result:String) {
        Global.pickerResult = result
    }
    static func setPickerCompletionHandler(int: Int) {
        Global.pickerCompletionHandler = int
    }
    static func setProfileCountry(string: String)
    {
        Global.profileCountry = string
    }
}

【问题讨论】:

  • 不要检查。得到通知!实现选择器视图委托方法didSelectRow 并通知(使用回调闭包、协议/委托或Notification)有关更改。
  • 我的 didselectrow 看起来像这样 func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { //Global.pickerResult = Global.pickerDataSource?[row] Global.setPickerResult(result : Global.pickerDataSource?[row] ?? "Test" ) } 我应该如何更改它以通知我? @vadian
  • 在 IBAction 中有对按钮的引用。添加在didSelectRow 中调用的回调闭包。在闭包的主体中设置标题
  • @vadian 我不会撒谎,我对此很陌生。如何连接回调闭包和 didselectrow,我从来没有做过回调闭包。这是在选择器视图控制器还是带有按钮的视图控制器上编码的。
  • 遗憾的是,问题中的代码过于模糊,无法提供具体建议。

标签: swift uibutton uipickerview


【解决方案1】:

我不知道Global 的全部内容是什么,最简单的解决方案可能是扩展pickerCompletionHandler,但这是另一个(简单)的解决方案:

  • PickerViewController 中添加一个回调,传递一个String 值并且没有返回值

    var callback : ((String) -> Void)?
    

    并在exitButton 中调用它(请变量名和函数名应该以小写字母开头)

    @IBAction func exitButton(_ sender: Any) {
        switch Global.pickerCompletionHandler {
    
        case 0:
            callback?(Global.pickerResult ?? "")
            Global.setProfileCountry(string:
                Global.pickerResult ?? "")
        default:
            print("nothing")
    
        }
        self.view.removeFromSuperview()
    }
    
  • countryPickButton(同样:小写字母)中设置回调并将sender设置为真实类型。回调设置标题

    @IBAction func countryPickButton(_ sender: UIButton) {
    
        Global.setPickerDataSource(data:["Test","test2","test3"])
        Global.setPickerCompletionHandler(int:0)
        let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PickerViewPopUpId") as! PickerViewController
        popOverVC.callback = { value in 
            sender.setTitle(value, for: .normal)
        }
    ...
    

【讨论】:

  • 这让我“无法调用非函数类型的值 ((String) -> Void)?”。我确实添加了 var 回调:((String) -> Void)?到pickerViewController,为了清楚起见,我会添加我的Globals,主要是为了让我可以通过多个swift文件交流信息
  • 我认为这是在说回调不是一个函数,因此不能返回一个值......所以做错了什么吗?我已经编辑了代码以将您添加的内容放入
  • 请仔细阅读我的代码。将 IBAction 的 sender 类型更改为 UIButton 并使用 sender.title。当函数以大写字母开头时,这正是混乱。实际上,如果 Global 结构仅在 PickerViewController 中使用,它是毫无意义的。
  • 我将 sender 更改为 UIButton,存在相同的错误,首先,“无法分配给属性:'title' 是一种方法”,然后我将其更改为:“popOverVC.callback { value in sender.setTitle (value, for: UIControl.State) } " "Cannot call value of non-function type '((String) -> Void)?'" 我又更新了代码
  • 这实际上是一个可重复使用的pickerviewcontroller,可以根据使用它的屏幕来更改要选择的数据。因此我不得不将它设置为一个全局变量。我将来也会合并登录和注册令牌
猜你喜欢
  • 1970-01-01
  • 2017-09-29
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 2012-07-21
相关资源
最近更新 更多