Cách sử dụng phông chữ tùy chỉnh với kích thước văn bản động trong iOS7


88

Trong iOS7, có các API mới để nhận phông chữ được tự động điều chỉnh theo kích thước văn bản mà người dùng đã đặt theo sở thích của họ.

Nó trông giống như thế này để sử dụng nó:

UIFont *myFont = [UIFont fontWithDescriptor:[UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleHeadline] size:0];

Bây giờ, bất kỳ văn bản nào bạn gán cho nó sẽ di chuyển lên và xuống theo kích thước phông chữ khi người dùng thay đổi cài đặt kích thước văn bản hệ thống của họ. (Nhớ lắng nghe name:UIContentSizeCategoryDidChangeNotificationthông báo và cập nhật chế độ xem của bạn để tính đến việc thay đổi kích thước).

Làm cách nào để sử dụng văn bản động với phông chữ khác với phông chữ Helvetica-Neue mặc định?


Không phải đã đến lúc bạn chấp nhận một câu trả lời sao?
Khanh Nguyen,

Từ ios-11 +, Apple hỗ trợ sử dụng kích thước phông chữ động tùy chỉnh. Để thực hiện, vui lòng xem câu trả lời này .
Umair Ali,

Câu trả lời:


132

Đằng sau API đó, apple có một số loại bảng tra cứu trả về một họ phông chữ cụ thể, kích thước và đôi khi là các đặc điểm tượng trưng (như in đậm) (ví dụ UIFontTextStyleHeadline) và kích thước văn bản ưa thích của người dùng. Sau đó là một chuỗi được kéo ra sharedApplicationnhư thế này:

[UIApplication sharedApplication].preferredContentSizeCategory;

(Tôi đã đăng xuất tất cả các kích thước / phông chữ / đặc điểm mặc định cho Helvetica-Neue cho các kích thước văn bản động khác nhau). Kể từ đó, chúng tôi đã thêm xử lý cho các kích thước trợ năng, điều này rất quan trọng .

Vì vậy, tất cả những gì bạn thực sự phải làm là xây dựng một bảng tra cứu tương tự. Nhà thiết kế của chúng tôi đã tạo một bảng tính đơn giản cho tôi:

Bảng tra cứu kích thước phông chữ

Lưu ý rằng chúng tôi đã thêm một vài kiểu (chú thích 3 & 4) để có 8 thay vì 6 để lựa chọn.

Sau đó, bạn sẽ muốn đặt nó ở một nơi nào đó thuận tiện, như một danh mục trên UIFontDescriptor. Bạn sẽ muốn phương thức của mình trả về một UIFontDescriptorAPI giống như của Apple, để nó vẫn dễ dàng điều chỉnh với các đặc điểm tượng trưng, ​​v.v.

Danh mục của tôi trông như thế này:

UIFontDescriptor + AvenirNext.h

#import <UIKit/UIKit.h>

extern NSString *const ANUIFontTextStyleCaption3;

@interface UIFontDescriptor (AvenirNext)

+(UIFontDescriptor *)preferredAvenirNextFontDescriptorWithTextStyle:(NSString *)style;

@end

UIFontDescriptor + AvenirNext.m

#import "UIFontDescriptor+AvenirNext.h"

NSString *const ANUIFontTextStyleCaption3 = @"ANUIFontTextStyleCaption3";
NSString *const ANUIFontTextStyleCaption4 = @"ANUIFontTextStyleCaption4";

