UIBarButtonItemに枠を付ける

2015/08/05 追記
画像リソースを用意しないバージョンも書きました!
— ここまで追記 —

コードでUIBarButtonItemを追加するのに、
styleに対して.Borderedを設定しても意味がなくて、
いろいろ試してみた結果、背景に画像を割り当てることにした。

    @IBOutlet weak var myNavigationItem: UINavigationItem! // 接続済み

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        /* 省略 */
        
        let toneInitButton = UIBarButtonItem( title: "Init Tone", style: .Plain, target: self, action: Selector("toneInitButtonTapped:") )
        myNavigationItem.setRightBarButtonItem( toneInitButton, animated: false )

        let toneLoadButton = UIBarButtonItem( title: "Load", style: .Plain, target: self, action: Selector("toneLoadButtonTapped:") )
        let toneSaveButton = UIBarButtonItem( title: "Save", style: .Plain, target: self, action: Selector("toneSaveButtonTapped:") )
        myNavigationItem.setLeftBarButtonItems( [ toneLoadButton, toneSaveButton ], animated: false )

        for btn in [ toneLoadButton, toneSaveButton, toneInitButton ] {
            let w: CGFloat = 6.0
            let backgroundImage = UIImage( named: "round_rect_r4" /* or "round_rect_r3" */ )!.resizableImageWithCapInsets(
                UIEdgeInsets(top: w, left: w, bottom: w, right: w) ).imageWithRenderingMode( .AlwaysTemplate )
            btn.setBackgroundImage( backgroundImage, forState: UIControlState.Normal, barMetrics: UIBarMetrics.Default )
            btn.setTitleTextAttributes( [
                NSFontAttributeName : UIFont(name: "Futura-CondensedMedium", size: 17) as! AnyObject
                ], forState: .Normal )
        }

        /* 省略 */

UIBarButtonItem#setBackgroundImageを呼ぶと、
アピアランスで設定したフォント設定が初期化されちゃう(*1)ので、
仕方なく再度設定している。

でもって、”round_rect_r3″、及び”round_rect_r4″はこちら。

20150803-1
round_rect_r3.pngにリネームしてください。

20150803-2
round_rect_r4.pngにリネームしてください。

これらはイラストレータを使って、14×14の領域に対して、
10×10の正方形に外接するように角丸の四角形を描いて、300%で出力した。

画像ダウンロード後の手順としては、
リネームして、”Images.xcassets”に追加して、
追加した画像を1xから3xに移動して、
上記のコードで背景に設定すると枠が描画される。

あらかじめ設定済みのtintColorで枠を描画するために、

imageWithRenderingMode( .AlwaysTemplate )

を呼んでいるが、
その必要がなければ、これを呼ぶ必要はない。

角丸が必要ない場合は、角丸のない背景画像を追加するとか、
そんな感じで対応して頂ければと思う。

おしまい。

(*1) バグなの?そういう仕様?

Leave a Comment