Xamarin.Mac의 Windows

이 문서에서는 Xamarin.Mac 애플리케이션의 창 및 패널 작업에 대해 설명합니다. Xcode 및 Interface Builder에서 창과 패널을 만들고, 스토리보드 및 .xib 파일에서 로드하고, 프로그래밍 방식으로 작업하는 방법을 설명합니다.

Xamarin.Mac 애플리케이션에서 C# 및 .NET으로 작업할 때 개발자가 작업하고 Xcode에서 수행하는 것과 동일한 Windows 및 패널에 Objective-C 액세스할 수 있습니다. Xamarin.Mac은 Xcode와 직접 통합되므로 Xcode의 인터페이스 작성기를 사용하여 Windows 및 패널을 만들고 유지 관리하거나 필요에 따라 C# 코드로 직접 만들 수 있습니다.

그 목적에 따라 Xamarin.Mac 애플리케이션은 화면에 하나 이상의 Windows 표시하고 사용하는 정보를 관리하고 조정할 수 있습니다. 창의 주 함수는 다음과 같습니다.

  1. 보기 및 컨트롤을 배치하고 관리할 수 있는 영역을 제공합니다.
  2. 키보드와 마우스의 사용자 상호 작용에 대한 응답으로 이벤트를 수락하고 응답합니다.

Windows 모덜리스 상태(예: 여러 문서를 한 번에 열 수 있는 텍스트 편집기) 또는 모달(예: 애플리케이션을 계속하기 전에 해제해야 하는 내보내기 대화 상자)에서 사용할 수 있습니다.

패널은 특수한 종류의 Window(기본 NSWindow 클래스의 하위 클래스)로, 일반적으로 텍스트 형식 검사기 및 시스템 색 선택기와 같은 유틸리티 창과 같은 애플리케이션의 보조 함수를 제공합니다.

Editing a window in Xcode

이 문서에서는 Xamarin.Mac 애플리케이션의 Windows 및 패널 작업에 대한 기본 사항을 설명합니다. 이 문서에서 사용할 주요 개념과 기술을 다루므로 Hello, Mac 문서, 특히 Xcode 및 인터페이스 작성기 소개 및 콘센트 및 작업 섹션을 통해 작업하는 것이 좋습니다.

Xamarin.Mac Internals 문서의 섹션에 Objective-C대한 C# 클래스/메서드 노출을 살펴보고, Register C# 클래스 Objective-C 를 개체 및 UI 요소에 연결하는 데 사용되는 명령과 Export 설명합니다.

창 소개

위에서 설명한 대로 창은 보기 및 컨트롤을 배치하고 관리할 수 있는 영역을 제공하고 사용자 상호 작용(키보드 또는 마우스를 통해)에 따라 이벤트에 응답합니다.

Apple에 따르면 macOS 앱에는 다음과 같은 5가지 주요 유형의 Windows 있습니다.

  • 문서 창 - 문서 창에는 스프레드시트 또는 텍스트 문서와 같은 파일 기반 사용자 데이터가 포함됩니다.
  • 앱 창 - 앱 창은 문서 기반이 아닌 애플리케이션의 주 창입니다(예: Mac의 일정 앱).
  • 패널 - 패널이 다른 창 위에 떠 있으며 문서가 열려 있는 동안 사용자가 작업할 수 있는 도구 또는 컨트롤을 제공합니다. 경우에 따라 패널이 반투명할 수 있습니다(예: 대형 그래픽으로 작업할 때).
  • 대화 상자 - 대화 상자는 사용자 작업에 대한 응답으로 표시되며 일반적으로 사용자가 작업을 완료할 수 있는 방법을 제공합니다. 대화 상자를 닫기 전에 사용자의 응답이 필요합니다. ( 대화 상자 작업 참조)
  • 경고 - 경고는 심각한 문제(예: 오류) 또는 경고(예: 파일 삭제 준비)가 발생할 때 나타나는 특별한 유형의 대화 상자입니다. 경고는 대화 상자이므로 닫기 전에 사용자 응답도 필요합니다. ( 경고 작업 참조)

자세한 내용은 Apple macOS 디자인 테마정보 Windows 섹션을 참조하세요.

기본, 키 및 비활성 창

Xamarin.Mac 애플리케이션의 Windows 사용자가 현재 상호 작용하는 방식에 따라 다르게 보이고 동작할 수 있습니다. 현재 사용자의 관심에 초점을 맞춘 가장 중요한 문서 또는 앱 창을 주 창이라고 합니다. 대부분의 경우 이 창은 키 창 (현재 사용자 입력을 허용하는 창)이기도 합니다. 그러나 항상 그런 것은 아닙니다. 예를 들어 색 선택기를 열고 사용자가 문서 창에서 항목의 상태를 변경하기 위해 상호 작용하는 키 창이 될 수 있습니다(주 창임).

Main 및 Key Windows(별도의 경우)는 항상 활성화되어 있으며 비활성 Windows 포그라운드에 없는 열린 창입니다. 예를 들어 텍스트 편집기 애플리케이션은 한 번에 두 개 이상의 문서를 열 수 있고 주 창만 활성화되고 다른 모든 문서는 비활성 상태가 될 수 있습니다.

