XCode6大小类中的自定义字体大小调整与自定义字体无法正常工作

mne*_*mia 103 interface-builder ios xcode6 ios8 size-classes

Xcode 6有一个新功能,可以在故事板中根据当前设备配置的大小类自动设置UILabel,UITextField和UIButton中的字体和字体大小.例如,您可以将UILabel设置为在"任何宽度,紧凑高度"(例如在横向上的iPhone上)配置上使用字体大小12,在"常规宽度,常规高度"配置(例如在iPad上)上使用大小18.更多信息请点击这里:

https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/Size-ClassSpecificLayout.html

这在理论上是一个非常好的功能,因为它可以使得不必根据设备配置以编程方式在UI功能上设置不同的字体.现在,我有一些条件代码根据设备类型设置字体,但显然这意味着我必须在整个应用程序的各个地方以编程方式设置字体.所以我最初对此功能感到非常兴奋,但我发现它在实际使用中存在严重问题(可能是一个bug).请注意,我正在构建针对SDK 8并设置iOS 8的最低部署目标,因此这与与旧版iOS的兼容性无关.

问题是:如果我为不同的大小类设置不同的字体大小,并使用iOS提供的"系统"字体,一切都按预期工作,字体大小根据大小类更改.如果我使用我的应用程序提供的自定义字体(是的,我在应用程序包中正确设置,因为它以编程方式工作)并将自定义字体设置为XCode 6故事板中的标签,这也可以按预期工作.但是当我尝试为不同大小的类使用不同大小的自定义字体时,在故事板中,它突然不起作用.配置的唯一区别是我选择的字体(自定义字体与系统字体).相反,所有字体都显示在设备和模拟器上作为默认大小的默认系统字体,无论大小等级(我通过调试器验证它是用系统字体替换故事板中指定的实际字体) .所以基本上,自定义字体的大小类功能似乎已被破坏.另外,有趣的是,自定义字体实际上在视图控制器的XCode 6"预览"窗格中正确显示和调整大小:只有在实际的iOS系统上运行它才停止工作(这让我觉得我正在配置它正确).

我尝试了多种不同的自定义字体,它似乎不适用于任何一种,但如果我使用"系统",它总是有效.

无论如何,还有其他人在Xcode 6中看到过这个问题吗?关于这是否是iOS 8,Xcode中的错误或者我做错了什么的任何想法?我发现,我发现的唯一解决方法是继续以编程方式设置字体,就像我已经为大约3个版本的iOS一样,因为这确实有效.但我希望能够使用此功能,如果我可以使用自定义字体.我们的设计不接受使用System字体.


附加信息:从Xcode 8.0开始,修复了错误.

raz*_*r28 40

快速修复:

1)将字体设置为System的大小类

标签属性检查器

2)子类UILabel并覆盖"layoutSubviews"方法,如:

- (void)layoutSubviews
{
  [super layoutSubviews];

   // Implement font logic depending on screen size
    if ([self.font.fontName rangeOfString:@"bold" options:NSCaseInsensitiveSearch].location == NSNotFound) {
        NSLog(@"font is not bold");
        self.font = [UIFont fontWithName:@"Custom regular Font" size:self.font.pointSize];
    } else {
        NSLog(@"font is bold");
        self.font = [UIFont fontWithName:@"Custom bold Font" size:self.font.pointSize];
    }

}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,它是标志性字体的一种非常方便的技术


Rob*_*hen 17

在尝试了一切之后,我最终确定了上述解决方案的组合.使用Xcode 7.2,Swift 2.

import UIKit

class LabelDeviceClass : UILabel {

    @IBInspectable var iPhoneSize:CGFloat = 0 {
        didSet {
            if isPhone() {
                overrideFontSize(iPhoneSize)
            }
        }
    }

    @IBInspectable var iPadSize:CGFloat = 0 {
        didSet {
            if isPad() {
                overrideFontSize(iPadSize)
            }
        }
    }

    func isPhone() -> Bool {
        // return UIDevice.currentDevice().userInterfaceIdiom == .Phone
        return !isPad()
    }

    func isPad() -> Bool {
        // return UIDevice.currentDevice().userInterfaceIdiom == .Pad
        switch (UIScreen.mainScreen().traitCollection.horizontalSizeClass, UIScreen.mainScreen().traitCollection.verticalSizeClass) {
        case (.Regular, .Regular):
            return true
        default:
            return false
        }
    }

    func overrideFontSize(fontSize:CGFloat){
        let currentFontName = self.font.fontName
        if let calculatedFont = UIFont(name: currentFontName, size: fontSize) {
            self.font = calculatedFont
        }
    }

}
Run Code Online (Sandbox Code Playgroud)
  • @IBInspectable 允许您在Storyboard中设置字体大小
  • 它使用一个didSet观察者来避免陷阱 layoutSubviews()(动态表视图行高的无限循环)和awakeFromNib()(参见@ cocoaNoob的评论)
  • 它使用大小类而不是设备习惯用法,希望最终能够使用它 @IBDesignable
  • 可悲的是,根据其他堆栈文章@IBDesignable不起作用traitCollection
  • 特征集合切换语句是在此堆栈文章UIScreen.mainScreen()而不是self每个堆栈文章上执行的


Phi*_*hil 9

解决方法UILabel:保持相同的字体大小在所有尺码类,而是相应地更改标签的高度在每个尺寸等级.您的标签必须启用自动收缩功能.在我的情况下它很好用.


joa*_*kim 8

这个(和其他Xcode - Size Classes相关)的bug最近引起了我一些严重的悲痛,因为我不得不通过一个巨大的故事板文件来破坏东西.

对于处于这个位置的其他人,我想在@ razor28的答案之上添加一些内容来缓解痛苦.

在自定义子类的头文件中,IBInspectable用于运行时属性.这将使"属性检查器"可以访问这些属性,可视化地位于字体设置的默认位置上方.

使用示例:

@interface MyCustomLabel : UILabel

    @property (nonatomic) IBInspectable NSString *fontType;
    @property (nonatomic) IBInspectable CGFloat iphoneFontSize;
    @property (nonatomic) IBInspectable CGFloat ipadFontSize;

@end
Run Code Online (Sandbox Code Playgroud)

这将非常有助于产生此输出:

在此输入图像描述

另一个好处是,现在我们不必为每个标签手动添加运行时属性.这是我最接近XCode的预期行为.希望今年夏天适用于iOS 9的正确解决方案.


小智 -8

  • 将应用程序提供的字体添加到您的应用程序 .plist 中
  • 将您的 .ttf 文件添加到项目 0
  • 使用它 [UIFont fontWithName:"example.ttf" size:10]