다음을 통해 공유


Xamarin.Mac의 .storyboard/.xib-less 사용자 인터페이스 디자인

이 문서에서는 .storyboard 파일, .xib 파일 또는 인터페이스 작성기 없이 C# 코드에서 직접 Xamarin.Mac 애플리케이션의 사용자 인터페이스를 만드는 방법에 대해 설명합니다.

개요

Xamarin.Mac 애플리케이션에서 C# 및 .NET으로 작업하는 경우 개발자와 Xcode에서 작업하는 것과 동일한 사용자 인터페이스 요소 및 도구에 Objective-C 액세스할 수 있습니다. 일반적으로 Xamarin.Mac 애플리케이션을 만들 때 .storyboard 또는 .xib 파일과 함께 Xcode의 인터페이스 작성기를 사용하여 애플리케이션의 사용자 인터페이스를 만들고 기본.

또한 C# 코드에서 직접 Xamarin.Mac 애플리케이션의 UI 중 일부 또는 전부를 만드는 옵션도 있습니다. 이 문서에서는 C# 코드에서 사용자 인터페이스 및 UI 요소를 만드는 기본 사항을 설명합니다.

Mac용 Visual Studio 코드 편집기

코드를 사용하도록 창 전환

새 Xamarin.Mac Cocoa 애플리케이션을 만들 때 기본적으로 표준 빈 창이 표시됩니다. 이 창은 프로젝트에 자동으로 포함된 Main.storyboard(또는 일반적으로 MainWindow.xib) 파일에 정의됩니다. 여기에는 앱의 기본 보기를 관리하는 ViewController.cs 파일(또는 기존에는 MainWindow.cs 및 MainWindowController.cs 파일)도 포함됩니다.

애플리케이션의 Xibless 창으로 전환하려면 다음을 수행합니다.

  1. 사용을 .storyboard 중지하려는 애플리케이션을 열거나 .xib 파일을 열어 Mac용 Visual Studio 사용자 인터페이스를 정의합니다.

  2. 솔루션 패드에서 Main.storyboard 또는 MainWindow.xib 파일을 마우스 오른쪽 단추로 클릭하고 제거를 선택합니다.

    기본 스토리보드 또는 창 제거

  3. [제거] 대화 상자에서 [삭제] 단추를 클릭하여 프로젝트에서 .storyboard 또는 .xib를 완전히 제거합니다.

    삭제 확인

이제 .storyboard 또는 .xib 파일을 더 이상 사용하지 않으므로 MainWindow.cs 파일을 수정하여 창의 레이아웃을 정의하고 ViewController.cs 또는 MainWindowController.cs 파일을 수정하여 클래스의 MainWindow 인스턴스를 만들어야 합니다.

사용자 인터페이스에 Storyboard를 사용하는 최신 Xamarin.Mac 앱에는 MainWindow.cs, ViewController.cs 또는 MainWindowController.cs 파일이 자동으로 포함되지 않을 수 있습니다. 필요에 따라 프로젝트에 새 빈 C# 클래스를 추가하기만 하면 됩니다(새 파일 추가...>>일반>빈 클래스)를 지정하고 누락된 파일과 동일한 이름을 지정합니다.

코드에서 창 정의

다음으로, MainWindow.cs 파일을 편집하고 다음과 같이 표시합니다.

using System;
using Foundation;
using AppKit;
using CoreGraphics;

namespace MacXibless
{
    public partial class MainWindow : NSWindow
    {
        #region Private Variables
        private int NumberOfTimesClicked = 0;
        #endregion

        #region Computed Properties
        public NSButton ClickMeButton { get; set;}
        public NSTextField ClickMeLabel { get ; set;}
        #endregion

        #region Constructors
        public MainWindow (IntPtr handle) : base (handle)
        {
        }

        [Export ("initWithCoder:")]
        public MainWindow (NSCoder coder) : base (coder)
        {
        }

        public MainWindow(CGRect contentRect, NSWindowStyle aStyle, NSBackingStore bufferingType, bool deferCreation): base (contentRect, aStyle,bufferingType,deferCreation) {
            // Define the user interface of the window here
            Title = "Window From Code";

            // Create the content view for the window and make it fill the window
            ContentView = new NSView (Frame);

            // Add UI elements to window
            ClickMeButton = new NSButton (new CGRect (10, Frame.Height-70, 100, 30)){
                AutoresizingMask = NSViewResizingMask.MinYMargin
            };
            ContentView.AddSubview (ClickMeButton);

            ClickMeLabel = new NSTextField (new CGRect (120, Frame.Height - 65, Frame.Width - 130, 20)) {
                BackgroundColor = NSColor.Clear,
                TextColor = NSColor.Black,
                Editable = false,
                Bezeled = false,
                AutoresizingMask = NSViewResizingMask.WidthSizable | NSViewResizingMask.MinYMargin,
                StringValue = "Button has not been clicked yet."
            };
            ContentView.AddSubview (ClickMeLabel);
        }
        #endregion