자세한 내용은 Apple macOS 디자인 테마정보 Windows 섹션을 참조하세요.

창 이름 지정

창은 제목 표시줄을 표시할 수 있으며 제목이 표시되면 일반적으로 응용 프로그램의 이름, 작업 중인 문서의 이름 또는 창의 기능(예: 검사기)입니다. 일부 애플리케이션은 시야에서 인식할 수 있고 문서로 작동하지 않기 때문에 제목 표시줄을 표시하지 않습니다.

Apple은 다음 지침을 제안합니다.

  • 기본 문서가 아닌 창의 제목에 애플리케이션 이름을 사용합니다.
  • 새 문서 창의 이름을 지정합니다 untitled. 첫 번째 새 문서의 경우 제목(예: untitled 1)에 숫자를 추가하지 마세요. 사용자가 첫 번째 문서를 저장하고 제목을 지정하기 전에 다른 새 문서를 만드는 경우 해당 창 untitled 2등을 untitled 3호출합니다.

자세한 내용은 Apple macOS 디자인 테마명명 Windows 섹션을 참조하세요.

전체 화면 창

macOS에서 애플리케이션의 창은 응용 프로그램 메뉴 모음(커서를 화면 맨 위로 이동하여 표시할 수 있음)을 포함한 모든 항목을 숨기는 전체 화면으로 이동하여 콘텐츠와의 주의를 산만하게 할 수 있습니다.

Apple은 다음 지침을 제안합니다.

  • 창이 전체 화면으로 이동하는 것이 적합한지 여부를 결정합니다. 간단한 상호 작용(예: 계산기)을 제공하는 애플리케이션은 전체 화면 모드를 제공하지 않아야 합니다.
  • 전체 화면 작업에 필요한 경우 도구 모음을 표시합니다. 일반적으로 도구 모음은 전체 화면 모드에서 숨겨집니다.
  • 전체 화면 창에는 사용자가 작업을 완료하는 데 필요한 모든 기능이 있어야 합니다.
  • 가능하면 사용자가 전체 화면 창에 있는 동안 Finder 상호 작용을 방지합니다.
  • 주 작업에서 포커스를 이동하지 않고도 화면 공간을 늘릴 수 있습니다.

자세한 내용은 Apple macOS 디자인 테마전체 화면 Windows 섹션을 참조하세요.

패널

패널은 현재 문서 또는 선택 영역(예: 시스템 색 선택기)에 영향을 주는 컨트롤과 옵션을 포함하는 보조 창입니다.

A color panel

패널은 앱별 또는 시스템 전체일 수 있습니다. App-Specific 패널은 애플리케이션의 문서 창 위쪽에 떠 있고 애플리케이션이 백그라운드에 있을 때 사라집니다. 시스템 전체 패널(예: 글꼴 패널)은 응용 프로그램에 관계없이 열려 있는 모든 창 위에 떠 있습니다.

Apple은 다음 지침을 제안합니다.

  • 일반적으로 표준 패널을 사용하려면 투명 패널을 그래픽 집약적인 작업에만 사용해야 합니다.
  • 패널을 사용하여 사용자에게 작업에 직접적인 영향을 주는 중요한 컨트롤 또는 정보에 쉽게 액세스할 수 있도록 하는 것이 좋습니다.
  • 필요에 따라 패널을 숨기고 표시합니다.
  • 패널은 항상 제목 표시줄을 포함해야 합니다.
  • 패널에는 활성 최소화 단추가 포함되어서는 안 됩니다.

검사기

대부분의 최신 macOS 애플리케이션은 패널 Windows 사용하는 대신 기본 창의 일부인 검사기(예: 아래 표시된 페이지 앱)로 현재 문서 또는 선택에 영향을 주는 보조 컨트롤 및 옵션을 제공합니다.

An example inspector

자세한 내용은 Apple macOS 디자인 테마패널 섹션과 MacInspector 샘플 앱에서 Xamarin.Mac 앱에서 검사기 인터페이스의 전체 구현을 참조하세요.

Xcode에서 창 만들기 및 유지 관리

새 Xamarin.Mac Cocoa 애플리케이션을 만들 때 기본적으로 빈 표준 창이 표시됩니다. 이 창은 프로젝트에 자동으로 포함된 파일에 정의 .storyboard 됩니다. 창 디자인을 편집하려면 솔루션 탐색기 파일을 두 번 클릭합니다Main.storyboard.

Selecting the main storyboard

그러면 Xcode의 인터페이스 작성기에서 창 디자인이 열립니다.

Editing the UI in Xcode

