我正在使用Swift在xcode上试验UISwitches。我有它有几个公司名称及其相应的开关。从上到下,如果用户切换例如“Google”开启,则他们可以查看所选公司的facebook和twitter。如果他们选择其他公司,一旦他们打开该开关,例如“三星”,谷歌开关关闭,然后用户可以看到三星的Facebook和Twitter页面。
我的问题是......从上到下,它运作正常。我能看到从谷歌到三星的两个页面。但是,如果我从三星回到谷歌,谷歌开关打开,但它仍然显示三星的页面。但是,如果我打开saumsung开关,关闭然后转到谷歌,它工作正常。
我的假设是,当一个开关从底部到顶部打开另一个开关时,视觉上看起来很开,但它仍然是以编程方式开启的
我想知道人们是否有过类似的问题。如果没有,我希望如果他们发现自己处于类似情况,这对未来有帮助
这是我的主视图Controller
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的相同)
import UIKit
class FacebookViewController: UIViewController{
var webAddress: String = ""
@IBOutlet weak var CompanyFB: UIWebView!
override func viewWillAppear(animated: Bool) {
let myCompany: ViewController = self.tabBarController!.viewControllers![0] as! ViewController
let showGoogle: Bool = myCompany.Google
let showSamsung: Bool = myCompany.Samsung
let showFord: Bool = myCompany.Ford
let showToyota: Bool = myCompany.Toyota
let showEnix: Bool = myCompany.SquareEnix
let showBank:Bool = myCompany.ABCBank
if showGoogle {
webAddress = "https://www.facebook.com/Google/"
//myCompany.GoogleSwitch.on = false had this to test. either way is still doesnt work
// CompanyFB.loadRequest(NSURLRequest(URL: NSURL(string: webAddress)!))
}
if showSamsung {
webAddress = "https://www.facebook.com/SamsungUSA"
// myCompany.SamsungSwitch.on = false
// CompanyFB.loadRequest(NSURLRequest(URL: NSURL(string: webAddress)!))
}
if showFord {
webAddress = "https://www.facebook.com/ford/"
// CompanyFB.loadRequest(NSURLRequest(URL: NSURL(string: webAddress)!))
}
if showToyota {
webAddress = "https://www.facebook.com/toyota"
// CompanyFB.loadRequest(NSURLRequest(URL: NSURL(string: webAddress)!))
}
if showEnix {
webAddress = "https://www.facebook.com/SquareEnix"
}
if showBank {
webAddress = "https://www.facebook.com/ABC-Bank-132047286857188/"
}
CompanyFB.loadRequest(NSURLRequest(URL: NSURL(string: webAddress)!))
}
override func viewDidLoad() {
super.viewDidLoad()
// 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.
}
}
答案 0 :(得分:2)
您的问题是,您没有将单独的布尔与您的交换机保持同步。请考虑以下代码:
@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
答案 1 :(得分:1)
这里有一些事情,有些事情与你的问题无关,但我也会评论它们,所以你可以改进编码器。
1)Swift的约定规定您命名以小写字母开头的变量和方法。因此,GoogleSwitch
应为googleSwitch
等。另外,请尝试使用名称进行描述。在FacebookViewController
myCompany
类中,您有一个变量ViewController
。首先,应该调用类MyCompanyViewController
之类的内容,以便知道它是哪个视图控制器。然后myCompany
变量可以称为myCompanyViewController
。 CompanyFB
应该是companyFBWebView
。
2)你可以在这里简单地编写代码。对所有交换机使用单个IBAction
。一个常见问题(这可能是一个问题),当您在Interface Builder中复制和粘贴控件时,它有时会复制分配的操作,然后您添加另一个,因此每次切换时都会调用两个方法。通过使用单一方法,您可以节省大量重复的代码并避免此问题。
您的整个第一个ViewController
课程可以缩小为此(然后将所有开关连接到同一个IBOutlet
switchToggled:
:
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 for Google等应该与交换机相同,所以只需使用switch.on
值即可。编辑:(或Paulw11提到的,使用计算属性)。
4)当使用if
来测试变量状态,或者在FacebookViewController
类中使用多个变量状态时,如果只发生一种可能的情况,请使用{{1}而不是多个else if
的。在您的情况下,您一次触发两个或更多个案件(由于您的其他错误)。如果你使用了if
条款,那么你只会触发一个条款,而你可能会早些时候缩小你的其他bug。
else if
5)扩展#4你可以改变它以利用Swift强大的 if showGoogle {
webAddress = "https://www.facebook.com/Google/"
}
else if showSamsung {
webAddress = "https://www.facebook.com/SamsungUSA/"
}
...
功能。
enum
6)在Swift中,避免像瘟疫那样使用import UIKit
class FacebookViewController: UIViewController {
enum Company: String {
case Google = "https://www.facebook.com/Google/"
case Samsung = "https://www.facebook.com/SamsungUSA/"
case Ford = "https://www.facebook.com/ford/"
case Toyota = "https://www.facebook.com/toyota/"
case SquareEnix = "https://www.facebook.com/SquareEnix/"
case ABCBank = "https://www.facebook.com/ABC-Bank-132047286857188/"
}
var company: Company = .Google // Default to Google
@IBOutlet weak var companyFBWebView: UIWebView!
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let myCompanyViewController: ViewController = self.tabBarController!.viewControllers![0] as! ViewController
if myCompanyViewController.googleSwitch.on {
company = .Google
}
else if myCompanyViewController.samsungSwitch.on {
company = .Samsung
}
else if myCompanyViewController.fordSwitch.on {
company = .Ford
}
else if myCompanyViewController.toyotaSwitch.on {
company = .Toyota
}
else if myCompanyViewController.squareEnixSwitch.on {
company = .SquareEnix
}
else if myCompanyViewController.abcBankSwitch.on {
company = .ABCBank
}
if let url = NSURLRequest(URL: NSURL(string: company.rawValue)) {
companyFBWebView.loadRequest(url)
}
}
}
。理想情况下,您只会将其用于!
以及您知道某些值存在的其他情况。在某些情况下,行IBOutlet
可能会崩溃。可能是由于时间问题或您可能对代码进行的其他更改。更安全地使用let myCompanyViewController: ViewController = self.tabBarController!.viewControllers![0] as! ViewController
检查选项并优雅地处理错误。
7)我刚刚注意到另一个问题,因为我正在校对。任何时候*你if let
来自超类的方法,请确保你也调用超级版本。因此,您的override
等电话需要调用超级版本,否则您可能会变得非常奇怪,难以追踪错误。
答案 2 :(得分:0)
我假设您的IBActions与ValueChanged事件挂钩,并且您希望它们在两个实例中触发:当您通过触摸它来更改开关时;或者当您更改on
属性的值时。
如果是这样,问题是事件不会在第二种情况下触发,只触发第一种情况。因此,一旦Google
设置为true,将其设置为false的唯一方法是将开关触摸为关闭。
由于您的模型只需要打开一个开关,因此您可以使用一个包含应该打开的开关的变量。当您触摸开关时,只需更新该变量并重新显示所有变量即可。对此变量使用enum
会很有帮助。沿着:
enum Switches {
case None
case Google
case Samsung
}
var onSwitch = Switches.None
然后在每个IBAction中编写代码:
@IBAction func ActiveGoogle(sender: UISwitch) {
if sender.on == true {
onSwitch = Switches.Google
updateSwitches()
}
}
updateSwitches
看起来像:
func updateSwitches() {
GoogleSwitch.on = (onSwitch == Switches.Google)
SamsungSwitch.on = (onSwitch == Switches.Samsung)
}