@implementation UIFontDescriptor (AvenirNext)
+(UIFontDescriptor *)preferredAvenirNextFontDescriptorWithTextStyle:(NSString *)style {
    static dispatch_once_t onceToken;
    static NSDictionary *fontSizeTable;
    dispatch_once(&onceToken, ^{
        fontSizeTable = @{
          UIFontTextStyleHeadline: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @26,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @25,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @24,
                                    UIContentSizeCategoryAccessibilityLarge: @24,
                                    UIContentSizeCategoryAccessibilityMedium: @23,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @23,
                                    UIContentSizeCategoryExtraExtraLarge: @22,
                                    UIContentSizeCategoryExtraLarge: @21,
                                    UIContentSizeCategoryLarge: @20,
                                    UIContentSizeCategoryMedium: @19,
                                    UIContentSizeCategorySmall: @18,
                                    UIContentSizeCategoryExtraSmall: @17,},

       UIFontTextStyleSubheadline: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @24,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @23,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @22,
                                    UIContentSizeCategoryAccessibilityLarge: @22,
                                    UIContentSizeCategoryAccessibilityMedium: @21,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @21,
                                    UIContentSizeCategoryExtraExtraLarge: @20,
                                    UIContentSizeCategoryExtraLarge: @19,
                                    UIContentSizeCategoryLarge: @18,
                                    UIContentSizeCategoryMedium: @17,
                                    UIContentSizeCategorySmall: @16,
                                    UIContentSizeCategoryExtraSmall: @15,},

              UIFontTextStyleBody: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @21,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @20,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @19,
                                    UIContentSizeCategoryAccessibilityLarge: @19,
                                    UIContentSizeCategoryAccessibilityMedium: @18,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @18,
                                    UIContentSizeCategoryExtraExtraLarge: @17,
                                    UIContentSizeCategoryExtraLarge: @16,
                                    UIContentSizeCategoryLarge: @15,
                                    UIContentSizeCategoryMedium: @14,
                                    UIContentSizeCategorySmall: @13,
                                    UIContentSizeCategoryExtraSmall: @12,},
          
          UIFontTextStyleCaption1: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @19,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @18,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @17,
                                    UIContentSizeCategoryAccessibilityLarge: @17,
                                    UIContentSizeCategoryAccessibilityMedium: @16,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @16,
                                    UIContentSizeCategoryExtraExtraLarge: @16,
                                    UIContentSizeCategoryExtraLarge: @15,
                                    UIContentSizeCategoryLarge: @14,
                                    UIContentSizeCategoryMedium: @13,
                                    UIContentSizeCategorySmall: @12,
                                    UIContentSizeCategoryExtraSmall: @12,},
          
          UIFontTextStyleCaption2: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @18,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @17,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @16,
                                    UIContentSizeCategoryAccessibilityLarge: @16,
                                    UIContentSizeCategoryAccessibilityMedium: @15,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @15,
                                    UIContentSizeCategoryExtraExtraLarge: @14,
                                    UIContentSizeCategoryExtraLarge: @14,
                                    UIContentSizeCategoryLarge: @13,
                                    UIContentSizeCategoryMedium: @12,
                                    UIContentSizeCategorySmall: @12,
                                    UIContentSizeCategoryExtraSmall: @11,},
          
        ANUIFontTextStyleCaption3: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @17,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @16,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @15,
                                    UIContentSizeCategoryAccessibilityLarge: @15,
                                    UIContentSizeCategoryAccessibilityMedium: @14,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @14,
                                    UIContentSizeCategoryExtraExtraLarge: @13,
                                    UIContentSizeCategoryExtraLarge: @12,
                                    UIContentSizeCategoryLarge: @12,
                                    UIContentSizeCategoryMedium: @12,
                                    UIContentSizeCategorySmall: @11,
                                    UIContentSizeCategoryExtraSmall: @10,},

          UIFontTextStyleFootnote: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @16,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @15,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @14,
                                    UIContentSizeCategoryAccessibilityLarge: @14,
                                    UIContentSizeCategoryAccessibilityMedium: @13,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @13,
                                    UIContentSizeCategoryExtraExtraLarge: @12,
                                    UIContentSizeCategoryExtraLarge: @12,
                                    UIContentSizeCategoryLarge: @11,
                                    UIContentSizeCategoryMedium: @11,
                                    UIContentSizeCategorySmall: @10,
                                    UIContentSizeCategoryExtraSmall: @10,},

          ANUIFontTextStyleCaption4: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @15,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @14,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @13,
                                    UIContentSizeCategoryAccessibilityLarge: @13,
                                    UIContentSizeCategoryAccessibilityMedium: @12,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @12,
                                    UIContentSizeCategoryExtraExtraLarge: @11,
                                    UIContentSizeCategoryExtraLarge: @11,
                                    UIContentSizeCategoryLarge: @10,
                                    UIContentSizeCategoryMedium: @10,
                                    UIContentSizeCategorySmall: @9,
                                    UIContentSizeCategoryExtraSmall: @9,},
        };
    });
    
    
    NSString *contentSize = [UIApplication sharedApplication].preferredContentSizeCategory;
    return [UIFontDescriptor fontDescriptorWithName:[self preferredFontName] size:((NSNumber *)fontSizeTable[style][contentSize]).floatValue];
}
+(UIFontDescriptor *)preferredAvenirNextDemiBoldFontDescriptorWithTextStyle:(NSString *)style {
    return [[self preferredAvenirNextFontDescriptorWithTextStyle:style] fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold];
}