특성 검사기에서 창을 정의하고 제어하는 데 사용할 수 있는 몇 가지 속성이 있습니다.

  • 제목 - 창의 제목 표시줄에 표시되는 텍스트입니다.
  • 자동 저장 - 위치 및 설정이 자동으로 저장될 때 창을 ID로 지정하는 데 사용되는 입니다.
  • 제목 표시줄 - 창에 제목 표시줄이 표시됩니까?
  • 통합 제목 및 도구 모음 - 창에 도구 모음이 포함된 경우 제목 표시줄의 일부여야 합니다.
  • 전체 크기 콘텐츠 보기 - 창의 콘텐츠 영역이 제목 표시줄 아래에 있을 수 있습니다.
  • 그림자 - 창에 그림자가 있나요?
  • 질감 - 질감 창은 효과(예: 진동)를 사용할 수 있으며 신체의 아무 곳이나 끌어서 이동할 수 있습니다.
  • 닫기 - 창에 닫기 단추가 있나요?
  • 최소화 - 창에 최소화 단추가 있나요?
  • 크기 조정 - 창에 크기 조정 컨트롤이 있나요?
  • 도구 모음 단추 - 창에 도구 모음 숨기기/표시 단추가 있나요?
  • 복원 가능 - 창의 위치와 설정이 자동으로 저장되고 복원됩니다.
  • 시작 시 표시 - 파일이 로드될 때 창이 .xib 자동으로 표시되는지 확인합니다.
  • 비활성화 시 숨기기 - 애플리케이션이 백그라운드로 들어갈 때 창이 숨겨집니다.
  • 닫힌 경우 해제 - 창을 닫을 때 메모리에서 제거됩니다.
  • 항상 표시 도구 설명 - 도구 설명이 지속적으로 표시됩니다.
  • 뷰 Loop 다시 계산 - 창을 그리기 전에 뷰 순서를 다시 계산합니다.
  • Spaces, ExposéCycling - 모두 해당 macOS 환경에서 창이 작동하는 방식을 정의합니다.
  • 전체 화면 - 이 창이 전체 화면 모드로 전환할 수 있는지 여부를 결정합니다.
  • 애니메이션 - 창에 사용할 수 있는 애니메이션의 유형을 제어합니다.
  • 모양 - 창의 모양을 제어합니다. 지금은 단 하나의 모양, 아쿠아가있다.

자세한 내용은 Apple의 Windows 소개NSWindow 설명서를 참조하세요.

기본 크기 및 위치 설정

창의 초기 위치를 설정하고 크기를 제어하려면 크기 검사기로 전환합니다.

The default size and location

여기에서 창의 초기 크기를 설정하고, 최소 및 최대 크기를 제공하고, 화면에서 초기 위치를 설정하고, 창 주위의 테두리를 제어할 수 있습니다.

사용자 지정 주 창 컨트롤러 설정

UI 요소를 C# 코드에 노출하는 출선 및 작업을 만들려면 Xamarin.Mac 앱에서 사용자 지정 창 컨트롤러를 사용해야 합니다.

다음을 수행합니다.

  1. Xcode의 인터페이스 작성기에서 앱의 Storyboard를 엽니다.

  2. NSWindowController 디자인 화면에서 선택합니다.

  3. ID 검사기 보기로 전환하고 클래스 이름으로 입력 WindowController 합니다.

    Setting the class name

  4. 변경 내용을 저장하고 동기화할 Mac용 Visual Studio 돌아갑니다.

  5. WindowController.cs 파일은 Mac용 Visual Studio 솔루션 탐색기 Project 추가됩니다.

    Selecting the windows controller

  6. Xcode의 인터페이스 작성기에서 Storyboard를 다시 엽니다.

  7. 파일을 WindowController.h 사용할 수 있습니다.

    Editing the WindowController.h file

UI 요소 추가

창의 내용을 정의하려면 라이브러리 검사 기에서 인터페이스 편집기로 컨트롤을 끌어옵니다. 인터페이스 작성기를 사용하여 컨트롤을 만들고 사용하도록 설정하는 방법에 대한 자세한 내용은 Xcode 및 Interface Builder 소개 설명서를 참조하세요.

예를 들어 라이브러리 검사 기에서 인터페이스 편집기의 창으로 도구 모음을 끌어 보겠습니다.

Selecting a Toolbar from the Library

다음으로 텍스트 뷰 를 끌어서 크기 조정하여 도구 모음 아래 영역을 채웁니다.

Adding a Text View

창의 크기가 변경되면 텍스트 보기 가 축소되고 증가하도록 하므로 제약 조건 편집 기로 전환하고 다음 제약 조건을 추가해 보겠습니다.

Editing constraints

편집기 맨 위에 있는 4개의 빨간색 I-빔 을 클릭하고 4개의 제약 조건 추가를 클릭하여 텍스트 보기에 지정된 X,Y 좌표를 고수하고 창 크기가 조정될 때 가로 및 세로로 확장하거나 축소하도록 알립니다.

마지막으로, 출선(파일을 선택해야 합니다)을 사용하여 텍스트 뷰를 코드에 ViewController.h 노출합니다.

Configuring an outlet

변경 내용을 저장하고 Mac용 Visual Studio 다시 전환하여 Xcode와 동기화합니다.

콘센트작업 작업에 대한 자세한 내용은 콘센트 및 작업 설명서를 참조하세요.

