文本不适合特定字体的 UIButton titleLabel 高度

Text doesn't fit in UIButton titleLabel height for a specific font

我在使用特定字体时遇到了一些问题。它是为学校设计的,所以 A 和 Å 的高度不同。我认为这给我的 UIButtons 带来了麻烦。我试图解决它,但似乎无法解决问题。这是我最后尝试过的:

[self setValue:[UIFont fontWithName:@"fontname" size:220] forKeyPath:@"button1.font"];
[self setValue:[UIFont fontWithName:@"fontname" size:220] forKeyPath:@"button2.font"];
[self setValue:[UIFont fontWithName:@"fontname" size:220] forKeyPath:@"button3.font"];
[button1 setTitle:@"A" forState:UIControlStateNormal];
[button2 setTitle:@"Å" forState:UIControlStateNormal];
[button3 setTitle:@"Å" forState:UIControlStateNormal];
[button2 setBackgroundColor:[UIColor blackColor]];
[button2 setFrame:CGRectMake(button2.frame.origin.x, button2.frame.origin.y, button2.frame.size.width, button2.frame.size.height+100)];
[button2.titleLabel setFrame:CGRectMake(button2.frame.origin.x, button2.frame.origin.y, button2.frame.size.width, button2.frame.size.height)];
button2.contentVerticalAlignment = UIControlContentVerticalAlignmentBottom;

这是结果:

如您所见,Å 未正确显示。我该如何解决这个问题?

谢谢!

此致, 乔金

编辑

这种特殊的字体与它的实际绘制方式有些奇怪。特别是,它从 center/baseline.

偏移了 "up"

原创

我不得不对 UILabel 做类似的事情,下面是我为适应 UIButton 子类所做的事情:

//  PaddedButton.h
#import <UIKit/UIKit.h>
@interface PaddedButton : UIButton
@property (assign, nonatomic) UIEdgeInsets padding;
@end

//  PaddedButton.m
#import "PaddedButton.h"
@implementation PaddedButton
- (CGSize)intrinsicContentSize {
    CGSize size = [super intrinsicContentSize];
    return CGSizeMake(size.width + self.padding.left + self.padding.right, size.height + self.padding.top + self.padding.bottom);
}
@end

然后,在我的 UIViewController 子类中,我以这种方式实例化了一个按钮:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.buttonFontSize                     = 200;
    self.buttonFont                         = [UIFont systemFontOfSize:self.buttonFontSize];
    self.button                             = [[PaddedButton alloc] init];
    self.button.backgroundColor             = [[UIColor blackColor] colorWithAlphaComponent:0.4f];
    self.button.contentVerticalAlignment    = UIControlContentVerticalAlignmentBottom;
    self.button.padding                     = UIEdgeInsetsMake(10, 10, 10, 10);
    [self.button setAttributedTitle:[[NSAttributedString alloc] initWithString:@"Å" attributes:@{NSFontAttributeName: self.buttonFont}] forState:UIControlStateNormal];
    [self.button setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self.view addSubview:self.button];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[button]-|"
                                                                     options:0
                                                                     metrics:nil
                                                                        views:@{@"button": self.button}]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(40)-[button]"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:@{@"button": self.button}]];
}

新代码部分

在为此苦苦挣扎了一段时间之后,我突然想到有更简单的方法可以做到这一点。此外,当尝试使用带有集合 titleattributedTitle 的按钮时,事情变得非常不稳定,按钮绘制其标题,然后我的代码 re-drawing 在正确的位置绘制标题。

最后,我想到了这个解决方案,似乎效果很好:

按钮Class

//  PaddedButton.h
#import <UIKit/UIKit.h>
@interface PaddedButton : UIButton
@property (strong, nonatomic) NSString      *title;
@property (assign, nonatomic) UIEdgeInsets   padding;
@property (strong, nonatomic) UIFont        *font;
@end

