Aligning text and image on UIButton with imageEdgeInsets and titleEdgeInsets
我想在两行文本的左侧放置一个图标,以使图像和文本开头之间大约有2-3个像素的空间。控件本身水平居中对齐(通过Interface Builder设置)
该按钮类似于以下内容:
1 2 3 | | | |[Image] Add To | | Favorites | |
我正在尝试将contentEdgeInset,imageEdgeInsets和titleEdgeInsets配置为无效。我知道负值会扩大边缘,而正值会缩小边缘以使其更靠近中心。
我试过了:
1 2 | [button setTitleEdgeInsets:UIEdgeInsetsMake(0, -image.size.width, 0, 0)]; [button setImageEdgeInsets:UIEdgeInsetsMake(0, button.titleLabel.bounds.size.width, 0, 0)]; |
但这无法正确显示。我一直在调整值,但是从左插入值的-5到-10似乎没有以预期的方式移动它。 -10将从头开始一直跟踪文本,所以我期望-5从左侧到中间跟踪它,但事实并非如此。
插图背后的逻辑是什么?我对图片位置和相关术语不熟悉。
我用这个问题作为参考,但是关于我的价值观的某些说法是不对的。
UIButton:如何使用imageEdgeInsets和titleEdgeInsets将图像和文本居中?
我参加这个聚会有点晚了,但是我想补充一下。
Kekoa的答案很好,但是,正如RonLugge提到的那样,它可以使按钮不再尊重
首先,
我相信
Use this property to resize and reposition the effective drawing rectangle for the button image. You can specify a different value for each of the four insets (top, left, bottom, right). A positive value shrinks, or insets, that edge—moving it closer to the center of the button. A negative value expands, or outsets, that edge.
我相信编写此文档时会想到按钮没有标题,只有图像。想到这种方式更有意义,并且表现出
好那怎么了
我快到那里了!默认情况下,这是您要设置的图像和标题(按钮边框为绿色只是为了显示其位置):
如果要在图像和标题之间留出间隔,而又不致使两者粉碎,则需要设置四个不同的插图,在图像和标题上分别设置两个。那是因为您不想更改这些元素框架的大小,而只是更改其位置。当您开始以这种方式思考时,对Kekoa优秀类别的必要更改就很清楚了:
1 2 3 4 5 6 7 8 9 | @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 |
但是等等,您说,当我这样做时,我得到了:
哦耶!我忘记了,文档对此警告了我。他们说:
This property is used only for positioning the image during layout. The button does not use this property to determine
intrinsicContentSize andsizeThatFits: .
但是有一个属性可以提供帮助,即
The button uses this property to determine
intrinsicContentSize andsizeThatFits: .
听起来不错。因此,让我们再次调整类别:
1 2 3 4 5 6 7 8 9 10 | @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中扩展的最终版本:
1 2 3 4 5 6 7 8 | 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) } } |
我同意
这个问题的总体思路就在这里,但这就是您是否希望文本和图像都居中。我们不希望图像和文本分别居中,我们希望图像和文本作为单个实体一起居中。实际上,这正是UIButton所做的,因此我们只需要调整间距即可。
1 2 3 | 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
1 2 3 4 5 | @interface UIButton(ImageTitleCentering) -(void) centerButtonAndImageWithSpacing:(CGFloat)spacing; @end |
UIButton + Position.m
1 2 3 4 5 6 7 8 | @implementation UIButton(ImageTitleCentering) -(void) centerButtonAndImageWithSpacing:(CGFloat)spacing { self.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, spacing); self.titleEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, 0); } @end |
所以现在我要做的就是:
1 | [button centerButtonAndImageWithSpacing:10]; |
而且我每次都能得到所需的东西。不再需要手动弄乱边缘插图。
编辑:交换图像和文本
回应@Javal的评论
使用相同的机制,我们可以交换图像和文本。要完成交换,只需使用负间距,但还要包括文本和图像的宽度。这将需要知道框架并已经执行布局。
1 2 3 | [self.view layoutIfNeeded]; CGFloat flippedSpacing = -(desiredSpacing + button.currentImage.size.width + button.titleLabel.frame.size.width); [button centerButtonAndImageWithSpacing:flippedSpacing]; |
当然,您可能会想为此做一个不错的方法,可能会添加第二类方法,这留给读者练习。
在界面生成器中。选择UIButton-> Attributes Inspector-> Edge = Title并修改边缘插图
另外,如果您想做类似的事情
你需要
1.将按钮的水平和垂直对齐设置为
查找所有必需的值并设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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)]; |
这将在按钮上排列您的标题和图像。
另外请注意在每次重排时更新
迅速
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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) } } } } |
使用此方法可以避免很多麻烦-
1 2 | myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; myButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; |
这将自动将您所有的内容向左(或您希望的位置)对齐
斯威夫特3:
1 2 | myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignment.left; myButton.contentVerticalAlignment = UIControlContentVerticalAlignment.center; |
在Xcode 8.0中,只需更改大小检查器中的
选择UIButton-> Attributes Inspector->转到size inspector并修改内容,图像和标题插图。
而且,如果您想在右侧更改图像,只需在Attribute inspector中将语义属性更改为
我也参加这个聚会有点晚,但是我想补充一下:o)。
我创建了一个
这意味着您可以进行以下按钮:
这里是有关如何在我的课堂上创建这些按钮的详细信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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个属性:
我还添加了一个名为
如果您想直接使用
正如@ravron向我们解释的那样,我会尽力使按钮内容的边缘正确(如红色边框所示)。
您也可以在Interface Builder中使用它:
这里的代码(要点):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | @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)对帐户语言环境更改的答案有一个小的补充:
1 2 3 4 5 6 7 8 9 10 11 | 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) } } |
斯威夫特4.x
1 2 3 4 5 6 7 8 9 10 11 | 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) } } |
用法:
1 | button.centerTextAndImage(spacing: 10.0) |
我写下面的代码。在产品版本中效果很好。 Supprot Swift 4.2 +
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | 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() } } |
这是有关如何使用imageEdgeInsets的简单示例
这将使一个30x30的按钮具有一个可击中区域,并且在整个过程中都会放大10像素(50x50)
1 2 3 4 5 6 7 | 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 3中的一种优雅方法,您可以更好地理解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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) } |
该解决方案的快速4.2版本如下所示:
1 2 3 | 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) |