다음을 통해 공유


iOS용 Xamarin 디자이너의 사용자 지정 컨트롤

iOS용 Xamarin 디자이너는 프로젝트에서 만들거나 Xamarin 구성 요소 저장소와 같은 외부 원본에서 참조되는 사용자 지정 컨트롤 렌더링을 지원합니다.

Warning

iOS 디자이너는 Visual Studio 2019 버전 16.8 및 Mac용 Visual Studio 2019 버전 8.8에서 사용이 중단되었으며 Visual Studio 2019 버전 16.9 및 Mac용 Visual Studio 버전 8.9에서 제거되었습니다. iOS 사용자 인터페이스를 빌드하는 권장 방법은 Xcode를 실행하는 Mac에서 직접 수행하는 것입니다. 자세한 내용은 Xcode를 사용하여 사용자 인터페이스 디자인을 참조하세요.

iOS용 Xamarin Designer는 애플리케이션의 사용자 인터페이스를 시각화하기 위한 강력한 도구이며 대부분의 iOS 보기 및 보기 컨트롤러에 대한 WYSIWYG 편집 지원을 제공합니다. 앱에는 iOS에 기본 제공되는 컨트롤을 확장하는 사용자 지정 컨트롤도 포함될 수 있습니다. 이러한 사용자 지정 컨트롤이 몇 가지 지침을 염두에 두고 작성된 경우 iOS 디자이너에서 렌더링하여 더욱 풍부한 편집 환경을 제공할 수 있습니다. 이 문서에서는 이러한 지침을 살펴봅합니다.

요구 사항

다음 요구 사항을 모두 충족하는 컨트롤이 디자인 화면에 렌더링됩니다.

  1. UIView 또는 UIViewController직접 또는 간접 하위 클래스입니다. 다른 NSObject 하위 클래스는 디자인 화면에 아이콘으로 표시됩니다.
  2. 에 노출하는 RegisterAttribute 가 있습니다 Objective-C.
  3. 필요한 IntPtr 생성자가 있습니다.
  4. IComponent 인터페이스를 구현하거나 DesignTimeVisibleAttribute가 True로 설정되어 있습니다.

위의 요구 사항을 충족하는 코드에 정의된 컨트롤은 시뮬레이터에 대해 포함된 프로젝트가 컴파일될 때 디자이너에 표시됩니다. 기본적으로 모든 사용자 지정 컨트롤은 도구 상자사용자 지정 구성 요소 섹션에 표시됩니다. 그러나 CategoryAttribute 를 사용자 지정 컨트롤의 클래스에 적용하여 다른 섹션을 지정할 수 있습니다.

디자이너는 타사 Objective-C 라이브러리 로드를 지원하지 않습니다.

사용자 지정 속성

다음 조건이 충족되면 사용자 지정 컨트롤에 의해 선언된 속성이 속성 패널에 표시됩니다.

  1. 속성에는 공용 getter 및 setter가 있습니다.
  2. 이 속성에는 ExportAttributeBrowsableAttribute 가 True로 설정되어 있습니다.
  3. 속성 형식은 숫자 형식, 열거형 형식, 문자열, 부울, SizeF, UIColor 또는 UIImage입니다. 이 지원되는 형식 목록은 나중에 확장될 수 있습니다.

속성 패널에 표시되는 레이블을 지정하기 위해 DisplayNameAttribute 로 속성을 데코레이트할 수도 있습니다.

초기화

하위 클래스의 경우 UIViewController 디자이너에서 만든 뷰에 따라 달라지는 코드에 ViewDidLoad 메서드를 사용해야 합니다.

다른 NSObject 서브클래스의 경우UIView, Layout 파일에서 로드된 후 사용자 지정 컨트롤의 초기화를 수행하는 데는 AwakeFromNib 메서드를 사용하는 것이 좋습니다. 이는 컨트롤의 생성자가 실행될 때 속성 패널에 설정된 사용자 지정 속성이 설정되지 않지만 호출되기 전에 AwakeFromNib 설정되기 때문입니다.

[Register ("CustomView"), DesignTimeVisible (true)]
public class CustomView : UIView {

    public CustomView (IntPtr handle) : base (handle) { }

    public override void AwakeFromNib ()
    {
        // Initialize the view here.
    }
}

컨트롤이 코드에서 직접 생성되도록 디자인된 경우 다음과 같이 일반적인 초기화 코드가 있는 메서드를 만들 수 있습니다.

[Register ("CustomView"), DesignTimeVisible (true)]
public class CustomView : UIView {

    public CustomView (IntPtr handle) : base (handle) { }

    public CustomView ()
    {
        // Called when created from code.
        Initialize ();
    }

    public override void AwakeFromNib ()
    {
        // Called when loaded from xib or storyboard.
        Initialize ();
    }

    void Initialize ()
    {
        // Common initialization code here.
    }
}

속성 초기화 및 AwakeFromNib

iOS 디자이너 내에서 설정된 값을 덮어쓰지 않도록 사용자 지정 구성 요소에서 디자인 가능한 속성을 초기화하는 시기와 위치를 주의해야 합니다. 예를 들어 다음 코드를 사용합니다.