표준 창 워크플로

Xamarin.Mac 애플리케이션에서 만들고 작업하는 모든 창의 프로세스는 기본적으로 위에서 수행한 것과 동일합니다.

  1. 기본값이 아닌 새 창의 경우 프로젝트에 새 창 정의를 추가합니다. 이 내용은 아래에서 자세히 설명합니다.
  2. 파일을 두 번 클릭하여 Main.storyboard Xcode의 인터페이스 작성기에서 편집할 창 디자인을 엽니다.
  3. 새 창을 사용자 인터페이스 디자인으로 끌어와 Segues를 사용하여 창을 주 창에 연결합니다(자세한 내용은 스토리보드 작업 설명서의 Segues 섹션 참조).
  4. 특성 검사기 및 크기 검사기에서 필요한 창 속성을 설정합니다.
  5. 인터페이스를 빌드하는 데 필요한 컨트롤을 끌어 서 특성 검사기에서 구성합니다.
  6. 크기 검사기를 사용하여 UI 요소의 크기 조정을 처리합니다.
  7. 출선작업을 통해 창의 UI 요소를 C# 코드에 노출합니다.
  8. 변경 내용을 저장하고 Mac용 Visual Studio 다시 전환하여 Xcode와 동기화합니다.

이제 기본 창이 만들어졌으므로 Windows로 작업할 때 Xamarin.Mac 애플리케이션이 수행하는 일반적인 프로세스를 살펴보겠습니다.

기본 창 표시

기본적으로 새 Xamarin.Mac 애플리케이션은 시작할 때 파일에 정의된 MainWindow.xib 창을 자동으로 표시합니다.

An example window running

위의 해당 창 디자인을 수정했으므로 이제 기본 도구 모음 및 텍스트 보기 컨트롤이 포함됩니다. 파일의 Info.plist 다음 섹션에서는 이 창을 표시합니다.

Editing Info.plist

기본 인터페이스 드롭다운은 주 앱 UI로 사용할 Storyboard를 선택하는 데 사용됩니다(이 경우Main.storyboard).

뷰 컨트롤러는 기본 보기와 함께 표시되는 기본 Windows 제어하기 위해 프로젝트에 자동으로 추가됩니다. 파일에서 ViewController.cs 정의되고 Id 검사기에서 인터페이스 작성기에서 파일의 소유자에 연결됩니다.

Setting the file's owner

창의 경우 처음 열리는 시점의 untitled 제목을 지정하여 다음과 같이 보이도록 메서드 ViewController.cs 를 재정 ViewWillAppear 의해 보겠습니다.

public override void ViewWillAppear ()
{
    base.ViewWillAppear ();

    // Set Window Title
    this.View.Window.Title = "untitled";
}

참고

뷰가 메모리에 ViewWillAppear 로드될 수 있지만 아직 완전히 인스턴스화되지 않았기 때문에 창의 TitleViewDidLoad 속성은 메서드 대신 메서드에서 설정됩니다. 메서드의 Title 속성에 ViewDidLoad 액세스하면 null 창이 아직 생성되지 않고 속성에 유선으로 연결되지 않았기 때문에 예외가 발생합니다.

프로그래밍 방식으로 창 닫기

사용자가 창의 닫기 단추를 클릭하거나 메뉴 항목을 사용하는 것 외에는 Xamarin.Mac 애플리케이션에서 프로그래밍 방식으로 창을 닫으려는 경우가 있을 수 있습니다. macOS는 프로그래밍 방식으로 PerformCloseCloseNSWindow 는 두 가지 방법을 제공합니다.

PerformClose

메서드를 PerformCloseNSWindow 호출하면 사용자가 잠시 단추를 강조 표시한 다음 창을 닫아 창의 닫기 단추를 클릭하는 것을 시뮬레이션합니다.

애플리케이션이 's WillClose 이벤트를 구현NSWindow하는 경우 창을 닫기 전에 이벤트가 발생합니다. 이벤트가 반환 false되면 창이 닫혀 있지 않습니다. 창에 닫기 단추가 없거나 어떤 이유로든 닫을 수 없는 경우 OS는 경고 소리를 내보낼 것입니다.

예를 들어:

MyWindow.PerformClose(this);

인스턴스를 닫 MyWindowNSWindow 으려고 합니다. 성공하면 창이 닫혀 있고, 그렇지 않으면 경고 소리가 내보내지고 열린 상태로 유지됩니다.

닫기

메서드를 CloseNSWindow 호출해도 사용자가 단추를 잠시 강조 표시하여 창의 닫기 단추를 클릭하는 것을 시뮬레이션하지 않고 단순히 창을 닫습니다.

창을 닫을 수 있도록 표시할 필요가 없으며 NSWindowWillCloseNotification 닫혀 있는 창에 대한 알림이 기본 알림 센터에 게시됩니다.

메서드는 Close 메서드와 두 가지 중요한 방법으로 PerformClose 다릅니다.

  1. 이벤트를 발생 WillClose 시키려고 시도하지 않습니다.
  2. 잠시 단추를 강조 표시하여 닫기 단추를 클릭하는 사용자를 시뮬레이션하지 않습니다.