+(UIFontDescriptor *)preferredAvenirNextBoldFontDescriptorWithTextStyle:(NSString *)style {
    return [UIFontDescriptor fontDescriptorWithName:[self preferredBoldFontName] size:[self preferredAvenirNextFontDescriptorWithTextStyle:style].pointSize];
}

+(NSString *)preferredFontName {
    return @"AvenirNext-Medium";
}
+(NSString *)preferredBoldFontName {
    return @"AvenirNext-Bold";
}

@end

Chúng tôi đã chọn sử dụng cùng một phông chữ cơ bản AvenirNext-Medium, sau đó in đậm và tương tự như vậy thông qua các đặc điểm tượng trưng, ​​nhưng bạn có thể phát điên và chỉ định các biến thể trọng lượng khác nhau trên phông chữ của mình như một phần của bảng tra cứu nếu bạn muốn, chẳng hạn như AvenirNext-ExtraBold.

Thats tất cả để có nó! Chúng tôi sử dụng nó như thế này:

[UIFont fontWithDescriptor:[UIFontDescriptor preferredAvenirNextFontDescriptorWithTextStyle:UIFontTextStyleHeadline] size: 0]

6
Giải pháp tuyệt vời, nhưng bạn đang bỏ lỡ các hằng số khả năng tiếp cận: UIContentSizeCategoryAccessibilityMedium, UIContentSizeCategoryAccessibilityLargevv
Ben Jackson

Ah thú vị. Thật vui khi biết @BenJackson. Cảm ơn!
Bob Spryn

1
Tại sao không mở rộng UIFont, để bạn chỉ có thể sử dụng [UIFont preferredAvenirFontForTextStyle:UIFontTextStyleHeadline]:? Kích thước là thừa trong ví dụ bạn đưa ra ở phía dưới?
Mingbit

2
@richarddas chỉ đơn giản là để phù hợp với khuôn mẫu của Apple. Kích thước 0 bị bỏ qua và chỉ cần chuyển qua kích thước chính xác từ bộ mô tả.
Bob Spryn

4
Kể từ iOS 8.4, Apple đã điều chỉnh kích thước phông chữ một chút: gist.github.com/klaas/750f489e2390389ab812
Klaas

15

Đây là cách tôi làm điều đó trong Swift. Tôi thích điều này vì nó tổng quát hơn, nó chỉ yêu cầu một bảng và nó sẽ hoạt động tốt với bất kỳ phông chữ nào. Đầu tiên, tôi đã viết một hệ số nhân tổng quát (trong một getter).

var fontSizeMultiplier : CGFloat {
    get {
        switch UIApplication.sharedApplication().preferredContentSizeCategory {
        case UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: return 23 / 16
        case UIContentSizeCategoryAccessibilityExtraExtraLarge: return 22 / 16
        case UIContentSizeCategoryAccessibilityExtraLarge: return 21 / 16
        case UIContentSizeCategoryAccessibilityLarge: return 20 / 16
        case UIContentSizeCategoryAccessibilityMedium: return 19 / 16
        case UIContentSizeCategoryExtraExtraExtraLarge: return 19 / 16
        case UIContentSizeCategoryExtraExtraLarge: return 18 / 16
        case UIContentSizeCategoryExtraLarge: return 17 / 16
        case UIContentSizeCategoryLarge: return 1.0
        case UIContentSizeCategoryMedium: return 15 / 16
        case UIContentSizeCategorySmall: return 14 / 16
        case UIContentSizeCategoryExtraSmall: return 13 / 16
        default: return 1.0
        }
    }
}

