Custom Font Sizing in XCode6 Size Classes not work

2019-01-07 04:26发布

Xcode 6 has a new feature where fonts and font sizes in UILabel, UITextField, and UIButton can be set automatically based on the size class of the current device configuration, right in the storyboard. For example, you can set a UILabel to use font size 12 on "any width, compact height" (such as on iPhones in landscape) configurations and size 18 on "regular width, regular height" configurations (such as on iPads). More information is available here:

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

This is a really great feature in theory because it could make it unnecessary to programmatically set different fonts on UI features based on the device configuration. Right now, I have some conditional code that sets the fonts based on the device type, but obviously that means I have to set the fonts programmatically everywhere throughout the app. So I was initially really excited about this feature, but I found that it has a serious problem in actual usage for me (perhaps a bug). Note that I am building against SDK 8 and setting a minimum deployment target of iOS 8 so this has nothing to do with compatibility with old versions of iOS.

The problem is this: If I set different font sizes for different size classes, and use the "System" font provided by iOS, everything works as expected and the font sizes change based on the size class. If I use a custom font provided by my application (yes, I have it set up correctly in my application bundle, as it works programmatically) and set the custom font to a label in an XCode 6 storyboard, that also works as expected. But when I try to use different sizes of the custom font for different size classes, in the storyboard, it suddenly doesn't work. The only difference in configuration is the font I've chosen (a custom one vs. the System font). Instead, all of the fonts show up on the device and simulator as the default system font at the default size, regardless of size class (and I verified via the debugger that it is substituting the system font for the actual one specified in the storyboard). So basically the size class feature appears to be broken for custom fonts. Also, interestingly, the custom fonts actually display and adjust size properly in the XCode 6 "Preview" pane for the view controller: it's only when running on the actual iOS system that it stops working (which makes me think that I'm configuring it correctly).

I tried multiple different custom fonts and it doesn't seem to work for any of them, but it always works if I use "System" instead.

Anyway, has anyone else seen this problem in Xcode 6? Any ideas on whether this is a bug in iOS 8, Xcode, or something I'm doing wrong? The only workaround I've found, like I said, is to continue to programmatically set the fonts like I have been for about 3 versions of iOS, because that does work. But I'd love to be able to use this feature if I could get it to work with custom fonts. Using the System font is not acceptable for our design.


ADDITIONAL INFO: As of Xcode 8.0, bug is fixed.

14条回答
Deceive 欺骗
2楼-- · 2019-01-07 05:02

This (and other Xcode - Size Classes related) bug caused me some serious grief recently as I had to go through a huge storyboard file hacking things away.

For anyone else in this position, I'd like to add something on top of @razor28's answer to ease the pain.

In the header file of your custom subclass, use IBInspectable for your runtime attributes. This will make these attributes accessible from the "Attributes Inspector", visually right above the default position for font settings.

Example use:

@interface MyCustomLabel : UILabel

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

@end

This will very helpfully produce this output:

enter image description here

An added benefit is that now we don't have to add the runtime attributes manually for each label. This is the closest I could get to XCode's intended behaviour. Hopefully a proper fix is on its way with iOS 9 this summer.

查看更多
等我变得足够好
3楼-- · 2019-01-07 05:04

I am using Swift, XCode 6.4. So this is what I did

import Foundation
import UIKit

    @IBDesignable class ExUILabel: UILabel {

        @IBInspectable var fontName: String = "Default-Font" {
            didSet {
                self.font = UIFont(name: fontName, size:self.font.pointSize)
            }
        }

        override func layoutSubviews() {
            super.layoutSubviews()
            self.font = UIFont(name: fontName, size:self.font.pointSize)
        }
    }
  1. Goto Designer -> Identity Inspector -> Set the class to ExUILabel

  2. Then go to Attribute inspector in designer and set the font name.

查看更多
登录 后发表回答