전체 페이지뷰

2017년 2월 9일 목요일

Chapter 3. Deeper into text, part 3

Font sizes and attributes

Label은 각 플랫폼에서 지정된 시스템 폰트를 디폴트로 사용합니다만 역시 폰트를 변경할 때 사용할 수 있는 몇몇 프로퍼티들을 가지고 있습니다. 폰트와 관련된 속성을 가지는 클래스로는 두가지가 있는데, 그것이 Label과 Button입니다. 
그 속성들은 다음과 같습니다.
  • FontFamily : string 타입
  • FontSize : double 타입
  • FontAttributes : FontAttributes 타입, None, Bold, Italic 열거형
또한 Font 속성과 해당 Font 구조체가 있지만, deprecated되어 사용하지 않아야 합니다.

가장 사용하기 어려운 것은 FontFamily 입니다. 이론상으론 "Times Roman"과 같은 것을 폰트 패밀리 이름으로 설정할 수 있지만, 해당 폰트 패밀리가 플랫폼에서 지원되는 경우에만 작동합니다. 그런 이유로 Device.OnPlatform과 함께 FontFamily를 사용하게 될 것이고, 각 플랫폼에서 지원하는 폰트 패밀리 이름도 알아두어야 합니다.

FontSize 속성도 조금 애매합니다. 대략적으로 말해서 폰트의 높이를 뜻하는 숫자가 필요한데, 어떤 숫자를 사용해야 할까요? 이것은 어려운 문제이고, 따라서 chapter 5, "Dealing with sizes"에서 다루기로 합니다.

그때까지는 Device 클래스의 GetNamedSize라는 static 메소드가 우릴 도울 것입니다. 이 메소드는 NamedSize라는 열거형의 멤버를 필요로 합니다.
  • Default
  • Micro
  • Small
  • Medium
  • Large
GetNamedSize는 크기를 조정하는 클래스 유형을 인수로 가지는데, 그것은 typeof (Label) 또는 typeof (Button)입니다. 또한 Type이 아닌 Label이나 Button 자체의 인스턴스를 사용할 수도 있지만 이 옵션은 불편할 때가 있습니다..

이 장의 뒷부분에서 보게 될 것이지만, NamedSize.Medium 멤버가 반드시 NamedSize.Default와 같은 크기를 반환하는 것은 아닙니다.

FontAttributes는 사용할 세 가지 글꼴 관련 속성 중 가장 간단합니다. 이 작은 스니펫 코드 (이전 장의 Greetings 프로그램에 적용해 보겠습니다)는 다음과 같이 Bold 또는 Italic 또는 둘 다를 지정할 수 있습니다.
public class GreetingsPage : ContentPage
{
    public GreetingsPage()
    {
        Content = new Label
        {
            Text = "Greetings Xamarin.Forms!",
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center,
            FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
            FontAttributes = FontAttributes.Bold | FontAttributes.Italic
        };      
    }
}
cs

윈도우즈 10 모바일의 Large 폰트는 한 줄에 쓰기 어려울 만큼 큰 것을 알 수 있습니다.


Formatted text

지금까지 본 것처럼 Label에는 문자열로 설정할 수 있는 Text 속성이 있습니다. 그러나 또한 Label에는 일정하지 않은 서식의 단락을 구성하는 대체 FormattedText 속성도 존재합니다.

FormattedText 속성의 형식은 FormattedString이며, Span object의 컬렉션인 IList <Span> 타입의 Spans 속성이 있습니다. Span 객체는 6 개의 속성에 의해 관리되는 형식화된 텍스트입니다

  • Text
  • FontFamily
  • FontSize
  • FontAttributes
  • ForegroundColor
  • BackgroundColor
다음은 FormattedString 객체를 인스턴스화 한 다음 Spans 인스턴스를 Spans 컬렉션 속성에 추가하는 한 가지 방법입니다.
public class VariableFormattedTextPage : ContentPage
{
    public VariableFormattedTextPage()
    {
        FormattedString formattedString = new FormattedString();
        formattedString.Spans.Add(new Span
        {
            Text = "I "
        });
        formattedString.Spans.Add(new Span
        {
            Text = "love",
            FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
            FontAttributes = FontAttributes.Bold
        });
        formattedString.Spans.Add(new Span
        {
            Text = " Xamarin.Forms!"
        });
        Content = new Label
        {
            FormattedText = formattedString,
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center,
            FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label))
        };
    }
}
cs

Span이 만들어지면 Spans 컬렉션의 Add 메서드에 바로 전달됩니다. 레이블의 FontSizeNamedSize.Large로 지정하고 Bold로 설정된 Span에도 동일한 크기를 명시적으로 지정한 것에 유의하시기 바랍니다. Span에 한번 FontAttributes 설정이 지정되면 Span은 더 이상 LabelFontSize 설정을 상속하지 않습니다.

아래처럼 하나의 중괄호 안에 Spans 컬렉션을 초기화하는 것도 가능합니다. 이 중괄호 안에서 Span 객체가 인스턴스화되고, 메서드 호출이 필요없기 때문에 FormattedString 초기화는 전부 Label 초기화 내부에서 할 수 있습니다.
public class VariableFormattedTextPage : ContentPage
{
    public VariableFormattedTextPage()
    {            
        Content = new Label
        {
            FormattedText = new FormattedString
            {
                Spans =
                {
                    new Span
                    {
                        Text="I "
                    },
                    new Span
                    {
                        Text = "love",
                        FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
                        FontAttributes = FontAttributes.Bold
                    },
                    new Span
                    {
                        Text = " Xamarin.Forms!"
                    }
                }
            },
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center,
            FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label))
        };
    }
}
cs

