概要
UIButtonの画像をどうしても右寄せしたくて色々と調べたことについてのまとめです。
実装方法
画像の上にUIButtonを配置する
以下の図のように、画像の上にボタンを配置すればデザインの簡単に実装はできます。
しかし、この実装方法だとボタンを押したときに画像がハイライトされません。
ハイライトさせるには以下の処理を追加する必要があります。
- ハイライト用の画像を設定
- ボタンのアクションに合わせて画像のハイライト状態を変更
@IBOutlet private weak var searchButtonImageView: UIImageView!
@IBAction private func searchButtonTouchCancel() {
searchButtonImageView.isHighlighted = false
}
@IBAction private func searchButtonTouchDown() {
searchButtonImageView.isHighlighted = true
}
@IBAction private func searchButtonTouchUpInside() {
searchButtonImageView.isHighlighted = false
}
@IBAction private func searchButtonTouchUpOutside() {
searchButtonImageView.isHighlighted = false
}
ボタンを押したときの画像のハイライトを気にしなければとても簡単ですが、
ハイライトも考慮するとなると少し手間がかかります。
UIButtonのEdgeInsetsを調整する
UIButtonに画像を設定してUIButtonのTitle Insets
とImage Insets
を調整してデザインを実装します。
- UIButtonの
Control
のHorizontal
を左寄せにします。
- UIButtonの
Title Insets
とImage Insets
を調整します。
この実装方法なら、ボタンを押したときに画像が適切にハイライトされます。
しかし、ボタン内のテキストが可変する場合はこの実装は向いていません。
ボタン内のテキストにあわせてImage Insetsを動的に変更する必要があり調整が大変だからです。
UISemanticContentAttributeを使用
UIButtonに画像を設定してviewのSemantic
をForce Right-to-Left
にすると画像が右寄せになります。
この方法だと画像のハイライトもボタン内の文字が可変になっても大丈夫です。
しかし、UISemanticContentAttribute
の使い方としては適切では無いのでおすすめできません。
そもそもUISemanticContentAttributeはiOS 9から追加された機能で、
Appleのドキュメントによると
左から右へのレイアウトと右から左へのレイアウトの切り替え時にビューを反転する必要があるかどうかを判断するために使用する
とあるので多言語対応するための機能だと思います。
今回設定したForce Right-to-Left
は右から左のレイアウトを使用して常に表示する
ものになるので、アラビア語など表記が左から右ではない言語を対応したときに意図したデザインにならないのではないかと思います。(確証はないので、詳しい方教えてください。)
参考
UISemanticContentAttribute
Stack Overflow
CGAffineTransformを使用
以下のコードを書いてUIButtonのtransformを変更して実装する方法です。
@IBOutlet private weak var searchButton: UIButton!
private func setupSearchButton() {
searchButton.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
searchButton.titleLabel?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
searchButton.imageView?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
}
コードを書くので、少し手間ではありますが一番いい実装方法だなと思いました。
おまけ
しかし、CGAffineTransform
を使った実装方法ではInterface Builder上で反映されません。
また、画像を右寄せしたいときにいちいちコードを書くのは面倒です。
なので、@IBDesignable
を設定したUIButtonのサブクラスを作ることをおすすめします。
// RightImageButton.swift
import UIKit
@IBDesignable final class RightImageButton: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
// アプリで表示されるとき
setup()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
// InterfaceBuilderに表示するため
setup()
}
private func setup() {
transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
titleLabel?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
imageView?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
}
}
これでいちいちコードを書かずに済みますし、Interface Builder上にも表示されるのでとても便利です。
まとめ
UIButtonの画像を右寄せにする方法でした。
個人的にはCGAffineTransformを使っての実装がおすすめです。
もっと、簡単な方法やいいやり方などあれば教えてください!