Sau đó, tôi cập nhật phông chữ (ví dụ: trong trình quan sát) bằng cách sử dụng UIFontDescriptornhư sau:

textView.font = UIFont(descriptor: fontDescriptor!, size: fontDescriptor!.pointSize * fontSizeMultiplier)

Điều này sẽ không hoạt động vì pointSize sẽ tăng theo cấp số nhân mỗi khi bạn cập nhật kích thước trong cài đặt. Nếu bạn đặt kích thước phông chữ mặc định, bạn có thể sử dụng kích thước phông chữ đó làm cơ sở và nhân kích thước đó với fontSizeMultiplier.
TejAces

@TejAces - Điều này hoạt động tốt. Tôi đã sử dụng nó trong nhiều năm. Vì nó trả về các giá trị theo nghĩa đen nên tôi không thấy bạn nghĩ nó sẽ tăng lên như thế nào khi bạn thay đổi cài đặt.
Bill Weinman

12

Trong UIFontMetricslớp iOS 11 đã được giới thiệu. Tạo một đối tượng FontMetrics cho kiểu văn bản mà bạn quan tâm. Sau đó, chọn bất kỳ phông chữ nào bạn muốn, có kích thước cho kích thước kiểu động tiêu chuẩn. Và sau đó, bạn có thể yêu cầu đối tượng FontMetrics mở rộng phông chữ đó theo cài đặt hiện tại của người dùng.

let bodyMetrics = UIFontMetrics(forTextStyle: .body)
let standardFont = ... // any font you want, for standard type size
let font = bodyMetrics.scaledFont(for: standardFont)

8

Mã @Bob Spryn được viết lại nhanh chóng:

import UIKit

extension UIFontDescriptor {

    private struct SubStruct {
        static var preferredFontName: NSString = "OEMeodedPashutPro-Regular"
    }

    class func preferredDescriptor(textStyle: NSString) -> UIFontDescriptor {
        struct Static {
            static var onceToken : dispatch_once_t = 0
            static var fontSizeTable : NSDictionary = NSDictionary()
        }

        dispatch_once(&Static.onceToken) {
            Static.fontSizeTable = [
                UIFontTextStyleHeadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 26,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 25,
                    UIContentSizeCategoryAccessibilityExtraLarge: 24,
                    UIContentSizeCategoryAccessibilityLarge: 24,
                    UIContentSizeCategoryAccessibilityMedium: 23,
                    UIContentSizeCategoryExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryExtraExtraLarge: 22,
                    UIContentSizeCategoryExtraLarge: 21,
                    UIContentSizeCategoryLarge: 20,
                    UIContentSizeCategoryMedium: 19,
                    UIContentSizeCategorySmall: 18,
                    UIContentSizeCategoryExtraSmall: 17
                ],
                UIFontTextStyleSubheadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 24,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityExtraLarge: 22,
                    UIContentSizeCategoryAccessibilityLarge: 22,
                    UIContentSizeCategoryAccessibilityMedium: 21,
                    UIContentSizeCategoryExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraExtraLarge: 20,
                    UIContentSizeCategoryExtraLarge: 19,
                    UIContentSizeCategoryLarge: 18,
                    UIContentSizeCategoryMedium: 17,
                    UIContentSizeCategorySmall: 16,
                    UIContentSizeCategoryExtraSmall: 15
                ],
                UIFontTextStyleBody: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 20,
                    UIContentSizeCategoryAccessibilityExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityLarge: 19,
                    UIContentSizeCategoryAccessibilityMedium: 18,
                    UIContentSizeCategoryExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryExtraExtraLarge: 17,
                    UIContentSizeCategoryExtraLarge: 16,
                    UIContentSizeCategoryLarge: 15,
                    UIContentSizeCategoryMedium: 14,
                    UIContentSizeCategorySmall: 13,
                    UIContentSizeCategoryExtraSmall: 12
                ],
                UIFontTextStyleCaption1: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityLarge: 17,
                    UIContentSizeCategoryAccessibilityMedium: 16,
                    UIContentSizeCategoryExtraExtraExtraLarge: 16,
                    UIContentSizeCategoryExtraExtraLarge: 16,
                    UIContentSizeCategoryExtraLarge: 15,
                    UIContentSizeCategoryLarge: 14,
                    UIContentSizeCategoryMedium: 13,
                    UIContentSizeCategorySmall: 12,
                    UIContentSizeCategoryExtraSmall: 12
                ],
                UIFontTextStyleCaption2: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityExtraLarge: 16,
                    UIContentSizeCategoryAccessibilityLarge: 16,
                    UIContentSizeCategoryAccessibilityMedium: 15,
                    UIContentSizeCategoryExtraExtraExtraLarge: 15,
                    UIContentSizeCategoryExtraExtraLarge: 14,
                    UIContentSizeCategoryExtraLarge: 14,
                    UIContentSizeCategoryLarge: 13,
                    UIContentSizeCategoryMedium: 12,
                    UIContentSizeCategorySmall: 12,
                    UIContentSizeCategoryExtraSmall: 11
                ],
                UIFontTextStyleFootnote: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 16,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 15,
                    UIContentSizeCategoryAccessibilityExtraLarge: 14,
                    UIContentSizeCategoryAccessibilityLarge: 14,
                    UIContentSizeCategoryAccessibilityMedium: 13,
                    UIContentSizeCategoryExtraExtraExtraLarge: 13,
                    UIContentSizeCategoryExtraExtraLarge: 12,
                    UIContentSizeCategoryExtraLarge: 12,
                    UIContentSizeCategoryLarge: 11,
                    UIContentSizeCategoryMedium: 11,
                    UIContentSizeCategorySmall: 10,
                    UIContentSizeCategoryExtraSmall: 10
                ],
            ]
        }

        let contentSize = UIApplication.sharedApplication().preferredContentSizeCategory

        let style = Static.fontSizeTable[textStyle] as NSDictionary

        return UIFontDescriptor(name: SubStruct.preferredFontName, size: CGFloat((style[contentSize] as NSNumber).floatValue))
    }

}