        #region Override Methods
        public override void AwakeFromNib ()
        {
            base.AwakeFromNib ();

            // Wireup events
            ClickMeButton.Activated += (sender, e) => {
                // Update count
                ClickMeLabel.StringValue = (++NumberOfTimesClicked == 1) ? "Button clicked one time." : string.Format("Button clicked {0} times.",NumberOfTimesClicked);
            };
        }
        #endregion

    }
}

몇 가지 주요 요소에 대해 살펴보겠습니다.

먼저 창이 .storyboard 또는 .xib 파일에 만들어진 것처럼 콘센트처럼 작동하는 몇 가지 계산 속성을 추가했습니다.

public NSButton ClickMeButton { get; set;}
public NSTextField ClickMeLabel { get ; set;}

이렇게 하면 창에 표시할 UI 요소에 액세스할 수 있습니다. 창이 .storyboard 또는 .xib 파일에서 확장되지 않으므로 인스턴스화하는 방법이 필요합니다(클래스의 뒷부분에서 MainWindowController 볼 수 있듯이). 이 새 생성자 메서드가 수행하는 작업은 다음과 같습니다.

public MainWindow(CGRect contentRect, NSWindowStyle aStyle, NSBackingStore bufferingType, bool deferCreation): base (contentRect, aStyle,bufferingType,deferCreation) {
    ...
}

여기서는 창의 레이아웃을 디자인하고 필요한 사용자 인터페이스를 만드는 데 필요한 UI 요소를 배치합니다. 창에 UI 요소를 추가하려면 요소를 포함하기 위해 콘텐츠 뷰가 필요합니다.

ContentView = new NSView (Frame);

그러면 창이 채워지는 콘텐츠 뷰가 만들어집니다. 이제 창에 첫 번째 UI 요소인 NSButton/>를 추가합니다.

ClickMeButton = new NSButton (new CGRect (10, Frame.Height-70, 100, 30)){
    AutoresizingMask = NSViewResizingMask.MinYMargin
};
ContentView.AddSubview (ClickMeButton);

여기서 유의해야 할 첫 번째 사항은 iOS와 달리 macOS는 수학적 표기법을 사용하여 창 좌표계를 정의한다는 것입니다. 따라서 원점은 창의 왼쪽 아래 모서리에 있으며 값은 오른쪽 및 창의 오른쪽 위 모서리쪽으로 증가합니다. 새 NSButton항목을 만들 때 화면에서 위치와 크기를 정의할 때 이를 고려합니다.

이 속성은 AutoresizingMask = NSViewResizingMask.MinYMargin 창의 크기를 세로로 조정할 때 창 위쪽에서 동일한 위치에 유지되도록 단추를 알려줍니다. (0,0)이 창의 왼쪽 아래에 있기 때문에 이 작업이 필요합니다.

마지막으로, 메서드는 ContentView.AddSubview (ClickMeButton) 애플리케이션이 실행되고 창이 표시될 때 화면에 표시되도록 콘텐츠 뷰에 추가 NSButton 합니다.

다음으로 클릭한 횟수를 표시하는 레이블이 창에 NSButton 추가됩니다.

ClickMeLabel = new NSTextField (new CGRect (120, Frame.Height - 65, Frame.Width - 130, 20)) {
    BackgroundColor = NSColor.Clear,
    TextColor = NSColor.Black,
    Editable = false,
    Bezeled = false,
    AutoresizingMask = NSViewResizingMask.WidthSizable | NSViewResizingMask.MinYMargin,
    StringValue = "Button has not been clicked yet."
};
ContentView.AddSubview (ClickMeLabel);

macOS에는 특정 Label UI 요소가 없으므로 레이블 역할을 하도록 특별히 스타일이 지정되어 편집할 수 없는 NSTextField 요소가 추가되었습니다. 이전 단추와 마찬가지로 크기 및 위치는 (0,0)이 창의 왼쪽 아래에 있음을 고려합니다. 속성은 AutoresizingMask = NSViewResizingMask.WidthSizable | NSViewResizingMask.MinYMargin 또는 연산자를 사용하여 두 가지 NSViewResizingMask 기능을 결합합니다. 이렇게 하면 창의 크기가 세로로 조정되고 창의 너비가 가로로 조정될 때 레이블이 창 위쪽에서 동일한 위치에 유지됩니다.