예를 들어:

MyWindow.Close();

인스턴스를 닫습니다 MyWindowNSWindow .

수정된 창 콘텐츠

macOS에서 Apple은 사용자가 창(NSWindow)의 콘텐츠를 수정하고 저장해야 한다고 사용자에게 알리는 방법을 제공했습니다. 창에 수정된 콘텐츠가 포함된 경우 작은 검은색 점이 닫기 위젯에 표시됩니다.

A window with the modified marker

창의 콘텐츠에 저장되지 않은 변경 내용이 있는 동안 사용자가 창을 닫거나 Mac 앱을 종료하려고 하면 대화 상자 또는 모달 시트 를 표시하고 사용자가 변경 내용을 먼저 저장할 수 있도록 해야 합니다.

A save sheet being shown when the window is closed

창을 수정된 것으로 표시

창을 수정된 콘텐츠로 표시하려면 다음 코드를 사용합니다.

// Mark Window content as modified
Window.DocumentEdited = true;

변경 내용이 저장되면 다음을 사용하여 수정된 플래그를 지웁다.

// Mark Window content as not modified
Window.DocumentEdited = false;

창을 닫기 전에 변경 내용 저장

사용자가 창을 닫고 수정된 콘텐츠를 미리 저장할 수 있도록 하려면 해당 메서드의 서브클래스를 만들고 재정 WindowShouldCloseNSWindowDelegate 해야 합니다. 예를 들어:

using System;
using AppKit;
using System.IO;
using Foundation;

namespace SourceWriter
{
    public class EditorWindowDelegate : NSWindowDelegate
    {
        #region Computed Properties
        public NSWindow Window { get; set;}
        #endregion

        #region constructors
        public EditorWindowDelegate (NSWindow window)
        {
            // Initialize
            this.Window = window;

        }
        #endregion

        #region Override Methods
        public override bool WindowShouldClose (Foundation.NSObject sender)
        {
            // is the window dirty?
            if (Window.DocumentEdited) {
                var alert = new NSAlert () {
                    AlertStyle = NSAlertStyle.Critical,
                    InformativeText = "Save changes to document before closing window?",
                    MessageText = "Save Document",
                };
                alert.AddButton ("Save");
                alert.AddButton ("Lose Changes");
                alert.AddButton ("Cancel");
                var result = alert.RunSheetModal (Window);

                // Take action based on result
                switch (result) {
                case 1000:
                    // Grab controller
                    var viewController = Window.ContentViewController as ViewController;

                    // Already saved?
                    if (Window.RepresentedUrl != null) {
                        var path = Window.RepresentedUrl.Path;

                        // Save changes to file
                        File.WriteAllText (path, viewController.Text);
                        return true;
                    } else {
                        var dlg = new NSSavePanel ();
                        dlg.Title = "Save Document";
                        dlg.BeginSheet (Window, (rslt) => {
                            // File selected?
                            if (rslt == 1) {
                                var path = dlg.Url.Path;
                                File.WriteAllText (path, viewController.Text);
                                Window.DocumentEdited = false;
                                viewController.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
                                viewController.View.Window.RepresentedUrl = dlg.Url;
                                Window.Close();
                            }
                        });
                        return true;
                    }
                    return false;
                case 1001:
                    // Lose Changes
                    return true;
                case 1002:
                    // Cancel
                    return false;
                }
            }

            return true;
        }
        #endregion
    }
}

다음 코드를 사용하여 이 대리자의 인스턴스를 창에 연결합니다.

// Set delegate
Window.Delegate = new EditorWindowDelegate(Window);

앱을 닫기 전에 변경 내용 저장

마지막으로 Xamarin.Mac 앱은 해당 Windows 수정된 콘텐츠가 포함되어 있는지 확인하고 사용자가 종료하기 전에 변경 내용을 저장할 수 있도록 해야 합니다. 이렇게 하려면 파일을 편집 AppDelegate.cs 하고, 메서드를 재정의 ApplicationShouldTerminate 하고, 다음과 같이 표시합니다.

public override NSApplicationTerminateReply ApplicationShouldTerminate (NSApplication sender)
{
    // See if any window needs to be saved first
    foreach (NSWindow window in NSApplication.SharedApplication.Windows) {
        if (window.Delegate != null && !window.Delegate.WindowShouldClose (this)) {
            // Did the window terminate the close?
            return NSApplicationTerminateReply.Cancel;
        }
    }

    // Allow normal termination
    return NSApplicationTerminateReply.Now;
}

여러 창 작업

대부분의 문서 기반 Mac 애플리케이션은 동시에 여러 문서를 편집할 수 있습니다. 예를 들어 텍스트 편집기에서 여러 텍스트 파일을 동시에 편집할 수 있습니다. 기본적으로 새 Xamarin.Mac 애플리케이션에는 항목이 작업에 자동으로 유선으로 연결된 파일 메뉴가 newDocument: 있습니다.