Sử dụng:

UIFont(descriptor: UIFontDescriptor.preferredDescriptor(UIFontTextStyleBody), size: 0)

1
Xcode 7.2 khiến tôi thay đổi hai dòng cuối cùng để: let style = Static.fontSizeTable[textStyle] as! NSDictionaryreturn UIFontDescriptor(name: SubStruct.preferredFontName as String, size: CGFloat((style[contentSize] as! NSNumber).floatValue))
Koen

Sẽ thực sự tuyệt vời nếu tôi có thể làm điều gì đó hiển thị phông chữ ưa thích trong Storyboard. Có thể bằng cách phân lớp các thành phần văn bản.
Aaron Bratcher

7

Thử đi:

UIFontDescriptor *userHeadLineFont = [UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleHeadline];
CGFloat userHeadLineFontSize = [userHeadLineFont pointSize];
myFont = [UIFont fontWithName:@"Baskerville" size:userHeadLineFontSize];

Nhưng hãy nhớ rằng mã này chỉ là một con số gần đúng (Loại động làm được nhiều hơn là chỉ chia tỷ lệ kích thước phông chữ).


Bạn có thể nói rõ hơn về câu chuyện ngụ ngôn? Tôi nên tính đến điều gì ngoài việc mở rộng quy mô?
hfossli

2
Có một ánh xạ giữa phông chữ "loại động" và phông chữ thực sự được sử dụng. Ví dụ, phông chữ nhỏ có thể trở nên đậm. Tôi không biết bản đồ chính xác. Xem hình ảnh cuối cùng ("chia tỷ lệ quang loại động") trong bài viết này: fireballed.org/linked/2013/07/08/ios-7-type để hiểu rõ hơn.
valfer

1
Câu trả lời này giống với câu trả lời đúng đã được phê duyệt, nhưng có sự khác biệt về số dòng. Giải pháp tuyệt vời. Tương tự trong SWIFT stackoverflow.com/questions/35355695/…
Vanya

Đây là một liên kết hoạt động đến bài viết được @valfer đề cập trong phần nhận xét: Beyond Helvetica: The Real Story Behind Fonts trong iOS 7
0xced

6