//  PaddedButton.m
#import "PaddedButton.h"
@implementation PaddedButton
- (CGSize)intrinsicContentSize {
    NSAttributedString *title   = [[NSAttributedString alloc] initWithString:self.title attributes:@{NSFontAttributeName: self.font}];
    CGRect textRect             = [title boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin context:nil];
    CGSize textSize             = textRect.size;
    return CGSizeMake(textSize.width + self.padding.left + self.padding.right, textSize.height + self.padding.top + self.padding.bottom);
}
- (void)drawRect:(CGRect)rect {
    NSAttributedString *title   = [[NSAttributedString alloc] initWithString:self.title attributes:@{NSFontAttributeName: self.font}];
    CGRect textRect             = [title boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin context:nil];
    textRect                    = CGRectIntegral(textRect);
    CGFloat xOffset             = (rect.size.width  - textRect.size.width)  / 2.0f;
    CGFloat yOffset             = (rect.size.height - textRect.size.height) / 2.0f;
    CGRect titleRect            = CGRectMake(xOffset, yOffset, textRect.size.width, textRect.size.height);
    // Show the bounding rect where the button WANTS to put the title
    CGContextRef ctx            = UIGraphicsGetCurrentContext();
    CGContextStrokeRect(ctx, titleRect);
    // From my testing, this offset will center the "Å" (accented) character.
    // The "A" (no accent) will be offset a little bit below center, due to the lack of accent.
    // You might want to play around with exactly what particular value is best.
    titleRect                   = CGRectOffset(titleRect, 0.0f, titleRect.size.height * 36.0f / 276.0f);
    NSLog(@"titleRect: %@", NSStringFromCGRect(titleRect));
    [title drawInRect:titleRect];
}
@end

视图控制器中的按钮设置

#pragma mark -
#pragma mark - UI Setup
- (void)setupUserInterface {
    [self createConstants];
    [self createControls];
    [self setupControls];
    [self layoutControls];
    self.view.backgroundColor   = [UIColor whiteColor];
}
- (void)createConstants {
    self.buttonFontSize         = 200;
    self.buttonFont             = [UIFont fontWithName:@"Skolrak" size:self.buttonFontSize];
}
- (void)createControls {
    self.button                 = [[PaddedButton alloc] init];
}
- (void)setupControls {
    self.button.backgroundColor             = [[UIColor blackColor] colorWithAlphaComponent:0.4f];
    self.button.contentVerticalAlignment    = UIControlContentVerticalAlignmentBottom;
    self.button.font                        = self.buttonFont;
    self.button.title                       = @"Å";
    self.button.title                       = @"A";
    self.button.padding                     = UIEdgeInsetsMake(10, 10, 10, 10);
    [self.button setTranslatesAutoresizingMaskIntoConstraints:NO];
}
- (void)layoutControls {
    [self.view addSubview:self.button];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[button]-|"
                                                                     options:0
                                                                     metrics:nil
                                                                        views:@{@"button": self.button}]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(20)-[button]"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:@{@"button": self.button}]];
}

这是我的结果(绘制方框只是为了查看按钮 想要 放置标题的位置):

这个适合你吗?

阿拉伯语字体也有同样的问题。为此,我只是在 viewdidlayoutsubviews 中设置了 titlelabel 的框架。 试试这个..希望它有帮助..让我知道它是否也适合你:)

-(void)viewDidLayoutSubviews {
       [super viewDidLayoutSubviews];
       [button2.titleLabel setFrame:CGRectMake(button2.frame.origin.x, button2.frame.origin.y, button2.frame.size.width, button2.frame.size.height)];
}

我自己发布了这个问题的另一个答案。 在我遇到字体的其他问题后,我决定在字体编辑器中编辑字体,我使用了字形。 当我在对其他字符进行一些编辑后导出字体时,Å 开始在我的应用程序中工作。 因此,在代码中进行自定义优化之前,请尝试使用字体编辑器重新生成字体。

我用下面的方法解决了这个问题

假设您的 xib 或故事板中有一个 UIButton, 然后

  1. Select UIButton
  2. 转到属性检查器
  3. 查找控件类别
  4. 找到对齐方式
  5. 选择垂直的最右侧按钮 属性!

只需增加按钮高度几个点。它对我有用

如果您也有图像但不想缩放它,这对我有用

btn.contentVerticalAlignment = .fill
btn.contentMode = .center
btn.imageView?.contentMode = .scaleAspectFit

我遇到过和@YuAn Shaolin Maculelê Lai 提到的一样的方法

Swift 3.2代码为: button.contentVerticalAlignment = .fill