[Register ("CustomView"), DesignTimeVisible (true)]
public class CustomView : UIView {

    [Export ("Counter"), Browsable (true)]
    public int Counter {get; set;}

    public CustomView (IntPtr handle) : base (handle) { }

    public CustomView ()
    {
        // Called when created from code.
        Initialize ();
    }

    public override void AwakeFromNib ()
    {
        // Called when loaded from xib or storyboard.
        Initialize ();
    }

    void Initialize ()
    {
        // Common initialization code here.
        Counter = 0;
    }
}

CustomView 구성 요소는 iOS 디자이너 내에서 개발자가 설정할 수 있는 속성을 노출 Counter 합니다. 그러나 디자이너 내에서 어떤 값을 설정하든 속성 값 Counter 은 항상 0이 됩니다. 이유는 다음과 같습니다.

  • 스토리보드 파일에서 인스턴스 CustomControl 가 확장됩니다.
  • iOS 디자이너에서 수정된 모든 속성이 설정됩니다(예: 2로 값 Counter 설정 등).
  • AwakeFromNib 메서드가 실행되고 구성 요소의 Initialize 메서드에 대한 호출이 이루어집니다.
  • 속성 값 내에서 InitializeCounter 0으로 다시 설정됩니다.

위의 상황을 해결하려면 다른 위치(예: 구성 요소의 생성자)에서 속성을 초기화 Counter 하거나 메서드를 재정 AwakeFromNib 의하고 구성 요소에서 현재 생성자가 처리 중인 것 외에 더 이상 초기화가 필요하지 않은 경우 호출 Initialize 하지 마세요.

디자인 모드

디자인 화면에서 사용자 지정 컨트롤은 몇 가지 제한 사항을 준수해야 합니다.

  • 앱 번들 리소스는 디자인 모드에서 사용할 수 없습니다. 이미지는 UIImage 메서드를 통해 로드할 때 사용할 수 있습니다 .
  • 웹 요청과 같은 비동기 작업은 디자인 모드에서 수행해서는 안 됩니다. 디자인 화면에서는 컨트롤의 UI에 대한 애니메이션 또는 기타 비동기 업데이트를 지원하지 않습니다.

사용자 지정 컨트롤은 IComponent를 구현하고 DesignMode 속성을 사용하여 디자인 화면에 있는 경우 검사 수 있습니다. 이 예제에서 레이블은 디자인 화면에 "디자인 모드"를, 런타임에 "런타임"을 표시합니다.

[Register ("DesignerAwareLabel")]
public class DesignerAwareLabel : UILabel, IComponent {

    #region IComponent implementation

    public ISite Site { get; set; }
    public event EventHandler Disposed;

    #endregion

    public DesignerAwareLabel (IntPtr handle) : base (handle) { }

    public override void AwakeFromNib ()
    {
        if (Site != null && Site.DesignMode)
            Text = "Design Mode";
        else
            Text = "Runtime";
    }
}

멤버에 액세스하기 전에 항상 속성을 null 검사 Site 합니다. 이 null경우 Site 컨트롤이 디자이너에서 실행되고 있지 않다고 가정해도 안전합니다. 디자인 모드에서는 Site 컨트롤의 생성자가 실행된 후 호출되기 전에 AwakeFromNib 설정됩니다.

디버깅

위의 요구 사항을 충족하는 컨트롤이 도구 상자에 표시되고 화면에 렌더링됩니다. 컨트롤이 렌더링되지 않으면 컨트롤의 버그 또는 해당 종속성 중 하나를 검사.

디자인 화면은 다른 컨트롤을 계속 렌더링하는 동안 개별 컨트롤에서 throw된 예외를 catch할 수 있습니다. 잘못된 컨트롤이 빨간색 자리 표시자로 대체되고 느낌표 아이콘을 클릭하여 예외 추적을 볼 수 있습니다.

A faulty control as red placeholder and the exception details

디버그 기호를 컨트롤에 사용할 수 있는 경우 추적에는 파일 이름과 줄 번호가 있습니다. 스택 추적에서 선을 두 번 클릭하면 소스 코드에서 해당 줄로 이동합니다.

디자이너에서 잘못된 컨트롤을 격리할 수 없는 경우 디자인 화면 맨 위에 경고 메시지가 표시됩니다.

A warning message at the top of the design surface

결함이 있는 컨트롤이 수정되거나 디자인 화면에서 제거되면 전체 렌더링이 다시 시작됩니다.

요약

이 문서에서는 iOS 디자이너에서 사용자 지정 컨트롤을 만들고 적용하는 것을 소개했습니다. 먼저 컨트롤이 디자인 화면에서 렌더링되고 속성 패널에서 사용자 지정 속성을 노출하기 위해 충족해야 하는 요구 사항을 설명했습니다. 그런 다음 뒤에 있는 코드인 컨트롤 및 DesignMode 속성의 초기화를 살펴보았습니다. 마지막으로 예외가 throw될 때 발생하는 작업과 이 문제를 해결하는 방법을 설명했습니다.