반응형

 

Hacking with Swift 사이트의 강좌 번역본입니다.

 

[원문 : https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-dynamic-type-with-a-custom-font]

 

How to use Dynamic Type with a custom font

 

SwiftUI는 font() modifier을 사용해서 설정하는 모든 Dynamic Type의 폰트 크기를 제공합니다. 하지만, 특정 폰트와 크기를 요구하는 경우, 텍스트가 더 이상 사용자의 Dynamic Type 설정에 따라 확대하거나 축소되지 않는 것을 알게 될 것 입니다 - 고정되어 있습니다.

 

이 작업을 하려면 현재 접근성(accessibility) 설정에 따라 폰트 크기를 확대할 수 있는 사용자정의 ViewModifer를 만들어야 하고, 설정이 변경될때 감지해야 합니다. 

 

코드를 먼저 보고, 작동 방법과 그 이유를 살펴볼 것입니다.

@available(iOS 13, macCatalyst 13, tvOS 13, watchOS 6, *)
struct ScaledFont: ViewModifier {
    @Environment(\.sizeCategory) var sizeCategory
    var name: String
    var size: CGFloat

    func body(content: Content) -> some View {
       let scaledSize = UIFontMetrics.default.scaledValue(for: size)
        return content.font(.custom(name, size: scaledSize))
    }
}

@available(iOS 13, macCatalyst 13, tvOS 13, watchOS 6, *)
extension View {
    func scaledFont(name: String, size: CGFloat) -> some View {
        return self.modifier(ScaledFont(name: name, size: size))
    }
}

 

그것은 Dynamic Type으로 사용자정의 폰트를 사용하는데 필요한 모든 코드 입니다. 이를 사용하는 예제로, 여기에 2개의 텍스트 뷰의 목록이 있고 하나는 내장된 폰트를 사용하고, 하나는 확대가능한 Georgia 폰트입니다. 

struct ContentView: View {
    var body: some View {
        List {
            Text("Hello World")
            Text("Hello World")
                .scaledFont(name: "Georgia", size: 12)
        }
    }
}

 

지금까지 작동 방법을 살펴봤고, 왜 그렇게 동작하는지 살펴봅시다.

 

우선, 여기에 사용자정의 뷰 modifier이 있습니다.

struct ScaledFont: ViewModifier {
    @Environment(\.sizeCategory) var sizeCategory
    var name: String
    var size: CGFloat

    func body(content: Content) -> some View {
       let scaledSize = UIFontMetrics.default.scaledValue(for: size)
        return content.font(.custom(name, size: scaledSize))
    }
}

 

폰트의 이름과 크기를 사용하고, UIFontMetrics를 사용해서 요청된 폰트가 사용자의 현재 기기 설정과 일치하도록 확대하고 다시 돌려보냅니다.

 

사용하기 쉽게 View에 있는 확장으로 감싸줍니다.

@available(iOS 13, macCatalyst 13, tvOS 13, watchOS 6, *)
extension View {
    func scaledFont(name: String, size: CGFloat) -> some View {
        return self.modifier(ScaledFont(name: name, size: size))
    }
}

 

모든 것은 사용자정의 폰트 modifier를 호출하는 것으로 끝나므로 뷰가 더 멋지게 보입니다 - .modifier(ScaledFont(nmae: Georgia, size: 12)) 대신, 사용하기 위해 .scaledFont(name: Georgia, size: 12)를 작성한다는 의미입니다. 

 

이제, 우리가 데이터를 전달하는 일을 하는 경우에 왜 사용자정의 modifier가 필요한지 궁금할지도 모릅니다. 그 실마리는 뷰 modifier에 있습니다.

@Environment(\.sizeCategory) var sizeCategory

 

시스템에게 environment에서 현재 크기 카테고리를 요청하며, 어떤 레벨의 Dynamic Type이 설정되는지를 결정합니다. 비결은 실제로 사용하지 않는 것입니다 - Dynamic Type 설정이 무엇인지 상관없지만, UIFontMetrics 코드가 변경될때 시스템은 업데이트를 요청하면 동시에 실행할 것이며, 폰트가 올바르게 확대될 것입니다. 

 

 : UIFontMetrics 클래스는 macOS에서는 사용할수 없으며, @available 표시를 추가한 이유입니다.

반응형
Posted by 까칠코더
,