快速解决选择问题

时间:2016-06-02 13:15:18

标签: ios swift

我是一个快速的新手,并试图让选项工作。我已经完成了很多谷歌搜索,阅读Apple Docs等,但我正在努力使用我的ViewController中的这个(简化的)片段:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == "segueToWebView") {
        // check what we're passing around
        print(sender!.urlString) // Optional("http://www.bbc.co.uk")

        // do some url validation etc
        var destUrl:String
        if sender!.urlString == nil{
            destUrl = "http://www.google.com"
        } else {
            destUrl = sender!.urlString // *** Error here ***
        }

        let targetWebViewController:GDWebViewController = segue.destinationViewController as! GDWebViewController
        targetWebViewController.loadURLWithString(destUrl)
        targetWebViewController.showsToolbar = true
        targetWebViewController.title = sender!.busName // this works correctly too (so isn't that a String?)
    }
}

上面标记的行上的错误为Cannot assign value of type 'String?!' to type 'String'。我尝试过以不同方式展开它,但却无法弄明白。

更多代码

发件人是一个自定义UIButton子类,具有以下结构:

import UIKit

class TestButton: UIButton {
    var urlString: String?
    var busName: String?
}

我已将变量设置为可选,因为我不知道按钮是否会赢得这些属性。

点击按钮时调用的方法是:

func tapTap(sender: TestButton) {
    print(sender.busName, sender.urlString) // Optional("My Button") Optional("http://www.bbc.co.uk")
    self.performSegueWithIdentifier("segueToWebView", sender: sender)
}

我知道Swift可选项对于像我这样的新手来说是一个常见的绊脚石,并且有很多关于他们的文档,但我无法弄明白,所以任何帮助都会很棒。

3 个答案:

答案 0 :(得分:10)

有三个级别的选项:

  • sender: AnyObject?参数是可选的。
  • AnyObject发送任意消息的行为与可选消息类似 链接并返回一个隐式解包的可选项 (比较here)。
  • var urlString: String?属性是可选的。

要解析前两个选项,请使用可选的绑定/强制转换 具体按钮类:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == "segueToWebView") {
        if let button = sender as? TestButton {
           // The type of `button`  is `TestButton`
           // ...
        }
    }
}

现在

var destUrl: String
if button.urlString == nil {
    destUrl = "http://www.google.com"
} else {
    destUrl = button.urlString!
}

会编译,但用更好的方法处理 零合并算子:

let destUrl = button.urlString ?? "http://www.google.com"

请注意,不再强制解包!运算符!

答案 1 :(得分:3)

你只需做这样的事情:

var destUrl:String
if let durl = sender!.urlString {
   destUrl = durl
} else {
   destUrl = "http://www.google.com"
}

代码中的问题是destUrl是一个String但是发件人!.urlString是可选的。所以你不能将一个分配给另一个。在分配之前,您必须打开可选项。要么强行解开它(带!),如果让它。我建议如果让,但这取决于你。

答案 2 :(得分:3)

您正在手动测试nil的字符串,但是您忘了打开它:

var destUrl:String
if sender!.urlString == nil{
    destUrl = "http://www.google.com"
} else {
    destUrl = sender!.urlString!
}

(请参阅添加的感叹号。)

但是打开像这样的字符串实际上更容易:

let destUrl = sender!.urlString ?? "http://www.google.com"

??运算符测试nil,unwraps或返回右侧,全部在一行。