다시 말하지만, 이 메서드는 ContentView.AddSubview (ClickMeLabel) 애플리케이션이 실행되고 창이 열릴 때 화면에 표시되도록 콘텐츠 뷰에 추가 NSTextField 합니다.

창 컨트롤러 조정

디자인 MainWindow 이 .storyboard 또는 .xib 파일에서 더 이상 로드되지 않으므로 창 컨트롤러를 약간 조정해야 합니다. MainWindowController.cs 파일을 편집하고 다음과 같이 표시합니다.

using System;

using Foundation;
using AppKit;
using CoreGraphics;

namespace MacXibless
{
    public partial class MainWindowController : NSWindowController
    {
        public MainWindowController (IntPtr handle) : base (handle)
        {
        }

        [Export ("initWithCoder:")]
        public MainWindowController (NSCoder coder) : base (coder)
        {
        }

        public MainWindowController () : base ("MainWindow")
        {
            // Construct the window from code here
            CGRect contentRect = new CGRect (0, 0, 1000, 500);
            base.Window = new MainWindow(contentRect, (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable), NSBackingStore.Buffered, false);

            // Simulate Awaking from Nib
            Window.AwakeFromNib ();
        }

        public override void AwakeFromNib ()
        {
            base.AwakeFromNib ();
        }

        public new MainWindow Window {
            get { return (MainWindow)base.Window; }
        }
    }
}

이 수정의 핵심 요소에 대해 설명해 보겠습니다.

먼저 클래스의 새 인스턴스를 MainWindow 정의하고 기본 창 컨트롤러의 Window 속성에 할당합니다.

CGRect contentRect = new CGRect (0, 0, 1000, 500);
base.Window = new MainWindow(contentRect, (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable), NSBackingStore.Buffered, false);

을 사용하여 화면 창의 위치를 정의합니다 CGRect. 창의 좌표계와 마찬가지로 화면은 왼쪽 아래 모서리로 (0,0)을 정의합니다. 다음으로 Or 연산자를 사용하여 두 개 이상의 NSWindowStyle 기능을 결합하여 창의 스타일을 정의합니다.

... (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable) ...

사용할 수 있는 기능은 다음과 같습니다 NSWindowStyle .

  • 테두리 없음 - 창에 테두리가 없습니다.
  • 제목 - 창에 제목 표시줄이 있습니다.
  • 복제 가능 - 창에 닫기 단추가 있으며 닫을 수 있습니다.
  • 미니어처화 가능 - 창에 미니어처화 단추가 있으며 최소화할 수 있습니다.
  • 크기 조정 가능 - 창에 크기 조정 단추가 있고 크기를 조정할 수 있습니다.
  • 유틸리티 - 창이 유틸리티 스타일 창(패널)입니다.
  • DocModal - 창이 패널인 경우 시스템 모달 대신 문서 모달이 됩니다.
  • NonactivatingPanel - 창이 패널인 경우 기본 창이 되지 않습니다.
  • TexturedBackground - 창에 질감이 있는 배경이 있습니다.
  • 크기 조정 되지 않음 - 창의 크기가 조정되지 않습니다.
  • UnifiedTitleAndToolbar - 창의 제목 및 도구 모음 영역이 조인됩니다.
  • Hud - 창이 헤드업 디스플레이 패널로 표시됩니다.
  • FullScreenWindow - 창이 전체 화면 모드로 전환될 수 있습니다.
  • FullSizeContentView - 창의 콘텐츠 보기가 제목 및 도구 모음 영역 뒤에 있습니다.

마지막 두 속성은 창에 대한 버퍼링 형식 을 정의하고 창 그리기를 지연할 경우 자세한 NSWindows내용은 Apple의 Windows 소개 설명서를 참조하세요.

마지막으로 창이 .storyboard 또는 .xib 파일에서 확장되지 않으므로 windows AwakeFromNib 메서드를 호출하여 MainWindowController.cs 시뮬레이션해야 합니다.

Window.AwakeFromNib ();

이렇게 하면 .storyboard 또는 .xib 파일에서 로드된 표준 창과 마찬가지로 창에 대해 코딩할 수 있습니다.

