24233


下のように書いていますが、もっとシンプルな書き方はありせんか？ 重複した部分が多く、冗長な気がするのですが。

[code]

    func addSomeButton(view:AnyObject) {
    
    
        let viewForMyButton = UIView()
    
        //...
    
    
        //Viewにボタン追加
        if view is UITextView {
            (view as! UITextView).inputAccessoryView = viewForMyButton
        } else if view is UITextField {
            (view as! UITextField).inputAccessoryView = viewForMyButton
        }
    }
    
[/code]


CC BY-SA 3.0
2016-04-21T09:21:05.250
24219
2016-04-22T09:35:58.423
2016-04-22T09:35:58.423
12297
12297
question
swift
引数に渡されるオブジェクトの型によって、引数の型を変更したい。シンプルな書き方は？


例えばswitch-caseを使うとこんな書き方ができます。

[code]

        switch view {
        case let v as UITextView:
            v.inputAccessoryView = viewForMyButton
        case let v as UITextField:
            v.inputAccessoryView = viewForMyButton
        default:
            break
        }
    
[/code]

行数はかえって増えてしまってますね。

if文にもcaseパターンが使えるので、こんな書き方もできます。

[code]

        if case let v as UITextView = view  {
            v.inputAccessoryView = viewForMyButton
        } else if case let v as UITextField = view {
            v.inputAccessoryView = viewForMyButton
        }
    
[/code]

この場面でif文中にcaseパターンを使うのは少し無理矢理って感じもしますが。

`as?`演算子を使えば、caseパターンではなくif-letでも同じことが書けます。

[code]

        if let v = view as? UITextView {
            v.inputAccessoryView = viewForMyButton
        } else if let v = view as? UITextField {
            v.inputAccessoryView = viewForMyButton
        }
    
[/code]

これが文字数的には一番短いし、一般的でしょうか。

こんな前準備をしておけば、

[code]

    protocol InputAccessoryViewType: class {
        var inputAccessoryView: UIView? {get set}
    }
    extension UITextView: InputAccessoryViewType {}
    extension UITextField: InputAccessoryViewType {}
    
[/code]

こんな書き方もできるんですが。

[code]

        if let v = view as? InputAccessoryViewType {
            v.inputAccessoryView = viewForMyButton
        }
    
[/code]

準備まで入れるととても「シンプル」とは言えないですね。

「もっとシンプルな書き方はありせんか？」と言う質問は少々「曖昧すぎる」気がするので、『「`as!`による強制キャスト」のように「使わなくて済むなら使いたくない機能」を出来るだけ省く』と解釈させてもらいました。思いつくのはこんなものでしょうか。


CC BY-SA 3.0
2016-04-21T11:22:00.133
24223
2016-04-21T11:22:00.133
13972
24219
answer


`inputAccessoryView` は `UITextView` と `UITextField` の共通の祖先 `UIResponder`
のプロパティですから、

[code]

    if view is UIResponder {
        (view as! UIResponder).inputAccessoryView = viewForMyButton
    }
    
[/code]

という感じでよろしいのではないでしょうか。

パラメータ `view` の型を `UIResponder` か `UIView` に変更できれば、型判定も `as` も必要ありません。

(追記)  
コメントで指摘があったように、この回答は間違いです。動きません。


CC BY-SA 3.0
2016-04-22T00:09:11.930
24232
2016-04-22T08:14:20.590
2016-04-22T08:14:20.590
3475
3475
24219
answer


そもそものメソッドを分割してしまうと言う手もありますね。

[code]

    func addSomeButton(view: UITextView) {
        let viewForMyButton = UIView()
    
        // 共通の処理は別メソッドにくくり出す
    
        view.inputAccessoryView = viewForMyButton
    }
    
    func addSomeButton(view: UITextField) {
        let viewForMyButton = UIView()
    
        // 共通の処理を呼ぶ
    
        view.inputAccessoryView = viewForMyButton
    }
    
[/code]

* * *

他の方も書かれていますが『シンプルな書き方』は受け取る人によって変わるでしょうし、自分が好きなようにやれば良いと思いますよ。


CC BY-SA 3.0
2016-04-22T00:27:13.957
24233
2016-04-22T00:27:13.957
7459
24219
answer