2016-04-14 62 views
0

我希望能夠從兩個地方調用此功能:當我完成編輯文本字段時,我想在stackView中沒有任何文本字段時添加新的webView,並且我還希望能夠使用barButtonItem這樣做。具有默認參數的swift函數也是一個選擇器?

我有兩個問題。當bar按鈕調用這個函數時,參數'url'成爲一個對象,輸入UIBarButtonItem。當它從textFieldShouldReturn中調用時,它正確地作爲NSURL進來。如果用戶未在地址欄中輸入任何內容,並且輸入,則會出現空白,並且不使用默認值。 (我喜歡它)

應該從textfieldShouldReturn函數看起來應該是什麼樣的,所以空白會觸發默認值?

我該如何處理一個事實,即我的函數或按鈕將調用該函數,爲什麼我的參數'url'成爲我想要的'發件人'?

override func viewDidLoad() { 
    super.viewDidLoad() 

    setDefaultTitle() 

    let add = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: #selector(ViewController.addWebView)) 
    let delete = UIBarButtonItem(barButtonSystemItem: .Trash, target: self, action: #selector(ViewController.deleteWebView)) 
    navigationItem.rightBarButtonItems = [delete, add] 
} 

    func addWebView(url: NSURL = NSURL(string: "https://www.google.com")!) { 
    let webView = UIWebView() 
    webView.delegate = self 
    stackView .addArrangedSubview(webView) 
    webView.loadRequest(NSURLRequest(URL: url)) 

    webView.layer.borderColor = UIColor.blueColor().CGColor 
    selectWebView(webView) 

    let recognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.webViewTapped)) 
    recognizer.delegate = self 
    webView.addGestureRecognizer(recognizer) 
} 

    func textFieldShouldReturn(textField: UITextField) -> Bool { 
    if let webView = activeWebView, address = addressBar.text { 
     if let url = NSURL(string: address) { 
      webView.loadRequest(NSURLRequest(URL: url)) 
     } 

    } else if stackView.arrangedSubviews.count == 0 { 
     let address = NSURL(string: addressBar.text!)! 
     addWebView(address) 
    } 
    textField.resignFirstResponder() 
    return true 
} 

回答

1

這是正確的,你得到的發件人對象其實是UIBarButtonItem。你聽說過Target-Action Cocoa模式嗎?如果否,您可以在這裏閱讀更多: https://developer.apple.com/library/ios/documentation/General/Conceptual/Devpedia-CocoaApp/TargetAction.html

對您而言,特別相關的部分是「操作方法必須具有某種形式」。

考慮引進addWebView超載:

func addWebView(sender: NSObject) { 

    addWebView(url: NSURL(string: "https://www.google.com")!) 
} 

private func addWebView(url: NSURL) { 
    //left as is ... 
} 

這裏是每戴夫的意見更新。 必須使用不同的名稱作爲實際的實現方法。否則,Swift編譯器無法解析分配的選擇器名稱。

有用的代碼,這表明該問題附着下面:

class Notifier: NSObject { 

    private var _target: NSObject! 
    private var _action: Selector! 

    func addObserver(target: NSObject, action: Selector) { 
     _target = target 
     _action = action 
    } 

    func invokeMethod() { 

     guard let t = _target else { 
      print("target must be set") 
      return 
     } 

     guard let a = _action else { 
      print("action must be set") 
      return 
     } 
     if t.respondsToSelector(a) { 
      t.performSelector(a, withObject: self) 
     } 
    } 

} 

class Observer: NSObject { 

    func subscribe(notifier: Notifier) { 
     notifier.addObserver(self, action: #selector(Observer.callback)) 
    } 

    func callback(sender: NSObject) { 
     callbackImpl(NSURL(string: "https://www.google.com")!) 
    } 

    private func callbackImpl(url: NSURL) { 
     print("url\(url)") 
    } 
} 

//client's code 
let n = Notifier() 
let o = Observer() 
o.subscribe(n) 
n.invokeMethod() 
+0

哦。我喜歡你所說的話,但Xcode不。它不起作用。 –

+0

你可以更具體一些,什麼不工作? BTW這對使用private關鍵字標記實際實現方法(接受url)很重要。 –

+0

'let add = UIBarButtonItem(barButtonSystemItem:.Add,target:self,action:#selector(ViewController.addWebView)) '停止工作。 –

相關問題