像 UISwitch 一样使用 UISegmentedControl
Using a UISegmentedControl like a UISwitch
是否可以像使用三路 UISwitch
一样使用具有 3 个分段的 UISegmentedControl
?我尝试在我的应用程序的设置部分中使用一个作为货币选择器,但没有成功,当我切换视图时它一直重置到第一部分,这造成了一个大混乱。
我是这样进行的:
IBAction func currencySelection(_ sender: Any) {
switch segmentedControl.selectedSegmentIndex {
case 0:
WalletViewController.currencyUSD = true
WalletViewController.currencyEUR = false
WalletViewController.currencyGBP = false
MainViewController().refreshPrices()
print(0)
case 1:
WalletViewController.currencyUSD = false
WalletViewController.currencyEUR = true
WalletViewController.currencyGBP = false
MainViewController().refreshPrices()
print(1)
case 2:
WalletViewController.currencyUSD = false
WalletViewController.currencyEUR = false
WalletViewController.currencyGBP = true
MainViewController().refreshPrices()
print(2)
default:
break
}
}
it keeps reseting to the first segment when I switch views
是的,是的。为避免这种情况,每次使用 UISegmentedControl
加载视图时,都应将正确的开关值设置为 segmentedControl.selectedSegmentIndex
。
UPD
好的,MainViewController
的行为可以类似于这样:
final class MainViewController: UIViewController {
private var savedValue = 0
override func viewDidLoad() {
super.viewDidLoad()
}
func openSettingsController() {
let viewController = SettingsController.instantiate() // simplify code a bit. use the full controller initialization
viewController.configure(value: savedValue, onValueChanged: { [unowned self] value in
self.savedValue = value
})
navigationController?.pushViewController(viewController, animated: true)
}
}
还有SettingsViewController
:
final class SettingsViewController: UIViewController {
@IBOutlet weak var segmentedControl: UISegmentedControl!
private var value: Int = 0
var onValueChanged: ((Int) -> Void)?
func configure(value: Int, onValueChanged: @escaping ((Int) -> Void)) {
self.value = value
self.onValueChanged = onValueChanged
}
override func viewDidLoad() {
super.viewDidLoad()
segmentedControl.selectedSegmentIndex = value
}
@IBAction func valueChanged(_ sender: UISegmentedControl) {
onValueChanged?(sender.selectedSegmentIndex)
}
}
如果您从 SettingsViewController
移动,您应该保留您选择的值的主要想法。为此,您可以创建闭包
var onValueChanged: ((Int) -> Void)?
将选定的 UISegmentedControl
值传回 MainViewController
。将来当您再次打开 SettingsViewController
时,您只需 configure()
这个值并将其设置为 UI.
The UISegmentedControl
is implemented in the
SettingsViewController
of the app to choose between currencies to
display in the MainViewController
.
(摘自@pacification 的回答中的评论。)
这就是我要找的丢失的部分。它提供了很多上下文。
TL;DR;
是的,您可以使用三段UISegmentedControl
作为三路开关。唯一的真实要求是您只能选择一个值或状态。
但我不明白为什么您的代码引用了两个视图控制器和一些导致重置段的切换视图。做你想做的事情的一个很好的方法是:
有MainViewController
现在SettingsViewController
。模态呈现意味着用户一次只做一件事。当他们进行设置更改时,您不希望他们添加新的货币值。
在SettingsViewController
中创建委托协议并使MainViewController
符合它。这将对设置所做的更改紧密耦合到对这些更改感兴趣的视图控制器。
这是我所说的模板:
SettingsViewController:
protocol SettingsVCDelegate {
func currencyChanged(sender: SettingsViewController)
}
class SettingsViewController : UIViewController {
var delegate:SettingsVCDelegate! = nil
var currency:Int = 0
@IBAction func valueChanged(_ sender: UISegmentedControl) {
currency = sender.selectSegmentIndex
delegate.currencyChanged(sender:self)
}
}
主视图控制器:
class MainViewController: UIViewController, SettingsVCDelegate {
var currency:Int = 0
let settingsVC = SettingsViewController()
override func viewDidLoad() {
super.viewDidLoad()
settingsVC.delegate = self
}
func presentSettings() {
present(settingsVC, animated: true, completion: nil)
}
func currencyChanged(sender:SettingsViewController) {
currency = sender.currency
}
}
您还可以创建类型为 Int
的 enum
以使您的代码更具可读性,将每个值命名为 currencyUSD
、currencyEUR
和 currencyGBP
.我会把它留给你作为学习练习。
是否可以像使用三路 UISwitch
一样使用具有 3 个分段的 UISegmentedControl
?我尝试在我的应用程序的设置部分中使用一个作为货币选择器,但没有成功,当我切换视图时它一直重置到第一部分,这造成了一个大混乱。
我是这样进行的:
IBAction func currencySelection(_ sender: Any) {
switch segmentedControl.selectedSegmentIndex {
case 0:
WalletViewController.currencyUSD = true
WalletViewController.currencyEUR = false
WalletViewController.currencyGBP = false
MainViewController().refreshPrices()
print(0)
case 1:
WalletViewController.currencyUSD = false
WalletViewController.currencyEUR = true
WalletViewController.currencyGBP = false
MainViewController().refreshPrices()
print(1)
case 2:
WalletViewController.currencyUSD = false
WalletViewController.currencyEUR = false
WalletViewController.currencyGBP = true
MainViewController().refreshPrices()
print(2)
default:
break
}
}
it keeps reseting to the first segment when I switch views
是的,是的。为避免这种情况,每次使用 UISegmentedControl
加载视图时,都应将正确的开关值设置为 segmentedControl.selectedSegmentIndex
。
UPD
好的,MainViewController
的行为可以类似于这样:
final class MainViewController: UIViewController {
private var savedValue = 0
override func viewDidLoad() {
super.viewDidLoad()
}
func openSettingsController() {
let viewController = SettingsController.instantiate() // simplify code a bit. use the full controller initialization
viewController.configure(value: savedValue, onValueChanged: { [unowned self] value in
self.savedValue = value
})
navigationController?.pushViewController(viewController, animated: true)
}
}
还有SettingsViewController
:
final class SettingsViewController: UIViewController {
@IBOutlet weak var segmentedControl: UISegmentedControl!
private var value: Int = 0
var onValueChanged: ((Int) -> Void)?
func configure(value: Int, onValueChanged: @escaping ((Int) -> Void)) {
self.value = value
self.onValueChanged = onValueChanged
}
override func viewDidLoad() {
super.viewDidLoad()
segmentedControl.selectedSegmentIndex = value
}
@IBAction func valueChanged(_ sender: UISegmentedControl) {
onValueChanged?(sender.selectedSegmentIndex)
}
}
如果您从 SettingsViewController
移动,您应该保留您选择的值的主要想法。为此,您可以创建闭包
var onValueChanged: ((Int) -> Void)?
将选定的 UISegmentedControl
值传回 MainViewController
。将来当您再次打开 SettingsViewController
时,您只需 configure()
这个值并将其设置为 UI.
The
UISegmentedControl
is implemented in theSettingsViewController
of the app to choose between currencies to display in theMainViewController
.
(摘自@pacification 的回答中的评论。)
这就是我要找的丢失的部分。它提供了很多上下文。
TL;DR;
是的,您可以使用三段UISegmentedControl
作为三路开关。唯一的真实要求是您只能选择一个值或状态。
但我不明白为什么您的代码引用了两个视图控制器和一些导致重置段的切换视图。做你想做的事情的一个很好的方法是:
有
MainViewController
现在SettingsViewController
。模态呈现意味着用户一次只做一件事。当他们进行设置更改时,您不希望他们添加新的货币值。在
SettingsViewController
中创建委托协议并使MainViewController
符合它。这将对设置所做的更改紧密耦合到对这些更改感兴趣的视图控制器。
这是我所说的模板:
SettingsViewController:
protocol SettingsVCDelegate {
func currencyChanged(sender: SettingsViewController)
}
class SettingsViewController : UIViewController {
var delegate:SettingsVCDelegate! = nil
var currency:Int = 0
@IBAction func valueChanged(_ sender: UISegmentedControl) {
currency = sender.selectSegmentIndex
delegate.currencyChanged(sender:self)
}
}
主视图控制器:
class MainViewController: UIViewController, SettingsVCDelegate {
var currency:Int = 0
let settingsVC = SettingsViewController()
override func viewDidLoad() {
super.viewDidLoad()
settingsVC.delegate = self
}
func presentSettings() {
present(settingsVC, animated: true, completion: nil)
}
func currencyChanged(sender:SettingsViewController) {
currency = sender.currency
}
}
您还可以创建类型为 Int
的 enum
以使您的代码更具可读性,将每个值命名为 currencyUSD
、currencyEUR
和 currencyGBP
.我会把它留给你作为学习练习。