在搜索中,我看到这是一个常见问题,但是我尝试了一些解决方案,但仍无法解决。下面是一个简单的例子。当我运行该应用程序并按按钮时,将按预期打印0。按下button2之后,也按预期打印按钮1。如果我移动选择器,然后按按钮,我希望是2,但仍然是1。
我收集到这是因为ViewController()。sample()正在创建一个副本,而实际上并未更改“原始” ViewController()中的变量。我为需要重新配置以获得所需的行为而感到困惑。
import UIKit
class pickerHelper: NSObject, UIPickerViewDataSource, UIPickerViewDelegate {
let data: [String]
init(data: [String]) {
self.data = data
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
data.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
data[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
ViewController().sample()
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
p1.delegate = helper1
p1.dataSource = helper1
}
@IBOutlet weak var p1: UIPickerView!
let helper1 = pickerHelper(data:["a", "b", "c"])
var test = Int()
@IBAction func button(_ sender: Any) {
print(test)
}
@IBAction func button2(_ sender: Any) {
test = 1
}
func sample() {
test = 2
}
}
答案 0 :(得分:1)
在这种情况下,您将使用委托模式或回调闭包;后者更“迅速”。
有代表团:
protocol PickerHelperDelegate {
func pickerHelper(_ helper: selectedRow row:)
}
然后在您的PickerHelper
中添加一个委托属性,并在需要时调用该委托:
class PickerHelper: NSObject, UIPickerViewDataSource, UIPickerViewDelegate {
let data: [String]
var delegate: PickerHelperDelegate?
init(data: [String]) {
self.data = data
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
data.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
data[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.delegate?.pickerHelper(self, selectedRow: row)
}
}
在视图控制器中,您需要分配委托并实现协议功能:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
p1.delegate = helper1
p1.dataSource = helper1
helper1.delegate = self // Assign this object as the picker helper's delegate
}
@IBOutlet weak var p1: UIPickerView!
let helper1 = pickerHelper(data:["a", "b", "c"])
var test = Int()
}
extension ViewController: PickerHelperDelegate {
func pickerHelper(_ helper: PickerHelper, selectedRow row:Int) {
self.sample()
print("Selected row \(row)")
}
}
您可以使用闭包执行类似的操作:
class PickerHelper: NSObject, UIPickerViewDataSource, UIPickerViewDelegate {
let data: [String]
var changeHandler: ((Int)->Void)?
init(data: [String]) {
self.data = data
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
data.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
data[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.changeHandler?(row)
}
}
在视图控制器中,您需要为changeHandler
属性分配一个闭包:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
p1.delegate = helper1
p1.dataSource = helper1
helper.changeHandler = { row in
self.sample()
print("Selected row \(row)")
}
}
您还可以更改协议或闭包以传回data
元素,而不只是行号,并为PickerHelper
使用泛型,这样它不仅限于字符串。
请注意,类按约定以大写字母开头,因此您应该说PickerHelper
,而不是pickerHelper
。
答案 1 :(得分:0)
您可以使用static属性将其状态保留在类中。
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
p1.delegate = helper1
p1.dataSource = helper1
}
@IBOutlet weak var p1: UIPickerView!
let helper1 = pickerHelper(data:["a", "b", "c"])
static var test = Int()
@IBAction func button(_ sender: Any) {
print(test)
}
@IBAction func button2(_ sender: Any) {
ViewController.test = 1
}
static func sample() {
test = 2
}
}