@@ -19,7 +19,14 @@ @interface QMUIButton ()
1919
2020@property (nonatomic , strong ) CALayer *highlightedBackgroundLayer;
2121@property (nonatomic , strong ) UIColor *originBorderColor;
22+
23+ // 记录上一次的 spacing 和 lastImagePosition,用于恢复状态
24+ @property (nonatomic , assign ) CGFloat lastSpacingBetweenImageAndTitle;
25+ @property (nonatomic , assign ) QMUIButtonImagePosition lastImagePosition;
26+ @property (nonatomic , assign ) BOOL hasInitialSpacingBetweenImageAndTitle;
27+
2228- (void )didInitialized ;// UISubclassingHooks
29+
2330@end
2431
2532@implementation QMUIButton
@@ -58,6 +65,7 @@ - (void)didInitialized {
5865
5966 // 图片默认在按钮左边,与系统UIButton保持一致
6067 self.imagePosition = QMUIButtonImagePositionLeft;
68+ self.lastImagePosition = QMUIButtonImagePositionLeft;
6169}
6270
6371- (CGSize)sizeThatFits : (CGSize)size {
@@ -274,9 +282,130 @@ - (void)layoutSubviews {
274282 }
275283}
276284
285+ - (UIEdgeInsets)adjustTitleInsetsWithSpacingValue : (CGFloat)spacingValue imagePositionValue : (QMUIButtonImagePosition)imagePositionValue insetsValue : (UIEdgeInsets)insetsValue {
286+
287+ switch (imagePositionValue) {
288+ case QMUIButtonImagePositionTop:
289+ return UIEdgeInsetsMake (insetsValue.top + spacingValue, insetsValue.left , insetsValue.bottom - spacingValue, insetsValue.right );
290+ break ;
291+
292+ case QMUIButtonImagePositionBottom:
293+ return UIEdgeInsetsMake (insetsValue.top - spacingValue, insetsValue.left , insetsValue.bottom + spacingValue, insetsValue.right );
294+ break ;
295+
296+ case QMUIButtonImagePositionLeft:
297+ return UIEdgeInsetsMake (insetsValue.top , insetsValue.left + spacingValue, insetsValue.bottom , insetsValue.right - spacingValue);
298+ break ;
299+
300+ case QMUIButtonImagePositionRight:
301+ return UIEdgeInsetsMake (insetsValue.top , insetsValue.left - spacingValue, insetsValue.bottom , insetsValue.right + spacingValue);
302+ break ;
303+ }
304+ }
305+
306+ - (UIEdgeInsets)adjustImageInsetsWithSpacingValue : (CGFloat)spacingValue imagePositionValue : (QMUIButtonImagePosition)imagePositionValue insetsValue : (UIEdgeInsets)insetsValue {
307+
308+ switch (imagePositionValue) {
309+ case QMUIButtonImagePositionTop:
310+ return UIEdgeInsetsMake (insetsValue.top - spacingValue, insetsValue.left , insetsValue.bottom + spacingValue, insetsValue.right );
311+ break ;
312+
313+ case QMUIButtonImagePositionBottom:
314+ return UIEdgeInsetsMake (insetsValue.top + spacingValue, insetsValue.left , insetsValue.bottom - spacingValue, insetsValue.right );
315+ break ;
316+
317+ case QMUIButtonImagePositionLeft:
318+ return UIEdgeInsetsMake (insetsValue.top , insetsValue.left - spacingValue, insetsValue.bottom , insetsValue.right + spacingValue);
319+ break ;
320+
321+ case QMUIButtonImagePositionRight:
322+ return UIEdgeInsetsMake (insetsValue.top , insetsValue.left + spacingValue, insetsValue.bottom , insetsValue.right - spacingValue);
323+ break ;
324+ }
325+ }
326+
327+ - (UIEdgeInsets)adjustContentInsetsWithSpacingValue : (CGFloat)spacingValue imagePositionValue : (QMUIButtonImagePosition)imagePositionValue insetsValue : (UIEdgeInsets)insetsValue {
328+
329+ switch (imagePositionValue) {
330+ case QMUIButtonImagePositionTop:
331+ case QMUIButtonImagePositionBottom:
332+ return UIEdgeInsetsMake (insetsValue.top + spacingValue, insetsValue.left , insetsValue.bottom + spacingValue, insetsValue.right );
333+ break ;
334+
335+ case QMUIButtonImagePositionLeft:
336+ case QMUIButtonImagePositionRight:
337+ return UIEdgeInsetsMake (insetsValue.top , insetsValue.left + spacingValue, insetsValue.bottom , insetsValue.right + spacingValue);
338+ break ;
339+ }
340+ }
341+
342+ - (void )adjustInsetsWithSpacingValue : (CGFloat)spacingValue imagePositionValue : (QMUIButtonImagePosition)imagePositionValue {
343+ UIEdgeInsets titleEdgeInsets = [self adjustTitleInsetsWithSpacingValue: spacingValue imagePositionValue: imagePositionValue insetsValue: self .titleEdgeInsets];
344+ UIEdgeInsets imageEdgeInsets = [self adjustImageInsetsWithSpacingValue: spacingValue imagePositionValue: imagePositionValue insetsValue: self .imageEdgeInsets];
345+ UIEdgeInsets contentEdgeInsets = [self adjustContentInsetsWithSpacingValue: spacingValue imagePositionValue: imagePositionValue insetsValue: self .contentEdgeInsets];
346+
347+ [super setTitleEdgeInsets: titleEdgeInsets];
348+ [super setImageEdgeInsets: imageEdgeInsets];
349+ [super setContentEdgeInsets: contentEdgeInsets];
350+ }
351+
352+ // 恢复到上一次的 insets 设置
353+ - (void )restoreInsets {
354+ CGFloat spacingValue = -self.lastSpacingBetweenImageAndTitle / 2 ;
355+
356+ [self adjustInsetsWithSpacingValue: spacingValue imagePositionValue: self .lastImagePosition];
357+ }
358+
359+ // 重新保存当前 insets
360+ - (void )saveInsets {
361+ CGFloat spacingValue = self.spacingBetweenImageAndTitle / 2 ;
362+
363+ [self adjustInsetsWithSpacingValue: spacingValue imagePositionValue: self .imagePosition];
364+ }
365+
366+ // 检查 insets 的设置,每次都恢复上一次没设置前的状态重新设置,避免多次赋值的问题。
367+ - (void )checkInsetsChange {
368+
369+ // 设置过则需要回滚到未设置的状态
370+ if (self.hasInitialSpacingBetweenImageAndTitle ) {
371+ [self restoreInsets ];
372+ }
373+
374+ [self saveInsets ];
375+
376+ self.lastImagePosition = self.imagePosition ;
377+
378+ [self setNeedsLayout ];
379+ }
380+
381+ - (void )setSpacingBetweenImageAndTitle : (CGFloat)spacingBetweenImageAndTitle {
382+ _spacingBetweenImageAndTitle = spacingBetweenImageAndTitle;
383+
384+ [self checkInsetsChange ];
385+
386+ self.hasInitialSpacingBetweenImageAndTitle = YES ;
387+ self.lastSpacingBetweenImageAndTitle = self.spacingBetweenImageAndTitle ;
388+ }
389+
277390- (void )setImagePosition : (QMUIButtonImagePosition)imagePosition {
278391 _imagePosition = imagePosition;
279- [self setNeedsLayout ];
392+
393+ [self checkInsetsChange ];
394+ }
395+
396+ - (void )setTitleEdgeInsets : (UIEdgeInsets)titleEdgeInsets {
397+ UIEdgeInsets adjustedEdgeInsets = [self adjustTitleInsetsWithSpacingValue: self .spacingBetweenImageAndTitle / 2 imagePositionValue: self .imagePosition insetsValue: titleEdgeInsets];
398+ [super setTitleEdgeInsets: adjustedEdgeInsets];
399+ }
400+
401+ - (void )setImageEdgeInsets : (UIEdgeInsets)imageEdgeInsets {
402+ UIEdgeInsets adjustedEdgeInsets = [self adjustImageInsetsWithSpacingValue: self .spacingBetweenImageAndTitle / 2 imagePositionValue: self .imagePosition insetsValue: imageEdgeInsets];
403+ [super setImageEdgeInsets: adjustedEdgeInsets];
404+ }
405+
406+ - (void )setContentEdgeInsets : (UIEdgeInsets)contentEdgeInsets {
407+ UIEdgeInsets adjustedEdgeInsets = [self adjustContentInsetsWithSpacingValue: self .spacingBetweenImageAndTitle / 2 imagePositionValue: self .imagePosition insetsValue: contentEdgeInsets];
408+ [super setContentEdgeInsets: adjustedEdgeInsets];
280409}
281410
282411- (void )setHighlightedBackgroundColor : (UIColor *)highlightedBackgroundColor {
@@ -572,9 +701,9 @@ + (void)renderNavigationButtonAppearanceStyle {
572701 if (!CGSizeEqualToSize (customBackIndicatorImageSize, systemBackIndicatorImageSize)) {
573702 CGFloat imageExtensionVerticalFloat = CGFloatGetCenter (systemBackIndicatorImageSize.height , customBackIndicatorImageSize.height );
574703 customBackIndicatorImage = [customBackIndicatorImage qmui_imageWithSpacingExtensionInsets: UIEdgeInsetsMake (imageExtensionVerticalFloat,
575- 0 ,
576- imageExtensionVerticalFloat,
577- systemBackIndicatorImageSize.width - customBackIndicatorImageSize.width)];
704+ 0 ,
705+ imageExtensionVerticalFloat,
706+ systemBackIndicatorImageSize.width - customBackIndicatorImageSize.width)];
578707 }
579708
580709 navBarAppearance.backIndicatorImage = customBackIndicatorImage;
0 commit comments