cdts/xdts-ios 3/TreeHole/CYHResetCode/CYH/QMUIKit/QMUIComponents/QMUIButton/QMUIButton.m

614 lines
38 KiB
Mathematica
Raw Normal View History

2023-07-27 09:20:00 +08:00
/**
* Tencent is pleased to support the open source community by making QMUI_iOS available.
* Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
//
// QMUIButton.m
// qmui
//
// Created by QMUI Team on 14-7-7.
//
#import "QMUIButton.h"
#import "QMUICore.h"
#import "CALayer+QMUI.h"
#import "UIButton+QMUI.h"
const CGFloat QMUIButtonCornerRadiusAdjustsBounds = -1;
@interface QMUIButton ()
@property(nonatomic, strong) CALayer *highlightedBackgroundLayer;
@property(nonatomic, strong) UIColor *originBorderColor;
@end
@implementation QMUIButton
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.tintColor = ButtonTintColor;
[self setTitleColor:self.tintColor forState:UIControlStateNormal];// adjustsTitleTintColorAutomatically NO titleColor tintColor
// iOS7buttonsizeToFitcontentInsets
self.contentEdgeInsets = UIEdgeInsetsMake(CGFLOAT_MIN, 0, CGFLOAT_MIN, 0);
// didInitialize
[self didInitialize];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[self didInitialize];
}
return self;
}
- (void)didInitialize {
// highlighteddisabled
self.adjustsImageWhenHighlighted = NO;
self.adjustsImageWhenDisabled = NO;
self.adjustsButtonWhenHighlighted = YES;
self.adjustsButtonWhenDisabled = YES;
// UIButton
self.imagePosition = QMUIButtonImagePositionLeft;
}
// 访 self.imageView layout _imageView 访 imageView QMUIButton layoutSubviews
// https://github.com/Tencent/QMUI_iOS/issues/1051
- (UIImageView *)_qmui_imageView {
BeginIgnorePerformSelectorLeaksWarning
return [self performSelector:NSSelectorFromString(@"_imageView")];
EndIgnorePerformSelectorLeaksWarning
}
- (CGSize)sizeThatFits:(CGSize)size {
// sizeToFit size size
// UIButton sizeThatFits:CGSizeZero
if (CGSizeEqualToSize(self.bounds.size, size) || CGSizeIsEmpty(size)) {
size = CGSizeMax;
}
BOOL isImageViewShowing = !!self.currentImage;
BOOL isTitleLabelShowing = !!self.currentTitle || self.currentAttributedTitle;
CGSize imageTotalSize = CGSizeZero;// imageEdgeInsets
CGSize titleTotalSize = CGSizeZero;// titleEdgeInsets
CGFloat spacingBetweenImageAndTitle = flat(isImageViewShowing && isTitleLabelShowing ? self.spacingBetweenImageAndTitle : 0);// spacing
UIEdgeInsets contentEdgeInsets = UIEdgeInsetsRemoveFloatMin(self.contentEdgeInsets);
CGSize resultSize = CGSizeZero;
CGSize contentLimitSize = CGSizeMake(size.width - UIEdgeInsetsGetHorizontalValue(contentEdgeInsets), size.height - UIEdgeInsetsGetVerticalValue(contentEdgeInsets));
switch (self.imagePosition) {
case QMUIButtonImagePositionTop:
case QMUIButtonImagePositionBottom: {
//
if (isImageViewShowing) {
CGFloat imageLimitWidth = contentLimitSize.width - UIEdgeInsetsGetHorizontalValue(self.imageEdgeInsets);
CGSize imageSize = self.imageView.image ? [self.imageView sizeThatFits:CGSizeMake(imageLimitWidth, CGFLOAT_MAX)] : self.currentImage.size;
imageSize.width = MIN(imageSize.width, imageLimitWidth);// QMUIButton sizeThatFits self._imageView nil self.imageView Bold Text self.imageView sizeThatFits BoldText 1pt imageView... Bold Text self.imageView self._imageView
imageTotalSize = CGSizeMake(imageSize.width + UIEdgeInsetsGetHorizontalValue(self.imageEdgeInsets), imageSize.height + UIEdgeInsetsGetVerticalValue(self.imageEdgeInsets));
}
if (isTitleLabelShowing) {
CGSize titleLimitSize = CGSizeMake(contentLimitSize.width - UIEdgeInsetsGetHorizontalValue(self.titleEdgeInsets), contentLimitSize.height - imageTotalSize.height - spacingBetweenImageAndTitle - UIEdgeInsetsGetVerticalValue(self.titleEdgeInsets));
CGSize titleSize = [self.titleLabel sizeThatFits:titleLimitSize];
titleSize.height = MIN(titleSize.height, titleLimitSize.height);
titleTotalSize = CGSizeMake(titleSize.width + UIEdgeInsetsGetHorizontalValue(self.titleEdgeInsets), titleSize.height + UIEdgeInsetsGetVerticalValue(self.titleEdgeInsets));
}
resultSize.width = UIEdgeInsetsGetHorizontalValue(contentEdgeInsets);
resultSize.width += MAX(imageTotalSize.width, titleTotalSize.width);
resultSize.height = UIEdgeInsetsGetVerticalValue(contentEdgeInsets) + imageTotalSize.height + spacingBetweenImageAndTitle + titleTotalSize.height;
}
break;
case QMUIButtonImagePositionLeft:
case QMUIButtonImagePositionRight: {
//
// titleLabel sizeThatFits: QMUIButtonImagePositionLeft titleLabel QMUIButton
if (isImageViewShowing) {
CGFloat imageLimitHeight = contentLimitSize.height - UIEdgeInsetsGetVerticalValue(self.imageEdgeInsets);
CGSize imageSize = self.imageView.image ? [self.imageView sizeThatFits:CGSizeMake(CGFLOAT_MAX, imageLimitHeight)] : self.currentImage.size;
imageSize.height = MIN(imageSize.height, imageLimitHeight);// QMUIButton sizeThatFits self._imageView nil self.imageView Bold Text self.imageView sizeThatFits BoldText 1pt imageView... Bold Text self.imageView self._imageView
imageTotalSize = CGSizeMake(imageSize.width + UIEdgeInsetsGetHorizontalValue(self.imageEdgeInsets), imageSize.height + UIEdgeInsetsGetVerticalValue(self.imageEdgeInsets));
}
if (isTitleLabelShowing) {
CGSize titleLimitSize = CGSizeMake(contentLimitSize.width - UIEdgeInsetsGetHorizontalValue(self.titleEdgeInsets) - imageTotalSize.width - spacingBetweenImageAndTitle, contentLimitSize.height - UIEdgeInsetsGetVerticalValue(self.titleEdgeInsets));
CGSize titleSize = [self.titleLabel sizeThatFits:titleLimitSize];
titleSize.height = MIN(titleSize.height, titleLimitSize.height);
titleTotalSize = CGSizeMake(titleSize.width + UIEdgeInsetsGetHorizontalValue(self.titleEdgeInsets), titleSize.height + UIEdgeInsetsGetVerticalValue(self.titleEdgeInsets));
}
resultSize.width = UIEdgeInsetsGetHorizontalValue(contentEdgeInsets) + imageTotalSize.width + spacingBetweenImageAndTitle + titleTotalSize.width;
resultSize.height = UIEdgeInsetsGetVerticalValue(contentEdgeInsets);
resultSize.height += MAX(imageTotalSize.height, titleTotalSize.height);
}
break;
}
return resultSize;
}
- (CGSize)intrinsicContentSize {
return [self sizeThatFits:CGSizeMax];
}
- (void)layoutSubviews {
[super layoutSubviews];
if (CGRectIsEmpty(self.bounds)) {
return;
}
if (self.cornerRadius == QMUIButtonCornerRadiusAdjustsBounds) {
self.layer.cornerRadius = CGRectGetHeight(self.bounds) / 2;
}
BOOL isImageViewShowing = !!self.currentImage;
BOOL isTitleLabelShowing = !!self.currentTitle || !!self.currentAttributedTitle;
CGSize imageLimitSize = CGSizeZero;
CGSize titleLimitSize = CGSizeZero;
CGSize imageTotalSize = CGSizeZero;// imageEdgeInsets
CGSize titleTotalSize = CGSizeZero;// titleEdgeInsets
CGFloat spacingBetweenImageAndTitle = flat(isImageViewShowing && isTitleLabelShowing ? self.spacingBetweenImageAndTitle : 0);// spacing
CGRect imageFrame = CGRectZero;
CGRect titleFrame = CGRectZero;
UIEdgeInsets contentEdgeInsets = UIEdgeInsetsRemoveFloatMin(self.contentEdgeInsets);
CGSize contentSize = CGSizeMake(CGRectGetWidth(self.bounds) - UIEdgeInsetsGetHorizontalValue(contentEdgeInsets), CGRectGetHeight(self.bounds) - UIEdgeInsetsGetVerticalValue(contentEdgeInsets));
// imagePosition
if (isImageViewShowing) {
imageLimitSize = CGSizeMake(contentSize.width - UIEdgeInsetsGetHorizontalValue(self.imageEdgeInsets), contentSize.height - UIEdgeInsetsGetVerticalValue(self.imageEdgeInsets));
CGSize imageSize = self._qmui_imageView.image ? [self._qmui_imageView sizeThatFits:imageLimitSize] : self.currentImage.size;
imageSize.width = MIN(imageLimitSize.width, imageSize.width);
imageSize.height = MIN(imageLimitSize.height, imageSize.height);
imageFrame = CGRectMakeWithSize(imageSize);
imageTotalSize = CGSizeMake(imageSize.width + UIEdgeInsetsGetHorizontalValue(self.imageEdgeInsets), imageSize.height + UIEdgeInsetsGetVerticalValue(self.imageEdgeInsets));
}
// UIButton (0,0) imageEdgeInsets imageView bounds imageView subviews
// https://github.com/Tencent/QMUI_iOS/issues/1012
void (^makesureBoundsPositive)(UIView *) = ^void(UIView *view) {
CGRect bounds = view.bounds;
if (CGRectGetMinX(bounds) < 0 || CGRectGetMinY(bounds) < 0) {
bounds = CGRectMakeWithSize(bounds.size);
view.bounds = bounds;
}
};
if (isImageViewShowing) {
makesureBoundsPositive(self._qmui_imageView);
}
if (isTitleLabelShowing) {
makesureBoundsPositive(self.titleLabel);
}
if (self.imagePosition == QMUIButtonImagePositionTop || self.imagePosition == QMUIButtonImagePositionBottom) {
if (isTitleLabelShowing) {
titleLimitSize = CGSizeMake(contentSize.width - UIEdgeInsetsGetHorizontalValue(self.titleEdgeInsets), contentSize.height - imageTotalSize.height - spacingBetweenImageAndTitle - UIEdgeInsetsGetVerticalValue(self.titleEdgeInsets));
CGSize titleSize = [self.titleLabel sizeThatFits:titleLimitSize];
titleSize.width = MIN(titleLimitSize.width, titleSize.width);
titleSize.height = MIN(titleLimitSize.height, titleSize.height);
titleFrame = CGRectMakeWithSize(titleSize);
titleTotalSize = CGSizeMake(titleSize.width + UIEdgeInsetsGetHorizontalValue(self.titleEdgeInsets), titleSize.height + UIEdgeInsetsGetVerticalValue(self.titleEdgeInsets));
}
switch (self.contentHorizontalAlignment) {
case UIControlContentHorizontalAlignmentLeft:
imageFrame = isImageViewShowing ? CGRectSetX(imageFrame, contentEdgeInsets.left + self.imageEdgeInsets.left) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetX(titleFrame, contentEdgeInsets.left + self.titleEdgeInsets.left) : titleFrame;
break;
case UIControlContentHorizontalAlignmentCenter:
imageFrame = isImageViewShowing ? CGRectSetX(imageFrame, contentEdgeInsets.left + self.imageEdgeInsets.left + CGFloatGetCenter(imageLimitSize.width, CGRectGetWidth(imageFrame))) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetX(titleFrame, contentEdgeInsets.left + self.titleEdgeInsets.left + CGFloatGetCenter(titleLimitSize.width, CGRectGetWidth(titleFrame))) : titleFrame;
break;
case UIControlContentHorizontalAlignmentRight:
imageFrame = isImageViewShowing ? CGRectSetX(imageFrame, CGRectGetWidth(self.bounds) - contentEdgeInsets.right - self.imageEdgeInsets.right - CGRectGetWidth(imageFrame)) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetX(titleFrame, CGRectGetWidth(self.bounds) - contentEdgeInsets.right - self.titleEdgeInsets.right - CGRectGetWidth(titleFrame)) : titleFrame;
break;
case UIControlContentHorizontalAlignmentFill:
if (isImageViewShowing) {
imageFrame = CGRectSetX(imageFrame, contentEdgeInsets.left + self.imageEdgeInsets.left);
imageFrame = CGRectSetWidth(imageFrame, imageLimitSize.width);
}
if (isTitleLabelShowing) {
titleFrame = CGRectSetX(titleFrame, contentEdgeInsets.left + self.titleEdgeInsets.left);
titleFrame = CGRectSetWidth(titleFrame, titleLimitSize.width);
}
break;
default:
break;
}
if (self.imagePosition == QMUIButtonImagePositionTop) {
switch (self.contentVerticalAlignment) {
case UIControlContentVerticalAlignmentTop:
imageFrame = isImageViewShowing ? CGRectSetY(imageFrame, contentEdgeInsets.top + self.imageEdgeInsets.top) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetY(titleFrame, contentEdgeInsets.top + imageTotalSize.height + spacingBetweenImageAndTitle + self.titleEdgeInsets.top) : titleFrame;
break;
case UIControlContentVerticalAlignmentCenter: {
CGFloat contentHeight = imageTotalSize.height + spacingBetweenImageAndTitle + titleTotalSize.height;
CGFloat minY = CGFloatGetCenter(contentSize.height, contentHeight) + contentEdgeInsets.top;
imageFrame = isImageViewShowing ? CGRectSetY(imageFrame, minY + self.imageEdgeInsets.top) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetY(titleFrame, minY + imageTotalSize.height + spacingBetweenImageAndTitle + self.titleEdgeInsets.top) : titleFrame;
}
break;
case UIControlContentVerticalAlignmentBottom:
titleFrame = isTitleLabelShowing ? CGRectSetY(titleFrame, CGRectGetHeight(self.bounds) - contentEdgeInsets.bottom - self.titleEdgeInsets.bottom - CGRectGetHeight(titleFrame)) : titleFrame;
imageFrame = isImageViewShowing ? CGRectSetY(imageFrame, CGRectGetHeight(self.bounds) - contentEdgeInsets.bottom - titleTotalSize.height - spacingBetweenImageAndTitle - self.imageEdgeInsets.bottom - CGRectGetHeight(imageFrame)) : imageFrame;
break;
case UIControlContentVerticalAlignmentFill: {
if (isImageViewShowing && isTitleLabelShowing) {
// label label
imageFrame = isImageViewShowing ? CGRectSetY(imageFrame, contentEdgeInsets.top + self.imageEdgeInsets.top) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetY(titleFrame, contentEdgeInsets.top + imageTotalSize.height + spacingBetweenImageAndTitle + self.titleEdgeInsets.top) : titleFrame;
titleFrame = isTitleLabelShowing ? CGRectSetHeight(titleFrame, CGRectGetHeight(self.bounds) - contentEdgeInsets.bottom - self.titleEdgeInsets.bottom - CGRectGetMinY(titleFrame)) : titleFrame;
} else if (isImageViewShowing) {
imageFrame = CGRectSetY(imageFrame, contentEdgeInsets.top + self.imageEdgeInsets.top);
imageFrame = CGRectSetHeight(imageFrame, contentSize.height - UIEdgeInsetsGetVerticalValue(self.imageEdgeInsets));
} else {
titleFrame = CGRectSetY(titleFrame, contentEdgeInsets.top + self.titleEdgeInsets.top);
titleFrame = CGRectSetHeight(titleFrame, contentSize.height - UIEdgeInsetsGetVerticalValue(self.titleEdgeInsets));
}
}
break;
}
} else {
switch (self.contentVerticalAlignment) {
case UIControlContentVerticalAlignmentTop:
titleFrame = isTitleLabelShowing ? CGRectSetY(titleFrame, contentEdgeInsets.top + self.titleEdgeInsets.top) : titleFrame;
imageFrame = isImageViewShowing ? CGRectSetY(imageFrame, contentEdgeInsets.top + titleTotalSize.height + spacingBetweenImageAndTitle + self.imageEdgeInsets.top) : imageFrame;
break;
case UIControlContentVerticalAlignmentCenter: {
CGFloat contentHeight = imageTotalSize.height + titleTotalSize.height + spacingBetweenImageAndTitle;
CGFloat minY = CGFloatGetCenter(contentSize.height, contentHeight) + contentEdgeInsets.top;
titleFrame = isTitleLabelShowing ? CGRectSetY(titleFrame, minY + self.titleEdgeInsets.top) : titleFrame;
imageFrame = isImageViewShowing ? CGRectSetY(imageFrame, minY + titleTotalSize.height + spacingBetweenImageAndTitle + self.imageEdgeInsets.top) : imageFrame;
}
break;
case UIControlContentVerticalAlignmentBottom:
imageFrame = isImageViewShowing ? CGRectSetY(imageFrame, CGRectGetHeight(self.bounds) - contentEdgeInsets.bottom - self.imageEdgeInsets.bottom - CGRectGetHeight(imageFrame)) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetY(titleFrame, CGRectGetHeight(self.bounds) - contentEdgeInsets.bottom - imageTotalSize.height - spacingBetweenImageAndTitle - self.titleEdgeInsets.bottom - CGRectGetHeight(titleFrame)) : titleFrame;
break;
case UIControlContentVerticalAlignmentFill: {
if (isImageViewShowing && isTitleLabelShowing) {
// label label
imageFrame = CGRectSetY(imageFrame, CGRectGetHeight(self.bounds) - contentEdgeInsets.bottom - self.imageEdgeInsets.bottom - CGRectGetHeight(imageFrame));
titleFrame = CGRectSetY(titleFrame, contentEdgeInsets.top + self.titleEdgeInsets.top);
titleFrame = CGRectSetHeight(titleFrame, CGRectGetHeight(self.bounds) - contentEdgeInsets.bottom - imageTotalSize.height - spacingBetweenImageAndTitle - self.titleEdgeInsets.bottom - CGRectGetMinY(titleFrame));
} else if (isImageViewShowing) {
imageFrame = CGRectSetY(imageFrame, contentEdgeInsets.top + self.imageEdgeInsets.top);
imageFrame = CGRectSetHeight(imageFrame, contentSize.height - UIEdgeInsetsGetVerticalValue(self.imageEdgeInsets));
} else {
titleFrame = CGRectSetY(titleFrame, contentEdgeInsets.top + self.titleEdgeInsets.top);
titleFrame = CGRectSetHeight(titleFrame, contentSize.height - UIEdgeInsetsGetVerticalValue(self.titleEdgeInsets));
}
}
break;
}
}
if (isImageViewShowing) {
imageFrame = CGRectFlatted(imageFrame);
self._qmui_imageView.frame = imageFrame;
}
if (isTitleLabelShowing) {
titleFrame = CGRectFlatted(titleFrame);
self.titleLabel.frame = titleFrame;
}
} else if (self.imagePosition == QMUIButtonImagePositionLeft || self.imagePosition == QMUIButtonImagePositionRight) {
if (isTitleLabelShowing) {
titleLimitSize = CGSizeMake(contentSize.width - UIEdgeInsetsGetHorizontalValue(self.titleEdgeInsets) - imageTotalSize.width - spacingBetweenImageAndTitle, contentSize.height - UIEdgeInsetsGetVerticalValue(self.titleEdgeInsets));
CGSize titleSize = [self.titleLabel sizeThatFits:titleLimitSize];
titleSize.width = MIN(titleLimitSize.width, titleSize.width);
titleSize.height = MIN(titleLimitSize.height, titleSize.height);
titleFrame = CGRectMakeWithSize(titleSize);
titleTotalSize = CGSizeMake(titleSize.width + UIEdgeInsetsGetHorizontalValue(self.titleEdgeInsets), titleSize.height + UIEdgeInsetsGetVerticalValue(self.titleEdgeInsets));
}
switch (self.contentVerticalAlignment) {
case UIControlContentVerticalAlignmentTop:
imageFrame = isImageViewShowing ? CGRectSetY(imageFrame, contentEdgeInsets.top + self.imageEdgeInsets.top) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetY(titleFrame, contentEdgeInsets.top + self.titleEdgeInsets.top) : titleFrame;
break;
case UIControlContentVerticalAlignmentCenter:
imageFrame = isImageViewShowing ? CGRectSetY(imageFrame, contentEdgeInsets.top + CGFloatGetCenter(contentSize.height, CGRectGetHeight(imageFrame)) + self.imageEdgeInsets.top) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetY(titleFrame, contentEdgeInsets.top + CGFloatGetCenter(contentSize.height, CGRectGetHeight(titleFrame)) + self.titleEdgeInsets.top) : titleFrame;
break;
case UIControlContentVerticalAlignmentBottom:
imageFrame = isImageViewShowing ? CGRectSetY(imageFrame, CGRectGetHeight(self.bounds) - contentEdgeInsets.bottom - self.imageEdgeInsets.bottom - CGRectGetHeight(imageFrame)) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetY(titleFrame, CGRectGetHeight(self.bounds) - contentEdgeInsets.bottom - self.titleEdgeInsets.bottom - CGRectGetHeight(titleFrame)) : titleFrame;
break;
case UIControlContentVerticalAlignmentFill:
if (isImageViewShowing) {
imageFrame = CGRectSetY(imageFrame, contentEdgeInsets.top + self.imageEdgeInsets.top);
imageFrame = CGRectSetHeight(imageFrame, contentSize.height - UIEdgeInsetsGetVerticalValue(self.imageEdgeInsets));
}
if (isTitleLabelShowing) {
titleFrame = CGRectSetY(titleFrame, contentEdgeInsets.top + self.titleEdgeInsets.top);
titleFrame = CGRectSetHeight(titleFrame, contentSize.height - UIEdgeInsetsGetVerticalValue(self.titleEdgeInsets));
}
break;
}
if (self.imagePosition == QMUIButtonImagePositionLeft) {
switch (self.contentHorizontalAlignment) {
case UIControlContentHorizontalAlignmentLeft:
imageFrame = isImageViewShowing ? CGRectSetX(imageFrame, contentEdgeInsets.left + self.imageEdgeInsets.left) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetX(titleFrame, contentEdgeInsets.left + imageTotalSize.width + spacingBetweenImageAndTitle + self.titleEdgeInsets.left) : titleFrame;
break;
case UIControlContentHorizontalAlignmentCenter: {
CGFloat contentWidth = imageTotalSize.width + spacingBetweenImageAndTitle + titleTotalSize.width;
CGFloat minX = contentEdgeInsets.left + CGFloatGetCenter(contentSize.width, contentWidth);
imageFrame = isImageViewShowing ? CGRectSetX(imageFrame, minX + self.imageEdgeInsets.left) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetX(titleFrame, minX + imageTotalSize.width + spacingBetweenImageAndTitle + self.titleEdgeInsets.left) : titleFrame;
}
break;
case UIControlContentHorizontalAlignmentRight: {
if (imageTotalSize.width + spacingBetweenImageAndTitle + titleTotalSize.width > contentSize.width) {
//
imageFrame = isImageViewShowing ? CGRectSetX(imageFrame, contentEdgeInsets.left + self.imageEdgeInsets.left) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetX(titleFrame, contentEdgeInsets.left + imageTotalSize.width + spacingBetweenImageAndTitle + self.titleEdgeInsets.left) : titleFrame;
} else {
//
titleFrame = isTitleLabelShowing ? CGRectSetX(titleFrame, CGRectGetWidth(self.bounds) - contentEdgeInsets.right - self.titleEdgeInsets.right - CGRectGetWidth(titleFrame)) : titleFrame;
imageFrame = isImageViewShowing ? CGRectSetX(imageFrame, CGRectGetWidth(self.bounds) - contentEdgeInsets.right - titleTotalSize.width - spacingBetweenImageAndTitle - imageTotalSize.width + self.imageEdgeInsets.left) : imageFrame;
}
}
break;
case UIControlContentHorizontalAlignmentFill: {
if (isImageViewShowing && isTitleLabelShowing) {
// label label
imageFrame = CGRectSetX(imageFrame, contentEdgeInsets.left + self.imageEdgeInsets.left);
titleFrame = CGRectSetX(titleFrame, contentEdgeInsets.left + imageTotalSize.width + spacingBetweenImageAndTitle + self.titleEdgeInsets.left);
titleFrame = CGRectSetWidth(titleFrame, CGRectGetWidth(self.bounds) - contentEdgeInsets.right - self.titleEdgeInsets.right - CGRectGetMinX(titleFrame));
} else if (isImageViewShowing) {
imageFrame = CGRectSetX(imageFrame, contentEdgeInsets.left + self.imageEdgeInsets.left);
imageFrame = CGRectSetWidth(imageFrame, contentSize.width - UIEdgeInsetsGetHorizontalValue(self.imageEdgeInsets));
} else {
titleFrame = CGRectSetX(titleFrame, contentEdgeInsets.left + self.titleEdgeInsets.left);
titleFrame = CGRectSetWidth(titleFrame, contentSize.width - UIEdgeInsetsGetHorizontalValue(self.titleEdgeInsets));
}
}
break;
default:
break;
}
} else {
switch (self.contentHorizontalAlignment) {
case UIControlContentHorizontalAlignmentLeft: {
if (imageTotalSize.width + spacingBetweenImageAndTitle + titleTotalSize.width > contentSize.width) {
//
imageFrame = isImageViewShowing ? CGRectSetX(imageFrame, CGRectGetWidth(self.bounds) - contentEdgeInsets.right - self.imageEdgeInsets.right - CGRectGetWidth(imageFrame)) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetX(titleFrame, CGRectGetWidth(self.bounds) - contentEdgeInsets.right - imageTotalSize.width - spacingBetweenImageAndTitle - titleTotalSize.width + self.titleEdgeInsets.left) : titleFrame;
} else {
//
titleFrame = isTitleLabelShowing ? CGRectSetX(titleFrame, contentEdgeInsets.left + self.titleEdgeInsets.left) : titleFrame;
imageFrame = isImageViewShowing ? CGRectSetX(imageFrame, contentEdgeInsets.left + titleTotalSize.width + spacingBetweenImageAndTitle + self.imageEdgeInsets.left) : imageFrame;
}
}
break;
case UIControlContentHorizontalAlignmentCenter: {
CGFloat contentWidth = imageTotalSize.width + spacingBetweenImageAndTitle + titleTotalSize.width;
CGFloat minX = contentEdgeInsets.left + CGFloatGetCenter(contentSize.width, contentWidth);
titleFrame = isTitleLabelShowing ? CGRectSetX(titleFrame, minX + self.titleEdgeInsets.left) : titleFrame;
imageFrame = isImageViewShowing ? CGRectSetX(imageFrame, minX + titleTotalSize.width + spacingBetweenImageAndTitle + self.imageEdgeInsets.left) : imageFrame;
}
break;
case UIControlContentHorizontalAlignmentRight:
imageFrame = isImageViewShowing ? CGRectSetX(imageFrame, CGRectGetWidth(self.bounds) - contentEdgeInsets.right - self.imageEdgeInsets.right - CGRectGetWidth(imageFrame)) : imageFrame;
titleFrame = isTitleLabelShowing ? CGRectSetX(titleFrame, CGRectGetWidth(self.bounds) - contentEdgeInsets.right - imageTotalSize.width - spacingBetweenImageAndTitle - self.titleEdgeInsets.right - CGRectGetWidth(titleFrame)) : titleFrame;
break;
case UIControlContentHorizontalAlignmentFill: {
if (isImageViewShowing && isTitleLabelShowing) {
//
imageFrame = CGRectSetX(imageFrame, CGRectGetWidth(self.bounds) - contentEdgeInsets.right - self.imageEdgeInsets.right - CGRectGetWidth(imageFrame));
titleFrame = CGRectSetX(titleFrame, contentEdgeInsets.left + self.titleEdgeInsets.left);
titleFrame = CGRectSetWidth(titleFrame, CGRectGetMinX(imageFrame) - self.imageEdgeInsets.left - spacingBetweenImageAndTitle - self.titleEdgeInsets.right - CGRectGetMinX(titleFrame));
} else if (isImageViewShowing) {
imageFrame = CGRectSetX(imageFrame, contentEdgeInsets.left + self.imageEdgeInsets.left);
imageFrame = CGRectSetWidth(imageFrame, contentSize.width - UIEdgeInsetsGetHorizontalValue(self.imageEdgeInsets));
} else {
titleFrame = CGRectSetX(titleFrame, contentEdgeInsets.left + self.titleEdgeInsets.left);
titleFrame = CGRectSetWidth(titleFrame, contentSize.width - UIEdgeInsetsGetHorizontalValue(self.titleEdgeInsets));
}
}
break;
default:
break;
}
}
if (isImageViewShowing) {
imageFrame = CGRectFlatted(imageFrame);
self._qmui_imageView.frame = imageFrame;
}
if (isTitleLabelShowing) {
titleFrame = CGRectFlatted(titleFrame);
self.titleLabel.frame = titleFrame;
}
}
}
- (void)setSpacingBetweenImageAndTitle:(CGFloat)spacingBetweenImageAndTitle {
_spacingBetweenImageAndTitle = spacingBetweenImageAndTitle;
[self setNeedsLayout];
}
- (void)setImagePosition:(QMUIButtonImagePosition)imagePosition {
_imagePosition = imagePosition;
[self setNeedsLayout];
}
- (void)setHighlightedBackgroundColor:(UIColor *)highlightedBackgroundColor {
_highlightedBackgroundColor = highlightedBackgroundColor;
if (_highlightedBackgroundColor) {
// highlightedBackgroundColoralpha
self.adjustsButtonWhenHighlighted = NO;
}
}
- (void)setHighlightedBorderColor:(UIColor *)highlightedBorderColor {
_highlightedBorderColor = highlightedBorderColor;
if (_highlightedBorderColor) {
// highlightedBorderColoralpha
self.adjustsButtonWhenHighlighted = NO;
}
}
- (void)setHighlighted:(BOOL)highlighted {
[super setHighlighted:highlighted];
if (highlighted && !self.originBorderColor) {
// setHighlighted:
self.originBorderColor = [UIColor colorWithCGColor:self.layer.borderColor];
}
//
if (self.highlightedBackgroundColor || self.highlightedBorderColor) {
[self adjustsButtonHighlighted];
}
// disableddisabled
if (!self.enabled) {
return;
}
// highlighted
if (self.adjustsButtonWhenHighlighted) {
if (highlighted) {
self.alpha = ButtonHighlightedAlpha;
} else {
self.alpha = 1;
}
}
}
- (void)setEnabled:(BOOL)enabled {
[super setEnabled:enabled];
if (!enabled && self.adjustsButtonWhenDisabled) {
self.alpha = ButtonDisabledAlpha;
} else {
self.alpha = 1;
}
}
- (void)adjustsButtonHighlighted {
if (self.highlightedBackgroundColor) {
if (!self.highlightedBackgroundLayer) {
self.highlightedBackgroundLayer = [CALayer layer];
[self.highlightedBackgroundLayer qmui_removeDefaultAnimations];
[self.layer insertSublayer:self.highlightedBackgroundLayer atIndex:0];
}
self.highlightedBackgroundLayer.frame = self.bounds;
self.highlightedBackgroundLayer.cornerRadius = self.layer.cornerRadius;
self.highlightedBackgroundLayer.maskedCorners = self.layer.maskedCorners;
self.highlightedBackgroundLayer.backgroundColor = self.highlighted ? self.highlightedBackgroundColor.CGColor : UIColorClear.CGColor;
}
if (self.highlightedBorderColor) {
self.layer.borderColor = self.highlighted ? self.highlightedBorderColor.CGColor : self.originBorderColor.CGColor;
}
}
- (void)setAdjustsTitleTintColorAutomatically:(BOOL)adjustsTitleTintColorAutomatically {
_adjustsTitleTintColorAutomatically = adjustsTitleTintColorAutomatically;
[self updateTitleColorIfNeeded];
}
- (void)updateTitleColorIfNeeded {
if (self.adjustsTitleTintColorAutomatically && self.currentTitleColor) {
[self setTitleColor:self.tintColor forState:UIControlStateNormal];
}
if (self.adjustsTitleTintColorAutomatically && self.currentAttributedTitle) {
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:self.currentAttributedTitle];
[attributedString addAttribute:NSForegroundColorAttributeName value:self.tintColor range:NSMakeRange(0, attributedString.length)];
[self setAttributedTitle:attributedString forState:UIControlStateNormal];
}
}
- (void)setAdjustsImageTintColorAutomatically:(BOOL)adjustsImageTintColorAutomatically {
BOOL valueDifference = _adjustsImageTintColorAutomatically != adjustsImageTintColorAutomatically;
_adjustsImageTintColorAutomatically = adjustsImageTintColorAutomatically;
if (valueDifference) {
[self updateImageRenderingModeIfNeeded];
}
}
- (void)updateImageRenderingModeIfNeeded {
if (self.currentImage) {
NSArray<NSNumber *> *states = @[@(UIControlStateNormal), @(UIControlStateHighlighted), @(UIControlStateSelected), @(UIControlStateSelected|UIControlStateHighlighted), @(UIControlStateDisabled)];
for (NSNumber *number in states) {
UIImage *image = [self imageForState:number.unsignedIntegerValue];
if (!image) {
continue;
}
if (number.unsignedIntegerValue != UIControlStateNormal && image == [self imageForState:UIControlStateNormal]) {
continue;
}
if (self.adjustsImageTintColorAutomatically) {
// setImage: 使 renderingMode image setImage:forState
[self setImage:image forState:[number unsignedIntegerValue]];
} else {
// template使templaterenderingModeOriginal
[self setImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:[number unsignedIntegerValue]];
}
}
}
}
- (void)setImage:(UIImage *)image forState:(UIControlState)state {
if (self.adjustsImageTintColorAutomatically) {
image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
}
[super setImage:image forState:state];
}
- (void)tintColorDidChange {
[super tintColorDidChange];
[self updateTitleColorIfNeeded];
if (self.adjustsImageTintColorAutomatically) {
[self updateImageRenderingModeIfNeeded];
}
}
- (void)setTintColorAdjustsTitleAndImage:(UIColor *)tintColorAdjustsTitleAndImage {
_tintColorAdjustsTitleAndImage = tintColorAdjustsTitleAndImage;
if (tintColorAdjustsTitleAndImage) {
self.tintColor = tintColorAdjustsTitleAndImage;
self.adjustsTitleTintColorAutomatically = YES;
self.adjustsImageTintColorAutomatically = YES;
}
}
- (void)setCornerRadius:(CGFloat)cornerRadius {
_cornerRadius = cornerRadius;
if (cornerRadius != QMUIButtonCornerRadiusAdjustsBounds) {
self.layer.cornerRadius = cornerRadius;
}
[self setNeedsLayout];
}
@end