아래 코드는 이 새 항목을 활성화하고 사용자가 주 창의 여러 복사본을 열어 한 번에 여러 문서를 편집할 수 있도록 합니다.

AppDelegate.cs 파일을 편집하고 다음 계산 속성을 추가합니다.

public int UntitledWindowCount { get; set;} =1;

이를 사용하여 저장되지 않은 파일 수를 추적하여 사용자에게 피드백을 제공할 수 있습니다(위에서 설명한 Apple 지침에 따라).

다음으로, 다음 메서드를 추가합니다.

[Export ("newDocument:")]
void NewDocument (NSObject sender) {
    // Get new window
    var storyboard = NSStoryboard.FromName ("Main", null);
    var controller = storyboard.InstantiateControllerWithIdentifier ("MainWindow") as NSWindowController;

    // Display
    controller.ShowWindow(this);

    // Set the title
    controller.Window.Title = (++UntitledWindowCount == 1) ? "untitled" : string.Format ("untitled {0}", UntitledWindowCount);
}

이 코드는 새 버전의 창 컨트롤러를 만들고, 새 창을 로드하고, 기본 및 키 창으로 만들고, 제목을 설정합니다. 이제 애플리케이션을 실행하고 파일 메뉴에서 새로 만들기를 선택하면 새 편집기 창이 열리고 표시됩니다.

A new untitled window was added

Windows 메뉴를 열면 애플리케이션이 열려 있는 창을 자동으로 추적하고 처리하는 것을 볼 수 있습니다.

The windows menu

Xamarin.Mac 애플리케이션에서 메뉴 작업에 대한 자세한 내용은 메뉴 작업 설명서를 참조하세요.

현재 활성 창 가져오기

여러 창(문서)을 열 수 있는 Xamarin.Mac 애플리케이션에서는 현재 맨 위 창(키 창)을 가져와야 하는 경우가 있습니다. 다음 코드는 키 창을 반환합니다.

var window = NSApplication.SharedApplication.KeyWindow;

현재 키 창에 액세스해야 하는 모든 클래스 또는 메서드에서 호출할 수 있습니다. 현재 열려 있는 창이 없으면 반환 null됩니다.

모든 앱 창에 액세스

Xamarin.Mac 앱이 현재 열려 있는 모든 창에 액세스해야 하는 경우가 있을 수 있습니다. 예를 들어 사용자가 열려는 파일이 이미 종료 창에서 열려 있는지 확인합니다.

NSApplication.SharedApplication 에서 열려 있는 Windows 모든 창의 배열을 포함하는 속성을 유지 관리합니다. 이 배열을 반복하여 앱의 모든 현재 창에 액세스할 수 있습니다. 예를 들어:

// Is the file already open?
for(int n=0; n<NSApplication.SharedApplication.Windows.Length; ++n) {
    var content = NSApplication.SharedApplication.Windows[n].ContentViewController as ViewController;
    if (content != null && path == content.FilePath) {
        // Bring window to front
        NSApplication.SharedApplication.Windows[n].MakeKeyAndOrderFront(this);
        return true;
    }
}

예제 코드에서는 반환된 각 창을 앱의 사용자 지정 ViewController 클래스로 캐스팅하고 사용자가 열려는 파일의 경로에 대해 사용자 지정 Path 속성 값을 테스트합니다. 파일이 이미 열려 있는 경우 해당 창을 맨 앞으로 가져옵니다.

코드에서 창 크기 조정

애플리케이션이 코드에서 창의 크기를 조정해야 하는 경우가 있습니다. 창의 크기를 조정하고 위치를 변경하려면 창의 Frame 속성을 조정합니다. 창의 크기를 조정할 때는 일반적으로 macOS의 좌표계 때문에 창을 동일한 위치에 유지하기 위해 창의 원점도 조정해야 합니다.

왼쪽 위 모서리가 (0,0)를 나타내는 iOS와 달리 macOS는 화면의 왼쪽 아래 모서리가 나타내는 수학 좌표계(0,0)를 사용합니다. iOS에서는 오른쪽으로 아래로 이동하면 좌표가 증가합니다. macOS에서 좌표는 오른쪽으로 위쪽으로 값이 증가합니다.

다음 예제 코드는 창의 크기를 조정합니다.

nfloat y = 0;

// Calculate new origin
y = Frame.Y - (768 - Frame.Height);

// Resize and position window
CGRect frame = new CGRect (Frame.X, y, 1024, 768);
SetFrame (frame, true);

중요

코드에서 창 크기와 위치를 조정하는 경우 Interface Builder에서 설정한 최소 및 최대 크기를 준수해야 합니다. 이는 자동으로 적용되지 않으며 창을 이러한 제한보다 크거나 작게 만들 수 있습니다.

모니터링 창 크기 변경

Xamarin.Mac 앱 내에서 창 크기의 변경 내용을 모니터링해야 하는 경우가 있을 수 있습니다. 예를 들어 새 크기에 맞게 콘텐츠를 다시 그리는 경우입니다.