Tương tự như cách tiếp cận của @ bill-weinman , tôi đã cân nhắc và chia nó thành một hàm không phụ thuộc vào kích thước phông chữ nhất định là 16.

/// The font scale for a given font size.
///
/// - seealso: [Source](https://stackoverflow.com/a/33114525/3643020)
///
/// - Parameter fontSize: The font size.
/// - Returns: The font scale
public func fontScale(for fontSize: CGFloat) -> CGFloat {
    switch UIApplication.shared.preferredContentSizeCategory {
    case UIContentSizeCategory.accessibilityExtraExtraExtraLarge:    return (fontSize + 8) / fontSize
    case UIContentSizeCategory.accessibilityExtraExtraLarge:         return (fontSize + 7) / fontSize
    case UIContentSizeCategory.accessibilityExtraLarge:              return (fontSize + 6) / fontSize
    case UIContentSizeCategory.accessibilityLarge:                   return (fontSize + 5) / fontSize
    case UIContentSizeCategory.accessibilityMedium:                  return (fontSize + 4) / fontSize
    case UIContentSizeCategory.extraExtraExtraLarge:                 return (fontSize + 3) / fontSize
    case UIContentSizeCategory.extraExtraLarge:                      return (fontSize + 2) / fontSize
    case UIContentSizeCategory.extraLarge:                           return (fontSize + 1) / fontSize
    case UIContentSizeCategory.large:                                return 1.0
    case UIContentSizeCategory.medium:                               return (fontSize - 1) / fontSize
    case UIContentSizeCategory.small:                                return (fontSize - 2) / fontSize
    case UIContentSizeCategory.extraSmall:                           return (fontSize - 3) / fontSize
    default:
        return 1.0
    }
}

Sau đó, nó có thể được sử dụng với các phông chữ tùy chỉnh như sau:

/// Light font of specified size.
///
/// - Parameter size: Font size.
/// - Returns: Light font of specified size.
func lightFont(ofSize size: CGFloat) -> UIFont {
    let scaledSize = size * fontScale(for: size)

    return UIFont(name: "HelveticaNeueLTStd-Lt", size: scaledSize)!
}

Điều này không tồi nếu bạn đang ở giai đoạn mà bạn không muốn tinh chỉnh mọi thứ. Ngoài ra, nếu phông chữ tùy chỉnh của bạn khá nhỏ và cần một số tỷ lệ theo mặc định.
JanBrinker 27/09/17

FYI - cách tiếp cận của tôi không dựa vào kích thước phông chữ. Nó trả về một giá trị dựa trên một tỷ lệ. Nó hoạt động tốt với các phông chữ tùy chỉnh / tỷ lệ.
Bill Weinman

3

Trong iOS 11, bạn có thể sử dụng:

var customFont = UIFont.systemFont(ofSize: 17.0)
if #available(iOS 11.0, *) {
    customFont = UIFontMetrics.default.scaledFont(for: customFont)
}
// use customFont...

Xem thêm Xây dựng ứng dụng với Loại động WWDC 2017 - Phiên 245 - Thời gian iOS 8:34.


2

Mã Swift 2.1-3.0 dựa trên cổng @Bob Spryn của @ smartDonkey. Cũng được cập nhật với các kích thước của Apple từ @Klaas .

import UIKit

extension UIFontDescriptor {

    private struct SubStruct {
        static var preferredFontName: String = "Roboto-Light"
    }

    class func preferredDescriptor(textStyle: NSString) -> UIFontDescriptor {
        struct Static {
            static var onceToken : dispatch_once_t = 0
            static var fontSizeTable : NSDictionary = NSDictionary()
        }

