Ios UI开关由用户关闭,但仍按编程方式打开
我正在使用Swift在xcode上试验UI开关。我有它的地方有一些公司名称和他们相应的开关。从上到下,如果用户打开例如“谷歌”开关,那么他们就可以查看所选的公司facebook和twitter。如果他们选择另一家公司,一旦他们打开该开关,例如“三星”,谷歌开关就会关闭,用户就可以看到三星的facebook和twitter页面 我的问题是。。。从上到下,它工作得很好。我可以看到从谷歌到三星的两个页面。但如果我从三星回到谷歌,谷歌的开关是打开的,但它仍然显示三星的页面。但是,如果我打开、关闭saumsung开关,然后转到谷歌,它工作正常 我的假设是,当另一个开关从下到上打开时,开关从视觉上看是关闭的,但它仍然以编程方式打开 我想知道人们是否也有类似的问题。如果没有,我希望这能帮助那些将来发现自己处于类似情况的人 这是我的主视图控制器Ios UI开关由用户关闭,但仍按编程方式打开,ios,swift,uiswitch,Ios,Swift,Uiswitch,我正在使用Swift在xcode上试验UI开关。我有它的地方有一些公司名称和他们相应的开关。从上到下,如果用户打开例如“谷歌”开关,那么他们就可以查看所选的公司facebook和twitter。如果他们选择另一家公司,一旦他们打开该开关,例如“三星”,谷歌开关就会关闭,用户就可以看到三星的facebook和twitter页面 我的问题是。。。从上到下,它工作得很好。我可以看到从谷歌到三星的两个页面。但如果我从三星回到谷歌,谷歌的开关是打开的,但它仍然显示三星的页面。但是,如果我打开、关闭saum
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var GoogleSwitch: UISwitch!
@IBOutlet weak var SamsungSwitch: UISwitch!
@IBOutlet weak var FordSwitch: UISwitch!
@IBOutlet weak var ToyotaSwitch: UISwitch!
@IBOutlet weak var SquareEnixSwitch: UISwitch!
@IBOutlet weak var ABCBankSwitch: UISwitch!
var Google: Bool = false
var Samsung: Bool = false
var Ford: Bool = false
var Toyota:Bool = false
var SquareEnix :Bool = false
var ABCBank :Bool = false
override func viewDidLoad() {
super.viewDidLoad()
// ABCBankSwitch.addTarget(self, action: Selector("switchIsChanged:"), forControlEvents: UIControlEvents.ValueChanged)
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func ActiveGoogle(sender: UISwitch) {
if sender.on == true
{
GoogleSwitch.on = true
SamsungSwitch.on = false
ToyotaSwitch.on = false
SquareEnixSwitch.on = false
ABCBankSwitch.on = false
Google = true
// GoogleSwitch.on = true
}
else
{ Google = false
sender.on = false
}
// sender.on = false
}
@IBAction func ActiveSamsung(sender: UISwitch) {
if sender.on == true
{
GoogleSwitch.on = false
SamsungSwitch.on = true
FordSwitch.on = false
ToyotaSwitch.on = false
SquareEnixSwitch.on = false
ABCBankSwitch.on = false
Samsung = true
}
else
{sender.on = false
Samsung = false}
}
@IBAction func ActiveFord(sender: UISwitch) {
if sender.on == true
{Ford = true
GoogleSwitch.on = false
SamsungSwitch.on = false
FordSwitch.on = true
ToyotaSwitch.on = false
SquareEnixSwitch.on = false
ABCBankSwitch.on = false
}
else
{ if sender.on == false {
Ford = false}
}
}
@IBAction func ActiveToyota(sender: UISwitch) {
if sender.on == true
{ Toyota = true
GoogleSwitch.on = false
SamsungSwitch.on = false
FordSwitch.on = false
ToyotaSwitch.on = true
SquareEnixSwitch.on = false
ABCBankSwitch.on = false
}
else
{ Toyota = false}
}
@IBAction func ActiveEnix(sender: UISwitch) {
if sender.on == true
{ SquareEnix = true
GoogleSwitch.on = false
SamsungSwitch.on = false
FordSwitch.on = false
ToyotaSwitch.on = false
//SquareEnixSwitch.on = true
ABCBankSwitch.on = false
}
else
{ SquareEnix = false
// sender.on = false
}
}
@IBAction func ActiveABC(sender: UISwitch) {
if sender.on == true
{ ABCBank = true
ABCBankSwitch.setOn(true, animated: true)
GoogleSwitch.on = false
SamsungSwitch.on = false
FordSwitch.on = false
ToyotaSwitch.on = false
SquareEnixSwitch.on = false
}
}
else
{
ABCBankSwitch.setOn(false, animated: true)
ABCBank = false
// sender.on = false
}
}
}
这是我的FacebookViewController。(不在twitter上发布,因为它与facebook几乎完全相同)
你的问题是,你没有保持你的独立布尔与你的开关同步。考虑这个代码:
@IBAction func ActiveGoogle(sender: UISwitch) {
if sender.on == true {
GoogleSwitch.on = true
SamsungSwitch.on = false
ToyotaSwitch.on = false
SquareEnixSwitch.on = false
ABCBankSwitch.on = false
Google = true
}
else {
Google = false
sender.on = false
}
}
如果我更改“Google”开关,则Google
变量将相应地设置为true/false。此代码还关闭所有其他开关,但不会更改布尔关联变量。因此,如果在选择Google I之后选择“Samsung”,Google开关将关闭,但Google
变量仍然为真
您可以使用计算属性,而不是单独的布尔值:
var Google: Bool {
return self.GoogleSwitch.on
}
等等
此外,按照惯例,变量和函数应该以小写字母开头,因此它应该是
var google
和func activateGoogle
您的问题是您没有将单独的布尔值与开关保持同步。考虑这个代码:
@IBAction func ActiveGoogle(sender: UISwitch) {
if sender.on == true {
GoogleSwitch.on = true
SamsungSwitch.on = false
ToyotaSwitch.on = false
SquareEnixSwitch.on = false
ABCBankSwitch.on = false
Google = true
}
else {
Google = false
sender.on = false
}
}
如果我更改“Google”开关,则Google
变量将相应地设置为true/false。此代码还关闭所有其他开关,但不会更改布尔关联变量。因此,如果在选择Google I之后选择“Samsung”,Google开关将关闭,但Google
变量仍然为真
您可以使用计算属性,而不是单独的布尔值:
var Google: Bool {
return self.GoogleSwitch.on
}
等等
此外,按照惯例,变量和函数应该以小写字母开头,因此它应该是
var google
和func activateGoogle
我假设您的iActions连接到ValueChanged事件,并且您希望它们在两种情况下触发:当您通过触摸开关来更改开关时;或者当您更改属性上的值时
如果是这样,问题是事件在第二种情况下不会触发,而只在第一种情况下触发。因此,一旦Google
设置为true,将其设置回false的唯一方法就是将开关触到off
由于您的模型只希望打开一个开关,因此您可以使用一个包含应该打开的开关的变量。当你触摸一个开关时,只需更新一个变量并重新显示所有变量。对这个变量使用enum
会很有帮助。大致如下:
enum Switches {
case None
case Google
case Samsung
}
var onSwitch = Switches.None
@IBAction func ActiveGoogle(sender: UISwitch) {
if sender.on == true {
onSwitch = Switches.Google
updateSwitches()
}
}
然后在每个iAction中按照以下行进行编码:
enum Switches {
case None
case Google
case Samsung
}
var onSwitch = Switches.None
@IBAction func ActiveGoogle(sender: UISwitch) {
if sender.on == true {
onSwitch = Switches.Google
updateSwitches()
}
}
而updateswitch
看起来像:
func updateSwitches() {
GoogleSwitch.on = (onSwitch == Switches.Google)
SamsungSwitch.on = (onSwitch == Switches.Samsung)
}
我假设您的iAction连接到ValueChanged事件,您希望它们在两种情况下触发:当您通过触摸开关来更改开关时;或者当您更改
属性上的值时
如果是这样,问题是事件在第二种情况下不会触发,而只在第一种情况下触发。因此,一旦Google
设置为true,将其设置回false的唯一方法就是将开关触到off
由于您的模型只希望打开一个开关,因此您可以使用一个包含应该打开的开关的变量。当你触摸一个开关时,只需更新一个变量并重新显示所有变量。对这个变量使用enum
会很有帮助。大致如下:
enum Switches {
case None
case Google
case Samsung
}
var onSwitch = Switches.None
@IBAction func ActiveGoogle(sender: UISwitch) {
if sender.on == true {
onSwitch = Switches.Google
updateSwitches()
}
}
然后在每个iAction中按照以下行进行编码:
enum Switches {
case None
case Google
case Samsung
}
var onSwitch = Switches.None
@IBAction func ActiveGoogle(sender: UISwitch) {
if sender.on == true {
onSwitch = Switches.Google
updateSwitches()
}
}
而updateswitch
看起来像:
func updateSwitches() {
GoogleSwitch.on = (onSwitch == Switches.Google)
SamsungSwitch.on = (onSwitch == Switches.Samsung)
}
这里有一些事情正在发生,有些与您的问题无关,但我也会对它们进行评论,以便您可以作为一名编码人员进行改进
1) Swift的约定要求您以小写字母开始命名变量和方法。所以GoogleSwitch
应该是GoogleSwitch
等等。另外,试着用名字来描述。在FacebookViewController
中,有一个变量myCompany
用于ViewController
类。首先,该类应该被称为类似MyCompanyViewController
的类,以便您知道它是哪个视图控制器。然后可以调用myCompanyViewController
变量myCompanyViewController
CompanyFB
应该类似于companyFBWebView
2) 您可以在这里简单地编写代码。对所有开关使用一个iAction
。一个常见的问题(这里可能是一个问题)是,当您在Interface Builder中复制和粘贴控件时,它有时也会复制指定的操作,然后添加另一个,因此每次切换时它都会调用两个方法。通过使用单一方法,您可以节省大量重复代码并避免此问题
您的第一个ViewController
类可以压缩为这个类(然后将所有交换机连接到同一个IBOutlet
交换机切换:
:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var googleSwitch: UISwitch!
@IBOutlet weak var samsungSwitch: UISwitch!
@IBOutlet weak var fordSwitch: UISwitch!
@IBOutlet weak var toyotaSwitch: UISwitch!
@IBOutlet weak var squareEnixSwitch: UISwitch!
@IBOutlet weak var abcBankSwitch: UISwitch!
@IBAction func switchToggled(sender: UISwitch) {
// Remember the state of the triggered switch because we're about to turn it off
let newState: Bool = sender.on
googleSwitch.on = false
samsungSwitch.on = false
fordSwitch.on = false
toyotaSwitch.on = false
squareEnixSwitch.on = false
abcBankSwitch.on = false
// Restore the state of the switch
sender.on = newState
}
}
3) 避免对同一事物使用重复的变量,比如谷歌的Bool等等