크기 변경을 모니터링하려면 먼저 Xcode의 인터페이스 작성기에서 창 컨트롤러에 대한 사용자 지정 클래스를 할당해야 합니다. 예를 들어 MasterWindowController 다음을 참조하세요.

The Identity Inspector

다음으로, 사용자 지정 Window 컨트롤러 클래스를 DidResize 편집하고 컨트롤러의 창에서 이벤트를 모니터링하여 라이브 크기 변경에 대한 알림을 받습니다. 예를 들어:

public override void WindowDidLoad ()
{
    base.WindowDidLoad ();

    Window.DidResize += (sender, e) => {
        // Do something as the window is being live resized
    };
}

필요에 따라 사용자가 창의 크기 변경을 완료한 후에만 이벤트를 사용하여 DidEndLiveResize 알림을 받을 수 있습니다. 예를 들면 다음과 같습니다.

public override void WindowDidLoad ()
{
    base.WindowDidLoad ();

        Window.DidEndLiveResize += (sender, e) => {
        // Do something after the user's finished resizing
        // the window
    };
}

창의 제목 및 표현된 파일 설정

문서를 NSWindowDocumentEdited 나타내는 창으로 작업할 때 닫기 단추에 작은 점을 표시하도록 true 설정하면 파일이 수정되었으며 닫히기 전에 저장되어야 한다는 표시를 사용자에게 제공하는 속성이 있습니다.

파일을 편집 ViewController.cs 하고 다음과 같이 변경해 보겠습니다.

public bool DocumentEdited {
    get { return View.Window.DocumentEdited; }
    set { View.Window.DocumentEdited = value; }
}
...

public override void ViewWillAppear ()
{
    base.ViewWillAppear ();

    // Set Window Title
    this.View.Window.Title = "untitled";

    View.Window.WillClose += (sender, e) => {
        // is the window dirty?
        if (DocumentEdited) {
            var alert = new NSAlert () {
                AlertStyle = NSAlertStyle.Critical,
                InformativeText = "We need to give the user the ability to save the document here...",
                MessageText = "Save Document",
            };
            alert.RunModal ();
        }
    };
}

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

    // Show when the document is edited
    DocumentEditor.TextDidChange += (sender, e) => {
        // Mark the document as dirty
        DocumentEdited = true;
    };

    // Overriding this delegate is required to monitor the TextDidChange event
    DocumentEditor.ShouldChangeTextInRanges += (NSTextView view, NSValue[] values, string[] replacements) => {
        return true;
    };

}

또한 창에서 WillClose 이벤트를 모니터링하고 속성의 상태를 확인합니다 DocumentEdited . true 이 경우 변경 내용을 파일에 저장할 수 있는 기능을 사용자에게 제공해야 합니다. 앱을 실행하고 텍스트를 입력하면 점이 표시됩니다.

A changed window

창을 닫으려면 다음과 같은 경고가 표시됩니다.

Displaying a save dialog

파일에서 문서를 로드하는 경우 열려 있는 파일을 나타내는 문자열인 경우 메서드 path 를 사용하여 window.SetTitleWithRepresentedFilename (Path.GetFileName(path)); 창의 제목을 파일 이름으로 설정합니다. 또한 메서드를 사용하여 파일의 URL을 window.RepresentedUrl = url; 설정할 수 있습니다.

URL이 OS에서 알려진 파일 형식을 가리키는 경우 해당 아이콘이 제목 표시줄에 표시됩니다. 사용자가 아이콘을 마우스 오른쪽 단추로 클릭하면 파일 경로가 표시됩니다.

AppDelegate.cs 파일을 편집하고 다음 메서드를 추가합니다.

[Export ("openDocument:")]
void OpenDialog (NSObject sender)
{
    var dlg = NSOpenPanel.OpenPanel;
    dlg.CanChooseFiles = true;
    dlg.CanChooseDirectories = false;

    if (dlg.RunModal () == 1) {
        // Nab the first file
        var url = dlg.Urls [0];

        if (url != null) {
            var path = url.Path;

            // Get new window
            var storyboard = NSStoryboard.FromName ("Main", null);
            var controller = storyboard.InstantiateControllerWithIdentifier ("MainWindow") as NSWindowController;

            // Display
            controller.ShowWindow(this);

            // Load the text into the window
            var viewController = controller.Window.ContentViewController as ViewController;
            viewController.Text = File.ReadAllText(path);
                    viewController.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
            viewController.View.Window.RepresentedUrl = url;

        }
    }
}

이제 앱을 실행하면 [파일] 메뉴에서 [열기...]를 선택하고 [대화 상자 열기]에서 텍스트 파일을 선택하고 엽니다.

An open dialog box

파일이 표시되고 파일의 아이콘으로 제목이 설정됩니다.

The contents of a file loaded

프로젝트에 새 창 추가

주 문서 창 외에도 Xamarin.Mac 애플리케이션은 기본 설정 또는 검사기 패널과 같은 다른 유형의 창을 사용자에게 표시해야 할 수 있습니다.

