2行のテキストの左にアイコンを配置して、画像とテキストの先頭との間に2〜3ピクセルのスペースができるようにします。コントロール自体は水平に中央揃えになっています(Interface Builderで設定)
ボタンは次のようになります。
| |
|[Image] Add To |
| Favorites |
私はこれをcontentEdgeInset、imageEdgeInsets、titleEdgeInsetsを使って無駄に設定しようとしています。負の値はEdgeを拡大し、正の値はそれを縮小して中心に近づけることを理解しています。
私は試した:
[button setTitleEdgeInsets:UIEdgeInsetsMake(0, -image.size.width, 0, 0)];
[button setImageEdgeInsets:UIEdgeInsetsMake(0, button.titleLabel.bounds.size.width, 0, 0)];
しかし、これは正しく表示されません。私は値を微調整してきましたが、左のインセット値の-5から-10までは期待通りに動かないようです。 -10はテキストを左いっぱいまでスクロールするので、私は-5が左半分からそれをスクートすると思っていましたが、そうではありませんでした。
インセットの背後にある論理は何ですか?画像の配置や関連する用語についてはあまり詳しくありません。
このSO質問を参照として使用しましたが、私の価値観に関することは正しくありません。 IButton:imageEdgeInsetsとtitleEdgeInsetsを使って画像とテキストを中央揃えにする方法?
私はimageEdgeInsets
とtitleEdgeInsets
に関する文書はもっと良いはずですが、試行錯誤をせずに正しい位置を得る方法を考え出しました。
一般的なアイデアはここにあります この質問 、しかしそれはあなたがテキストと画像の両方を中心にしたい場合でした。画像とテキストを個別に中央揃えにするのではなく、画像とテキストを1つのエンティティとして中央揃えにします。これは実際にはUIButtonがすでに行っていることなので、間隔を調整するだけです。
CGFloat spacing = 10; // the amount of spacing to appear between image and title
tabBtn.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, spacing);
tabBtn.titleEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, 0);
私もこれをUIButtonのカテゴリにしたので、使いやすくなります。
UIButton + Position.h
@interface UIButton(ImageTitleCentering)
-(void) centerButtonAndImageWithSpacing:(CGFloat)spacing;
@end
UIButton + Position.m
@implementation UIButton(ImageTitleCentering)
-(void) centerButtonAndImageWithSpacing:(CGFloat)spacing {
self.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, spacing);
self.titleEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, 0);
}
@end
だから今私がしなければならないのは次のとおりです。
[button centerButtonAndImageWithSpacing:10];
そして毎回必要なものが手に入ります。手動でEdgeインセットをいじる必要はもうありません。
編集:画像とテキストの入れ替え
コメントの@Javalへの返信
これと同じメカニズムを使って、画像とテキストを入れ替えることができます。スワップを実行するには、単に負の間隔を使用しますが、テキストと画像の幅も含めます。これはフレームが知られていて、レイアウトがすでに行われていることを必要とするでしょう。
[self.view layoutIfNeeded];
CGFloat flippedSpacing = -(desiredSpacing + button.currentImage.size.width + button.titleLabel.frame.size.width);
[button centerButtonAndImageWithSpacing:flippedSpacing];
もちろん、おそらくあなたはおそらくこれのためにNiceメソッドを作りたいと思うでしょう、潜在的に2番目のカテゴリーメソッドを追加する、これは読者への課題として残されています。
私はこのパーティーに少し遅れています、しかし私は私が追加するのに役に立つ何かがあると思います。
Kekoaの答えは素晴らしいですが、RonLuggeが述べているように、ボタンがsizeToFit
を尊重しなくなったり、もっと重要なことに、ボタンが本来のサイズになったときにコンテンツを切り取ることがあります。いいね!
まず、
imageEdgeInsets
とtitleEdgeInsets
がどのように機能すると思うかについての簡単な説明:
imageEdgeInsets
のドキュメント は、次のように言っています。
このプロパティを使用して、ボタン画像の有効な描画四角形のサイズを変更して位置を変更します。 4つのインセット(上、左、下、右)のそれぞれに異なる値を指定できます。正の値を設定すると、そのエッジが縮小または挿入され、ボタンの中央に近づくように移動します。負の値は、そのEdgeを拡大または反転します。
このドキュメントはボタンにタイトルがなく、単なるイメージであることをイメージして書かれていると思います。これはこの方法をもっと理にかなったものにし、UIEdgeInsets
が通常どのように動作するかを振る舞います。基本的に、画像のフレーム(またはtitleEdgeInsets
を含むタイトル)は、正のインセットの場合は内側に、負のインセットの場合は外側に移動します。
さて、それで何ですか?
私はそこに着いています!これがデフォルトで持っているもので、画像とタイトルを設定します(ボタンの境界はそれがどこにあるかを示すためだけに緑色です):
画像とタイトルの間に間隔を空けたくない場合は、画像とタイトルのそれぞれに2つずつ、4つの異なるインセットを設定する必要があります。それは、あなたがそれらの要素のフレームのサイズを変えるのではなく、それらの位置だけを変えたいからです。このように考え始めると、Kekoaの優れたカテゴリーに必要な変更が明らかになります。
@implementation UIButton(ImageTitleCentering)
- (void)centerButtonAndImageWithSpacing:(CGFloat)spacing {
CGFloat insetAmount = spacing / 2.0;
self.imageEdgeInsets = UIEdgeInsetsMake(0, -insetAmount, 0, insetAmount);
self.titleEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, -insetAmount);
}
@end
でも待ってください、そうすれば、あなたはこう言います:
そうそう!忘れました ドキュメント これについて私に警告しました彼らは部分的に言う:
このプロパティは、レイアウト中に画像を配置するためにのみ使用されます。ボタンは、このプロパティを使用して
intrinsicContentSize
およびsizeThatFits:
を決定しません。
しかし、は役立つプロパティであり、それはcontentEdgeInsets
です。 ドキュメント そのためには、一部、
ボタンはこのプロパティを使用して
intrinsicContentSize
とsizeThatFits:
を決定します。
いいですね。それではもう一度カテゴリを微調整しましょう。
@implementation UIButton(ImageTitleCentering)
- (void)centerButtonAndImageWithSpacing:(CGFloat)spacing {
CGFloat insetAmount = spacing / 2.0;
self.imageEdgeInsets = UIEdgeInsetsMake(0, -insetAmount, 0, insetAmount);
self.titleEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, -insetAmount);
self.contentEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, insetAmount);
}
@end
そして、あなたは何を得ますか?
私にとって勝者のように見えます。
Swiftで作業していて、まったく考えたくありませんか?これがSwiftの拡張機能の最終版です。
extension UIButton {
func centerTextAndImage(spacing: CGFloat) {
let insetAmount = spacing / 2
imageEdgeInsets = UIEdgeInsets(top: 0, left: -insetAmount, bottom: 0, right: insetAmount)
titleEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: -insetAmount)
contentEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: insetAmount)
}
}
インタフェースBuilder内。 UIButton - > Attributes Inspector - > Edge = Titleを選択し、Edgeインセットを修正します。
あなたがに似たようなものを作りたい場合にも
あなたが必要
1.ボタンの水平方向と垂直方向の配置を
必要な値をすべて見つけてUIImageEdgeInsets
を設定します。
CGSize buttonSize = button.frame.size;
NSString *buttonTitle = button.titleLabel.text;
CGSize titleSize = [buttonTitle sizeWithAttributes:@{ NSFontAttributeName : [UIFont camFontZonaProBoldWithSize:12.f] }];
UIImage *buttonImage = button.imageView.image;
CGSize buttonImageSize = buttonImage.size;
CGFloat offsetBetweenImageAndText = 10; //vertical space between image and text
[button setImageEdgeInsets:UIEdgeInsetsMake((buttonSize.height - (titleSize.height + buttonImageSize.height)) / 2 - offsetBetweenImageAndText,
(buttonSize.width - buttonImageSize.width) / 2,
0,0)];
[button setTitleEdgeInsets:UIEdgeInsetsMake((buttonSize.height - (titleSize.height + buttonImageSize.height)) / 2 + buttonImageSize.height + offsetBetweenImageAndText,
titleSize.width + [button imageEdgeInsets].left > buttonSize.width ? -buttonImage.size.width + (buttonSize.width - titleSize.width) / 2 : (buttonSize.width - titleSize.width) / 2 - buttonImage.size.width,
0,0)];
これでタイトルと画像がボタンに配置されます。
また、各再レイアウトでこれを更新してください。
迅速
import UIKit
extension UIButton {
// MARK: - UIButton+Aligment
func alignContentVerticallyByCenter(offset:CGFloat = 10) {
let buttonSize = frame.size
if let titleLabel = titleLabel,
let imageView = imageView {
if let buttonTitle = titleLabel.text,
let image = imageView.image {
let titleString:NSString = NSString(string: buttonTitle)
let titleSize = titleString.sizeWithAttributes([
NSFontAttributeName : titleLabel.font
])
let buttonImageSize = image.size
let topImageOffset = (buttonSize.height - (titleSize.height + buttonImageSize.height + offset)) / 2
let leftImageOffset = (buttonSize.width - buttonImageSize.width) / 2
imageEdgeInsets = UIEdgeInsetsMake(topImageOffset,
leftImageOffset,
0,0)
let titleTopOffset = topImageOffset + offset + buttonImageSize.height
let leftTitleOffset = (buttonSize.width - titleSize.width) / 2 - image.size.width
titleEdgeInsets = UIEdgeInsetsMake(titleTopOffset,
leftTitleOffset,
0,0)
}
}
}
}
あなたはこれを使うことによって多くのトラブルを避けることができます -
myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
myButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
これにより、すべてのコンテンツが自動的に左揃えになります(または必要な場所に)。
スイフト3:
myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignment.left;
myButton.contentVerticalAlignment = UIControlContentVerticalAlignment.center;
私はこのパーティーにも少し遅れています、しかし私は追加するのに役に立つ何かがあると思います:o)。
私はUIButton
サブクラスを作成しました。その目的はボタンの画像がどこに配置されているかを縦または横に選択できるようにすることです。
それはあなたがこの種のボタンを作ることができることを意味します:
これが私のクラスでこれらのボタンを作成する方法についての詳細です:
func makeButton (imageVerticalAlignment:LayoutableButton.VerticalAlignment, imageHorizontalAlignment:LayoutableButton.HorizontalAlignment, title:String) -> LayoutableButton {
let button = LayoutableButton ()
button.imageVerticalAlignment = imageVerticalAlignment
button.imageHorizontalAlignment = imageHorizontalAlignment
button.setTitle(title, for: .normal)
// add image, border, ...
return button
}
let button1 = makeButton(imageVerticalAlignment: .center, imageHorizontalAlignment: .left, title: "button1")
let button2 = makeButton(imageVerticalAlignment: .center, imageHorizontalAlignment: .right, title: "button2")
let button3 = makeButton(imageVerticalAlignment: .top, imageHorizontalAlignment: .center, title: "button3")
let button4 = makeButton(imageVerticalAlignment: .bottom, imageHorizontalAlignment: .center, title: "button4")
let button5 = makeButton(imageVerticalAlignment: .bottom, imageHorizontalAlignment: .center, title: "button5")
button5.contentEdgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
そのために、2つの属性imageVerticalAlignment
とimageHorizontalAlignment
を追加しました。もちろん、ボタンに画像やタイトルしかない場合は、このクラスを使用しないでください。
また、タイトルと画像の間のスペースを調整できるimageToTitleSpacing
という名前の属性も追加しました。
このクラスは、imageEdgeInsets
、titleEdgeInsets
、およびcontentEdgeInsets
を直接または新しいレイアウト属性と組み合わせて使用する場合に、互換性があるように最善を尽くします。
@ ravronが私たちを説明しているように、私はボタンの内容が正しくなるように最善を尽くします(あなたが赤い枠でわかるように)。
Interface Builderでも使えます。
ここでのコード( 要旨 ):
@IBDesignable
class LayoutableButton: UIButton {
enum VerticalAlignment : String {
case center, top, bottom, unset
}
enum HorizontalAlignment : String {
case center, left, right, unset
}
@IBInspectable
var imageToTitleSpacing: CGFloat = 8.0 {
didSet {
setNeedsLayout()
}
}
var imageVerticalAlignment: VerticalAlignment = .unset {
didSet {
setNeedsLayout()
}
}
var imageHorizontalAlignment: HorizontalAlignment = .unset {
didSet {
setNeedsLayout()
}
}
@available(*, unavailable, message: "This property is reserved for Interface Builder. Use 'imageVerticalAlignment' instead.")
@IBInspectable
var imageVerticalAlignmentName: String {
get {
return imageVerticalAlignment.rawValue
}
set {
if let value = VerticalAlignment(rawValue: newValue) {
imageVerticalAlignment = value
} else {
imageVerticalAlignment = .unset
}
}
}
@available(*, unavailable, message: "This property is reserved for Interface Builder. Use 'imageHorizontalAlignment' instead.")
@IBInspectable
var imageHorizontalAlignmentName: String {
get {
return imageHorizontalAlignment.rawValue
}
set {
if let value = HorizontalAlignment(rawValue: newValue) {
imageHorizontalAlignment = value
} else {
imageHorizontalAlignment = .unset
}
}
}
var extraContentEdgeInsets:UIEdgeInsets = UIEdgeInsets.zero
override var contentEdgeInsets: UIEdgeInsets {
get {
return super.contentEdgeInsets
}
set {
super.contentEdgeInsets = newValue
self.extraContentEdgeInsets = newValue
}
}
var extraImageEdgeInsets:UIEdgeInsets = UIEdgeInsets.zero
override var imageEdgeInsets: UIEdgeInsets {
get {
return super.imageEdgeInsets
}
set {
super.imageEdgeInsets = newValue
self.extraImageEdgeInsets = newValue
}
}
var extraTitleEdgeInsets:UIEdgeInsets = UIEdgeInsets.zero
override var titleEdgeInsets: UIEdgeInsets {
get {
return super.titleEdgeInsets
}
set {
super.titleEdgeInsets = newValue
self.extraTitleEdgeInsets = newValue
}
}
//Needed to avoid IB crash during autolayout
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.imageEdgeInsets = super.imageEdgeInsets
self.titleEdgeInsets = super.titleEdgeInsets
self.contentEdgeInsets = super.contentEdgeInsets
}
override func layoutSubviews() {
if let imageSize = self.imageView?.image?.size,
let font = self.titleLabel?.font,
let textSize = self.titleLabel?.attributedText?.size() ?? self.titleLabel?.text?.size(attributes: [NSFontAttributeName: font]) {
var _imageEdgeInsets = UIEdgeInsets.zero
var _titleEdgeInsets = UIEdgeInsets.zero
var _contentEdgeInsets = UIEdgeInsets.zero
let halfImageToTitleSpacing = imageToTitleSpacing / 2.0
switch imageVerticalAlignment {
case .bottom:
_imageEdgeInsets.top = (textSize.height + imageToTitleSpacing) / 2.0
_imageEdgeInsets.bottom = (-textSize.height - imageToTitleSpacing) / 2.0
_titleEdgeInsets.top = (-imageSize.height - imageToTitleSpacing) / 2.0
_titleEdgeInsets.bottom = (imageSize.height + imageToTitleSpacing) / 2.0
_contentEdgeInsets.top = (min (imageSize.height, textSize.height) + imageToTitleSpacing) / 2.0
_contentEdgeInsets.bottom = (min (imageSize.height, textSize.height) + imageToTitleSpacing) / 2.0
//only works with contentVerticalAlignment = .center
contentVerticalAlignment = .center
case .top:
_imageEdgeInsets.top = (-textSize.height - imageToTitleSpacing) / 2.0
_imageEdgeInsets.bottom = (textSize.height + imageToTitleSpacing) / 2.0
_titleEdgeInsets.top = (imageSize.height + imageToTitleSpacing) / 2.0
_titleEdgeInsets.bottom = (-imageSize.height - imageToTitleSpacing) / 2.0
_contentEdgeInsets.top = (min (imageSize.height, textSize.height) + imageToTitleSpacing) / 2.0
_contentEdgeInsets.bottom = (min (imageSize.height, textSize.height) + imageToTitleSpacing) / 2.0
//only works with contentVerticalAlignment = .center
contentVerticalAlignment = .center
case .center:
//only works with contentVerticalAlignment = .center
contentVerticalAlignment = .center
break
case .unset:
break
}
switch imageHorizontalAlignment {
case .left:
_imageEdgeInsets.left = -halfImageToTitleSpacing
_imageEdgeInsets.right = halfImageToTitleSpacing
_titleEdgeInsets.left = halfImageToTitleSpacing
_titleEdgeInsets.right = -halfImageToTitleSpacing
_contentEdgeInsets.left = halfImageToTitleSpacing
_contentEdgeInsets.right = halfImageToTitleSpacing
case .right:
_imageEdgeInsets.left = textSize.width + halfImageToTitleSpacing
_imageEdgeInsets.right = -textSize.width - halfImageToTitleSpacing
_titleEdgeInsets.left = -imageSize.width - halfImageToTitleSpacing
_titleEdgeInsets.right = imageSize.width + halfImageToTitleSpacing
_contentEdgeInsets.left = halfImageToTitleSpacing
_contentEdgeInsets.right = halfImageToTitleSpacing
case .center:
_imageEdgeInsets.left = textSize.width / 2.0
_imageEdgeInsets.right = -textSize.width / 2.0
_titleEdgeInsets.left = -imageSize.width / 2.0
_titleEdgeInsets.right = imageSize.width / 2.0
_contentEdgeInsets.left = -((imageSize.width + textSize.width) - max (imageSize.width, textSize.width)) / 2.0
_contentEdgeInsets.right = -((imageSize.width + textSize.width) - max (imageSize.width, textSize.width)) / 2.0
case .unset:
break
}
_contentEdgeInsets.top += extraContentEdgeInsets.top
_contentEdgeInsets.bottom += extraContentEdgeInsets.bottom
_contentEdgeInsets.left += extraContentEdgeInsets.left
_contentEdgeInsets.right += extraContentEdgeInsets.right
_imageEdgeInsets.top += extraImageEdgeInsets.top
_imageEdgeInsets.bottom += extraImageEdgeInsets.bottom
_imageEdgeInsets.left += extraImageEdgeInsets.left
_imageEdgeInsets.right += extraImageEdgeInsets.right
_titleEdgeInsets.top += extraTitleEdgeInsets.top
_titleEdgeInsets.bottom += extraTitleEdgeInsets.bottom
_titleEdgeInsets.left += extraTitleEdgeInsets.left
_titleEdgeInsets.right += extraTitleEdgeInsets.right
super.imageEdgeInsets = _imageEdgeInsets
super.titleEdgeInsets = _titleEdgeInsets
super.contentEdgeInsets = _contentEdgeInsets
} else {
super.imageEdgeInsets = extraImageEdgeInsets
super.titleEdgeInsets = extraTitleEdgeInsets
super.contentEdgeInsets = extraContentEdgeInsets
}
super.layoutSubviews()
}
}
アカウントロケールの変更に対するRiley Avronの回答に少し追加します。
extension UIButton {
func centerTextAndImage(spacing: CGFloat) {
let insetAmount = spacing / 2
let writingDirection = UIApplication.sharedApplication().userInterfaceLayoutDirection
let factor: CGFloat = writingDirection == .LeftToRight ? 1 : -1
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: -insetAmount*factor, bottom: 0, right: insetAmount*factor)
self.titleEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount*factor, bottom: 0, right: -insetAmount*factor)
self.contentEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: insetAmount)
}
}
Swift 4.x
extension UIButton {
func centerTextAndImage(spacing: CGFloat) {
let insetAmount = spacing / 2
let writingDirection = UIApplication.shared.userInterfaceLayoutDirection
let factor: CGFloat = writingDirection == .leftToRight ? 1 : -1
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: -insetAmount*factor, bottom: 0, right: insetAmount*factor)
self.titleEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount*factor, bottom: 0, right: -insetAmount*factor)
self.contentEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: insetAmount)
}
}
使用法:
button.centerTextAndImage(spacing: 10.0)
ImageEdgeInsetsの使い方の簡単な例を示します。これは、ヒット可能な領域が30 x 30のボタンの幅が10ピクセル大きくなったとき(50 x 50)になります。
var expandHittableAreaAmt : CGFloat = 10
var buttonWidth : CGFloat = 30
var button = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
button.frame = CGRectMake(0, 0, buttonWidth+expandHittableAreaAmt, buttonWidth+expandHittableAreaAmt)
button.imageEdgeInsets = UIEdgeInsetsMake(expandHittableAreaAmt, expandHittableAreaAmt, expandHittableAreaAmt, expandHittableAreaAmt)
button.setImage(UIImage(named: "buttonImage"), forState: .Normal)
button.addTarget(self, action: "didTouchButton:", forControlEvents:.TouchUpInside)
私は以下のコードを書きます。製品版ではうまくいきます。 Swift 4.2以降をサポート
extension UIButton{
enum ImageTitleRelativeLocation {
case imageUpTitleDown
case imageDownTitleUp
case imageLeftTitleRight
case imageRightTitleLeft
}
func centerContentRelativeLocation(_ relativeLocation:
ImageTitleRelativeLocation,
spacing: CGFloat = 0) {
assert(contentVerticalAlignment == .center,
"only works with contentVerticalAlignment = .center !!!")
guard (title(for: .normal) != nil) || (attributedTitle(for: .normal) != nil) else {
assert(false, "TITLE IS NIL! SET TITTLE FIRST!")
return
}
guard let imageSize = self.currentImage?.size else {
assert(false, "IMGAGE IS NIL! SET IMAGE FIRST!!!")
return
}
guard let titleSize = titleLabel?
.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) else {
assert(false, "TITLELABEL IS NIL!")
return
}
let horizontalResistent: CGFloat
// extend contenArea in case of title is shrink
if frame.width < titleSize.width + imageSize.width {
horizontalResistent = titleSize.width + imageSize.width - frame.width
print("horizontalResistent", horizontalResistent)
} else {
horizontalResistent = 0
}
var adjustImageEdgeInsets: UIEdgeInsets = .zero
var adjustTitleEdgeInsets: UIEdgeInsets = .zero
var adjustContentEdgeInsets: UIEdgeInsets = .zero
let verticalImageAbsOffset = abs((titleSize.height + spacing) / 2)
let verticalTitleAbsOffset = abs((imageSize.height + spacing) / 2)
switch relativeLocation {
case .imageUpTitleDown:
adjustImageEdgeInsets.top = -verticalImageAbsOffset
adjustImageEdgeInsets.bottom = verticalImageAbsOffset
adjustImageEdgeInsets.left = titleSize.width / 2 + horizontalResistent / 2
adjustImageEdgeInsets.right = -titleSize.width / 2 - horizontalResistent / 2
adjustTitleEdgeInsets.top = verticalTitleAbsOffset
adjustTitleEdgeInsets.bottom = -verticalTitleAbsOffset
adjustTitleEdgeInsets.left = -imageSize.width / 2 + horizontalResistent / 2
adjustTitleEdgeInsets.right = imageSize.width / 2 - horizontalResistent / 2
adjustContentEdgeInsets.top = spacing
adjustContentEdgeInsets.bottom = spacing
adjustContentEdgeInsets.left = -horizontalResistent
adjustContentEdgeInsets.right = -horizontalResistent
case .imageDownTitleUp:
adjustImageEdgeInsets.top = verticalImageAbsOffset
adjustImageEdgeInsets.bottom = -verticalImageAbsOffset
adjustImageEdgeInsets.left = titleSize.width / 2 + horizontalResistent / 2
adjustImageEdgeInsets.right = -titleSize.width / 2 - horizontalResistent / 2
adjustTitleEdgeInsets.top = -verticalTitleAbsOffset
adjustTitleEdgeInsets.bottom = verticalTitleAbsOffset
adjustTitleEdgeInsets.left = -imageSize.width / 2 + horizontalResistent / 2
adjustTitleEdgeInsets.right = imageSize.width / 2 - horizontalResistent / 2
adjustContentEdgeInsets.top = spacing
adjustContentEdgeInsets.bottom = spacing
adjustContentEdgeInsets.left = -horizontalResistent
adjustContentEdgeInsets.right = -horizontalResistent
case .imageLeftTitleRight:
adjustImageEdgeInsets.left = -spacing / 2
adjustImageEdgeInsets.right = spacing / 2
adjustTitleEdgeInsets.left = spacing / 2
adjustTitleEdgeInsets.right = -spacing / 2
adjustContentEdgeInsets.left = spacing
adjustContentEdgeInsets.right = spacing
case .imageRightTitleLeft:
adjustImageEdgeInsets.left = titleSize.width + spacing / 2
adjustImageEdgeInsets.right = -titleSize.width - spacing / 2
adjustTitleEdgeInsets.left = -imageSize.width - spacing / 2
adjustTitleEdgeInsets.right = imageSize.width + spacing / 2
adjustContentEdgeInsets.left = spacing
adjustContentEdgeInsets.right = spacing
}
imageEdgeInsets = adjustImageEdgeInsets
titleEdgeInsets = adjustTitleEdgeInsets
contentEdgeInsets = adjustContentEdgeInsets
setNeedsLayout()
}
}
Swift 3の洗練された方法で、よく理解してください。
override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
let leftMargin:CGFloat = 40
let imgWidth:CGFloat = 24
let imgHeight:CGFloat = 24
return CGRect(x: leftMargin, y: (contentRect.size.height-imgHeight) * 0.5, width: imgWidth, height: imgHeight)
}
override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
let leftMargin:CGFloat = 80
let rightMargin:CGFloat = 80
return CGRect(x: leftMargin, y: 0, width: contentRect.size.width-leftMargin-rightMargin, height: contentRect.size.height)
}
override func backgroundRect(forBounds bounds: CGRect) -> CGRect {
let leftMargin:CGFloat = 10
let rightMargin:CGFloat = 10
let topMargin:CGFloat = 10
let bottomMargin:CGFloat = 10
return CGRect(x: leftMargin, y: topMargin, width: bounds.size.width-leftMargin-rightMargin, height: bounds.size.height-topMargin-bottomMargin)
}
override func contentRect(forBounds bounds: CGRect) -> CGRect {
let leftMargin:CGFloat = 5
let rightMargin:CGFloat = 5
let topMargin:CGFloat = 5
let bottomMargin:CGFloat = 5
return CGRect(x: leftMargin, y: topMargin, width: bounds.size.width-leftMargin-rightMargin, height: bounds.size.height-topMargin-bottomMargin)
}
Swift 4.2バージョンのソリューションは次のようになります。
let spacing: CGFloat = 10 // the amount of spacing to appear between image and title
self.button?.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: spacing)
self.button?.titleEdgeInsets = UIEdgeInsets(top: 0, left: spacing, bottom: 0, right: 0)