창 표시

.storyboard 또는 .xib 파일이 제거되고 MainWindow.csMainWindowController.cs 파일이 수정되면 Xcode의 인터페이스 작성기에서 .xib 파일을 사용하여 만든 일반 창과 마찬가지로 창을 사용할 수 있습니다.

다음은 창 및 해당 컨트롤러의 새 인스턴스를 만들고 화면에 창을 표시합니다.

private MainWindowController mainWindowController;
...

mainWindowController = new MainWindowController ();
mainWindowController.Window.MakeKeyAndOrderFront (this);

이때 애플리케이션이 실행되고 단추가 몇 번 클릭하면 다음이 표시됩니다.

앱 실행 예제

코드 전용 창 추가

기존 Xamarin.Mac 애플리케이션에 코드 전용 xibless 창을 추가하려면 Solution Pad에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 새 파일 추가>를 선택합니다. 새 파일 대화 상자에서 아래 그림과 같이 컨트롤러가 있는 Xamarin.Mac>Cocoa 창을 선택합니다.

새 창 컨트롤러 추가

이전과 마찬가지로 프로젝트에서 기본 .storyboard 또는 .xib 파일을 삭제하고(이 경우 SecondWindow.xib) 창 전환의 단계에 따라 위의 코드 섹션을 사용하여 창의 정의를 코드로 다룹니다.

코드의 창에 UI 요소 추가

창이 코드에서 만들어졌거나 .storyboard 또는 .xib 파일에서 로드되었든 간에 코드에서 창에 UI 요소를 추가하려는 경우가 있을 수 있습니다. 예시:

var ClickMeButton = new NSButton (new CGRect (10, 10, 100, 30)){
    AutoresizingMask = NSViewResizingMask.MinYMargin
};
MyWindow.ContentView.AddSubview (ClickMeButton);

위의 코드는 새 NSButton 코드를 만들고 표시를 위해 MyWindow 창 인스턴스에 추가합니다. 기본적으로 .storyboard 또는 .xib 파일의 Xcode 인터페이스 작성기에서 정의할 수 있는 모든 UI 요소를 코드에서 만들고 창에 표시할 수 있습니다.

코드에서 메뉴 모음 정의

Xamarin.Mac의 현재 제한 사항으로 인해 Xamarin.Mac 애플리케이션의 메뉴 모음을NSMenuBar 코드로 만들지만 Main.storyboard 또는 MainMenu.xib 파일을 계속 사용하여 정의하는 것이 좋습니다. 즉, C# 코드에서 메뉴 및 메뉴 항목을 추가 및 제거할 수 있습니다.

예를 들어 AppDelegate.cs 파일을 편집하고 메서드를 DidFinishLaunching 다음과 같이 만듭니다.

public override void DidFinishLaunching (NSNotification notification)
{
    mainWindowController = new MainWindowController ();
    mainWindowController.Window.MakeKeyAndOrderFront (this);

    // Create a Status Bar Menu
    NSStatusBar statusBar = NSStatusBar.SystemStatusBar;

    var item = statusBar.CreateStatusItem (NSStatusItemLength.Variable);
    item.Title = "Phrases";
    item.HighlightMode = true;
    item.Menu = new NSMenu ("Phrases");

    var address = new NSMenuItem ("Address");
    address.Activated += (sender, e) => {
        Console.WriteLine("Address Selected");
    };
    item.Menu.AddItem (address);

    var date = new NSMenuItem ("Date");
    date.Activated += (sender, e) => {
        Console.WriteLine("Date Selected");
    };
    item.Menu.AddItem (date);

    var greeting = new NSMenuItem ("Greeting");
    greeting.Activated += (sender, e) => {
        Console.WriteLine("Greetings Selected");
    };
    item.Menu.AddItem (greeting);

    var signature = new NSMenuItem ("Signature");
    signature.Activated += (sender, e) => {
        Console.WriteLine("Signature Selected");
    };
    item.Menu.AddItem (signature);
}

위의 코드에서 상태 표시줄 메뉴를 만들고 애플리케이션이 시작될 때 표시합니다. 메뉴 작업에 대한 자세한 내용은 메뉴 설명서를 참조하세요.

요약

이 문서에서는 .storyboard 또는 .xib 파일과 함께 Xcode의 인터페이스 작성기를 사용하는 대신 C# 코드에서 Xamarin.Mac 애플리케이션의 사용자 인터페이스를 만드는 방법을 자세히 살펴보았습니다.