새 창을 추가하려면 다음을 수행합니다.

  1. 솔루션 탐색기 파일을 두 번 클릭하여 Main.storyboard Xcode의 인터페이스 작성기에서 편집할 수 있도록 엽니다.

  2. 라이브러리에서 새 창 컨트롤러를 끌어 디자인 화면에 놓습니다.

    Selecting a new Window Controller in the Library

  3. ID 검사기에서 스토리보드 ID를 입력 PreferencesWindow 합니다.

    Setting the storyboard ID

  4. 인터페이스를 디자인합니다.

    Designing the UI

  5. 앱 메뉴()MacWindows를 열고 기본 설정을 선택하고 Control-Click 새 창으로 끕니다.

    Creating a segue

  6. 팝업 메뉴에서 표시 를 선택합니다.

  7. 변경 내용을 저장하고 Mac용 Visual Studio 돌아가 Xcode와 동기화합니다.

코드를 실행하고 애플리케이션 메뉴에서기본 설정을 선택하면 창이 표시됩니다.

A sample preferences menu

패널 사용

이 문서의 시작 부분에 설명된 것처럼 패널은 다른 창 위에 떠 있으며 문서가 열려 있는 동안 사용자가 작업할 수 있는 도구 또는 컨트롤을 제공합니다.

Xamarin.Mac 애플리케이션에서 만들고 작업하는 다른 유형의 창과 마찬가지로 프로세스는 기본적으로 동일합니다.

  1. 프로젝트에 새 창 정의를 추가합니다.
  2. 파일을 두 번 클릭하여 .xib Xcode의 인터페이스 작성기에서 편집할 창 디자인을 엽니다.
  3. 특성 검사기 및 크기 검사기에서 필요한 창 속성을 설정합니다.
  4. 인터페이스를 빌드하는 데 필요한 컨트롤을 끌어 서 특성 검사기에서 구성합니다.
  5. 크기 검사기를 사용하여 UI 요소의 크기 조정을 처리합니다.
  6. 출선작업을 통해 창의 UI 요소를 C# 코드에 노출합니다.
  7. 변경 내용을 저장하고 Mac용 Visual Studio 다시 전환하여 Xcode와 동기화합니다.

특성 검사기에서 패널과 관련된 다음 옵션이 있습니다.

The Attribute Inspector

  • 스타일 - 일반 패널(표준 창처럼 표시됨), 유틸리티 패널(작은 제목 표시줄 포함), HUD 패널(반투명하고 제목 표시줄이 배경의 일부임)에서 패널 스타일을 조정할 수 있습니다.
  • 정품 인증 없음 - 패널에서 확인이 키 창이 됩니다.
  • 문서 모달 - 문서 모달인 경우 패널은 애플리케이션의 창 위에만 떠있고, 그렇지 않으면 무엇보다도 떠 있습니다.

새 패널을 추가하려면 다음을 수행합니다.

  1. 솔루션 탐색기 Project 마우스 오른쪽 단추로 클릭하고 AddNew>파일...을 선택합니다.

  2. 새 파일 대화 상자에서 컨트롤러가 있는 Xamarin.MacCocoa>창을 선택합니다.

    Adding a new window controller

  3. 이름에 대해 DocumentPanel를 입력하고 새로 만들기 단추를 클릭합니다.

  4. 인터페이스 작성기 DocumentPanel.xib 에서 편집할 수 있도록 파일을 두 번 클릭하여 엽니다.

    Editing the panel

  5. 기존 창을 삭제하고 인터페이스 편집기의 라이브러리 검사기에서 패널을 끕니다.

    Deleting the existing window

  6. 패널을 파일의OwnerwindowOutlet - - 에 연결합니다.

    Dragging to wire up the panel

  7. ID 검사기로 전환하고 패널의 클래스를 다음으로 DocumentPanel설정합니다.

    Setting the panel's class

  8. 변경 내용을 저장하고 Mac용 Visual Studio 돌아가 Xcode와 동기화합니다.

  9. DocumentPanel.cs 파일을 편집하고 클래스 정의를 다음으로 변경합니다.

    public partial class DocumentPanel : NSPanel

  10. 변경 내용을 파일에 저장합니다.

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

public override void DidFinishLaunching (NSNotification notification)
{
        // Display panel
    var panel = new DocumentPanelController ();
    panel.Window.MakeKeyAndOrderFront (this);
}

애플리케이션을 실행하면 패널이 표시됩니다.

The panel in a running app

중요

패널 Windows Apple에서 더 이상 사용되지 않으며 Inspector 인터페이스로 대체되어야 합니다. Xamarin.Mac 앱에서 검사 기를 만드는 전체 예제는 MacInspector 샘플 앱을 참조하세요.

요약

이 문서에서는 Xamarin.Mac 애플리케이션에서 Windows 및 패널을 사용하는 방법을 자세히 살펴보았습니다. Windows 및 패널의 다양한 형식과 사용, Xcode의 Interface Builder에서 Windows 및 패널을 만들고 유지 관리하는 방법 및 C# 코드에서 Windows 및 패널을 사용하는 방법을 알아보았습니다.