        dispatch_once(&Static.onceToken) {
            Static.fontSizeTable = [
                UIFontTextStyleHeadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityLarge: 23,
                    UIContentSizeCategoryAccessibilityMedium: 23,
                    UIContentSizeCategoryExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraLarge: 19,
                    UIContentSizeCategoryLarge: 17,
                    UIContentSizeCategoryMedium: 16,
                    UIContentSizeCategorySmall: 15,
                    UIContentSizeCategoryExtraSmall: 14
                ],
                UIFontTextStyleSubheadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityLarge: 21,
                    UIContentSizeCategoryAccessibilityMedium: 21,
                    UIContentSizeCategoryExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraExtraLarge: 19,
                    UIContentSizeCategoryExtraLarge: 17,
                    UIContentSizeCategoryLarge: 15,
                    UIContentSizeCategoryMedium: 14,
                    UIContentSizeCategorySmall: 13,
                    UIContentSizeCategoryExtraSmall: 12
                ],
                UIFontTextStyleBody: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 53,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 47,
                    UIContentSizeCategoryAccessibilityExtraLarge: 40,
                    UIContentSizeCategoryAccessibilityLarge: 33,
                    UIContentSizeCategoryAccessibilityMedium: 28,
                    UIContentSizeCategoryExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraLarge: 19,
                    UIContentSizeCategoryLarge: 17,
                    UIContentSizeCategoryMedium: 16,
                    UIContentSizeCategorySmall: 15,
                    UIContentSizeCategoryExtraSmall: 14
                ],
                UIFontTextStyleCaption1: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityLarge: 18,
                    UIContentSizeCategoryAccessibilityMedium: 18,
                    UIContentSizeCategoryExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryExtraExtraLarge: 16,
                    UIContentSizeCategoryExtraLarge: 14,
                    UIContentSizeCategoryLarge: 12,
                    UIContentSizeCategoryMedium: 11,
                    UIContentSizeCategorySmall: 11,
                    UIContentSizeCategoryExtraSmall: 11
                ],
                UIFontTextStyleCaption2: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityLarge: 17,
                    UIContentSizeCategoryAccessibilityMedium: 17,
                    UIContentSizeCategoryExtraExtraExtraLarge: 17,
                    UIContentSizeCategoryExtraExtraLarge: 15,
                    UIContentSizeCategoryExtraLarge: 13,
                    UIContentSizeCategoryLarge: 11,
                    UIContentSizeCategoryMedium: 11,
                    UIContentSizeCategorySmall: 11,
                    UIContentSizeCategoryExtraSmall: 11
                ],
                UIFontTextStyleFootnote: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityLarge: 19,
                    UIContentSizeCategoryAccessibilityMedium: 19,
                    UIContentSizeCategoryExtraExtraExtraLarge: 19,
                    UIContentSizeCategoryExtraExtraLarge: 17,
                    UIContentSizeCategoryExtraLarge: 15,
                    UIContentSizeCategoryLarge: 13,
                    UIContentSizeCategoryMedium: 12,
                    UIContentSizeCategorySmall: 12,
                    UIContentSizeCategoryExtraSmall: 12
                ],
            ]
        }

        let contentSize = UIApplication.sharedApplication().preferredContentSizeCategory
        let style = Static.fontSizeTable[textStyle] as! NSDictionary
        return UIFontDescriptor(name: SubStruct.preferredFontName, size: CGFloat((style[contentSize] as! NSNumber).floatValue))
    }

}

Lỗi trên Swift 3 với giải pháp của bạn:'dispatch_once_t' is unavailable in Swift: Use lazily initialized globals instead
thexande

2

Đây là câu trả lời của tôi về câu trả lời của @ Gobe, trong Swift 3:

extension UIFontDescriptor {

@nonobjc static var fontSizeTable: [UIFontTextStyle : [UIContentSizeCategory : CGFloat]] = {
    return [
        .headline: [
            .accessibilityExtraExtraExtraLarge: 23,
            .accessibilityExtraExtraLarge: 23,
            .accessibilityExtraLarge: 23,
            .accessibilityLarge: 23,
            .accessibilityMedium: 23,
            .extraExtraExtraLarge: 23,
            .extraExtraLarge: 21,
            .extraLarge: 19,
            .large: 17,
            .medium: 16,
            .small: 15,
            .extraSmall: 14],
        .subheadline: [
            .accessibilityExtraExtraExtraLarge: 21,
            .accessibilityExtraExtraLarge: 21,
            .accessibilityExtraLarge: 21,
            .accessibilityLarge: 21,
            .accessibilityMedium: 21,
            .extraExtraExtraLarge: 21,
            .extraExtraLarge: 19,
            .extraLarge: 17,
            .large: 15,
            .medium: 14,
            .small: 13,
            .extraSmall: 12],
        .body: [
            .accessibilityExtraExtraExtraLarge: 53,
            .accessibilityExtraExtraLarge: 47,
            .accessibilityExtraLarge: 40,
            .accessibilityLarge: 33,
            .accessibilityMedium: 28,
            .extraExtraExtraLarge: 23,
            .extraExtraLarge: 21,
            .extraLarge: 19,
            .large: 17,
            .medium: 16,
            .small: 15,
            .extraSmall: 14],
        .caption1: [
            .accessibilityExtraExtraExtraLarge: 18,
            .accessibilityExtraExtraLarge: 18,
            .accessibilityExtraLarge: 18,
            .accessibilityLarge: 18,
            .accessibilityMedium: 18,
            .extraExtraExtraLarge: 18,
            .extraExtraLarge: 16,
            .extraLarge: 14,
            .large: 12,
            .medium: 11,
            .small: 11,
            .extraSmall: 11],
        .caption2: [
            .accessibilityExtraExtraExtraLarge: 17,
            .accessibilityExtraExtraLarge: 17,
            .accessibilityExtraLarge: 17,
            .accessibilityLarge: 17,
            .accessibilityMedium: 17,
            .extraExtraExtraLarge: 17,
            .extraExtraLarge: 15,
            .extraLarge: 13,
            .large: 11,
            .medium: 11,
            .small: 11,
            .extraSmall: 11],
        .footnote: [
            .accessibilityExtraExtraExtraLarge: 19,
            .accessibilityExtraExtraLarge: 19,
            .accessibilityExtraLarge: 19,
            .accessibilityLarge: 19,
            .accessibilityMedium: 19,
            .extraExtraExtraLarge: 19,
            .extraExtraLarge: 17,
            .extraLarge: 15,
            .large: 13,
            .medium: 12,
            .small: 12,
            .extraSmall: 12],
    ]
}()

class func currentPreferredSize(textStyle: UIFontTextStyle = .body) -> CGFloat {
    let contentSize = UIApplication.shared.preferredContentSizeCategory
    guard let style = fontSizeTable[textStyle], let fontSize = style[contentSize] else { return 17 }
    return fontSize
}

class func preferredFontDescriptor(fontName: String = "SnellRoundhand", textStyle: UIFontTextStyle = .body) -> UIFontDescriptor {
    return UIFontDescriptor(name: fontName, size: currentPreferredSize())
}
}

Phiên bản Swift5 đã được thêm vào stackoverflow.com/questions/41798080/…
marika.daboja

1

Đây là cách tôi cập nhật phông chữ của prefferedFontForTextStyle:

UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
UIFontDescriptor *fontDesc = [font fontDescriptor];
fontDesc = [fontDesc fontDescriptorByAddingAttributes:@{UIFontDescriptorNameAttribute : @"Helvetica",
                                                        UIFontDescriptorSizeAttribute : @16}];

font = [UIFont fontWithDescriptor:fontDesc
                             size:[fontDesc pointSize]];

1

Chỉ muốn nhảy vào và nói rằng có một thư viện ngoài đó để giúp tích hợp các phông chữ tùy chỉnh và đối phó với các thay đổi kích thước Kiểu động. Thật hữu ích, nó được gọi là Phông chữ ( https://github.com/adamyanalunas/Font ) và thay vì là một giải pháp kỳ diệu, nó thiết lập một cấu trúc để xử lý từng phông chữ tùy chỉnh khác nhau trong khi loại bỏ bảng soạn sẵn.

nb Tôi là tác giả của thư viện lil 'này và tôi nghĩ nó gọn gàng.


0

Bắt đầu từ iOS 11, bạn có thể lập trình điều chỉnh phông chữ tùy chỉnh được định cấu hình trong trình chỉnh sửa trực quan:

  1. Định cấu hình phông chữ tùy chỉnh của bạn bằng trình chỉnh sửa trực quan
  2. Điều chỉnh kích thước phông chữ trong phương thức viewDidLoad:
@IBOutlet weak var leftLangLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    leftLangLabel.font = UIFontMetrics.default.scaledFont(for: leftLangLabel.font)
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.