화면에 나타난 샘플코드는 다음과 같습니다. 어떤 방식을 사용하건 결과는 같을 것입니다.

FormattedText 속성을 사용하여 아래의 VariableFormattedParagraph처럼 전체 단락 내에 italic 또는 bold 단어를 포함할 수도 있습니다
public class VariableFormattedParagraphPage : ContentPage
{
    public VariableFormattedParagraphPage()
    {
        Content = new Label
        {
            FormattedText = new FormattedString
            {
                Spans =
                {
                    new Span
                    {
                        Text = "\u2003There was nothing so "
                    },
                    new Span
                    {
                        Text = "very",
                        FontAttributes = FontAttributes.Italic
                    },
                    new Span
                    {
                        Text = " remarkable in that; nor did Alice " +
                        "think it so "
                    },
                    new Span
                    {
                        Text = "very",
                        FontAttributes = FontAttributes.Italic
                    },
                    new Span
                    {
                        Text = " much out of the way to hear the " +
                        "Rabbit say to itself \u2018Oh " +
                        "dear! Oh dear! I shall be too late!" +
                        "\u2019 (when she thought it over " +
                        "afterwards, it occurred to her that " +
                        "she ought to have wondered at this, " +
                        "but at the time it all seemed quite " +
                        "natural); but, when the Rabbit actually "
                    },
                    new Span
                    {
                        Text = "took a watch out of its waistcoat-pocket",
                        FontAttributes = FontAttributes.Italic
                    },
                    new Span
                    {
                        Text = ", and looked at it, and then hurried on, " +
                        "Alice started to her feet, for it flashed " +
                        "across her mind that she had never before " +
                        "seen a rabbit with either a waistcoat-" +
                        "pocket, or a watch to take out of it, " +
                        "and, burning with curiosity, she ran " +
                        "across the field after it, and was just " +
                        "in time to see it pop down a large " +
                        "rabbit-hold under the hedge."
                    }
                }
            },
 
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center
        };
    }
}
cs

이 단락은 공백(유니코드 \u2003)으로 시작하고, 따옴표(유니코드 \u201C,\u201D)와 italic체를 포함합니다. 실행화면은 다음과 같습니다.



다음 NamedFontSizes의 예에서는 end-of-line 문자를 삽입하여 single Label 여러개로 여러 줄을 표시하는 것을 보여줍니다. 여러 개의 Span object가 foreach 루프 안에서 FormattedString 오브젝트에 추가됩니다. 각 Span 객체는 다른 NamedFont 값을 사용하고 Device.GetNamedSize에서 반환된 실제 크기로 출력됩니다
public class NamedFontSizesPage : ContentPage
{        
    public NamedFontSizesPage()
    {
        FormattedString formattedString = new FormattedString();
        NamedSize[] namedSizes =
        {
            NamedSize.Default,NamedSize.Micro,NamedSize.Small,
            NamedSize.Medium, NamedSize.Large
        };
 
        foreach (NamedSize namedSize in namedSizes)
        {
            double fontSize = Device.GetNamedSize(namedSize, typeof(Label));
 
            formattedString.Spans.Add(new Span
            {
                Text = String.Format("Named Size = {0} ({1:F2})", namedSize, fontSize),
                FontSize = fontSize
            });
 
            if (namedSize != namedSizes.Last())
            {
                formattedString.Spans.Add(new Span
                {
                    Text = Environment.NewLine + Environment.NewLine
                });
            }
        }
        Content = new Label
        {
            FormattedText = formattedString,
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center
        };
    }
}
cs

별도의 Span마다 개별 행을 구분하는 두 개의 플랫폼 관련 end-of-line 문자열이 들어 있습니다. 이렇게하면 줄 간격이 방금 표시된 글꼴 크기가 아닌 기본 글꼴 크기 기준이 됩니다.

이것들은 픽셀 크기가 아닙니다!  iOS 상태 표시 줄의 높이에서처럼, 이 크기를 일종의 "unit"으로 간주하는 것이 좋을 것입니다. 5 장에서 더 명확한 설명이 나옵니다.

Default 사이즈는 일반적으로 운영 체제에 의해 결정되지만 다른 크기는 Xamarin.Forms 개발자가 선택합니다. iOS에서는 DefaultMedium과 동일하고, Android DefaultSmall과 같으며, Windows 10 Mobile에서는 DefaultMicro보다 작습니다.

iPad 및 Windows 10에서의 크기는 각각 iPhone 및 Windows Mobile과 동일합니다. 그러나 Windows 8.1 및 Windows Phone 8.1 플랫폼에서는 일치하지 않는 경우가 더 많습니다.



물론 단일 Label에서 여러 Span객체를 사용하는 것은 여러 단락의 텍스트를 렌더링하는데 적절치 않습니다. 또한 텍스트에는 스크롤을 요하는 단락이 많습니다. 이것은 다음 장에서 나올 StackLayoutScrollView에서 살펴봅시다.

댓글 없음:

댓글 쓰기