0

この関数を 2 つの場所から呼び出せるようにしたかったのです。テキスト フィールドの編集が終了したら、webViewa に何もないときに新しい を追加したいのとstackView、 a を使用しbarButtonItemてそうできるようにしたいのです。

2 つの問題があります。バー ボタンがこの関数を呼び出すと、パラメーター「url」がオブジェクト type になりますUIBarButtonItem。から呼び出されるとtextFieldShouldReturn、適切に として入りますNSURL。ユーザーがアドレス フィールドに何も入力せずに Enter キーを押すと、空白NSURLが入り、デフォルト値は使用されません。(そうであってほしい)

textfieldShouldReturn空白がデフォルトをトリガーするように、関数からの呼び出しはどのように見えるべきですか?

関数またはボタンのいずれかが関数を呼び出すという事実をどのように処理すればよいですか?また、名前付きパラメーター「url」が「sender」と推測されるものになるのはなぜですか?

    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
}
4

1 に答える 1

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 ...
}

これは、Dave のコメントによる更新です。実際の実装方法には別の名前を使用する必要があります。そうしないと、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()
于 2016-04-14T06:53:43.493 に答える