Создание современных приложений macOSBuilding Modern macOS Apps

В этой статье рассматривается несколько советов, возможности и методы, разработчик может использовать для создания приложения на основе современных macOS в Xamarin.Mac.This article covers several tips, features and techniques a developer can use to build a modern macOS app in Xamarin.Mac.

Создание современных выглядит с помощью современных представленийBuilding Modern Looks with Modern Views

Современный интерфейс будет включать более современных вид окна и панели инструментов такие как пример приложения, показано ниже:A modern look will include a modern Window and Toolbar appearance such as the example app shown below:

Включение полного размера содержимого представленияEnabling Full Sized Content Views

Чтобы добиться этого выглядит в приложении Xamarin.Mac, разработчику потребуется использовать полный размер содержимого представления, то есть содержимое распространяется в области заголовка окна и средства и будет автоматически размыто с macOS.To achieve this looks in a Xamarin.Mac app, the developer will want to use a Full Size Content View, meaning the content extends under the Tool and Title Bar areas and will be automatically blurred by macOS.

Чтобы включить эту функцию в коде, создайте пользовательский класс для NSWindowController и это должно выглядеть следующим образом:To enable this feature in code, create a custom class for the NSWindowController and make it look like the following:

using System;
using Foundation;
using AppKit;

namespace MacModern
{
    public partial class MainWindowController : NSWindowController
    {
        #region Constructor
        public MainWindowController (IntPtr handle) : base (handle)
        {
        }
        #endregion

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

            // Set window to use Full Size Content View
            Window.StyleMask = NSWindowStyle.FullSizeContentView;
        }
        #endregion
    }
}

Также можно включить эту функцию в Interface Builder в Xcode, выбрав окна и проверка полного размера представления содержимого:This feature can also be enabled in Xcode's Interface Builder by selecting the Window and checking Full Sized Content View:

При использовании полный размер представления содержимого, разработчик может потребоваться смещение содержимое под области панель заголовка и средства, чтобы определенное содержимое (например, метки) не слайд в них.When using a Full Size Content View, the developer may need to offset the content beneath the title and tool bar areas so that specific content (such as labels) doesn't slide under them.

Усложняет эту проблему, области заголовка и панели инструментов можно иметь динамические высоту на основе действия, в которой он выполняется, версия macOS пользователь установил и/или оборудования Mac, на котором приложение выполняется на.To complicate this issue, the Title and Tool Bar areas can have a dynamic height based on the action that the user is currently performing, the version of macOS the user has installed and/or the Mac hardware that the app is running on.

Таким образом просто жесткого кодирования смещение, при создании макетов пользовательский интерфейс не будет работать.As a result, simply hard coding the offset when laying out the User Interface will not work. Разработчику необходимо динамического подхода.The developer will need to take a dynamic approach.

Включает в себя Apple ключ-значение наблюдаемый ContentLayoutRect свойство NSWindow класса для получения текущей области содержимого в коде.Apple has included the Key-Value Observable ContentLayoutRect property of the NSWindow class to get the current Content Area in code. Разработчик может использовать это значение, чтобы вручную изменить расположение необходимых элементов при изменении области содержимого.The developer can use this value to manually position the required elements when the Content Area changes.

Лучшее решение — использовать автоматический макет и классы размера для размещения элементов пользовательского интерфейса в код или конструктор Interface Builder.The better solution is to use Auto Layout and Size Classes to position the UI elements in either code or Interface Builder.

Код, как в следующем примере, может использоваться для размещения элементов пользовательского интерфейса, с помощью Автомакет и размер классов в контроллер представления приложения:Code like the following example can be used to position UI elements using AutoLayout and Size Classes in the app's View Controller:

using System;
using AppKit;
using Foundation;

namespace MacModern
{
    public partial class ViewController : NSViewController
    {
        #region Computed Properties
        public NSLayoutConstraint topConstraint { get; set; }
        #endregion

        ...

        #region Override Methods
        public override void UpdateViewConstraints ()
        {
            // Has the constraint already been set?
            if (topConstraint == null) {
                // Get the top anchor point
                var contentLayoutGuide = ItemTitle.Window?.ContentLayoutGuide as NSLayoutGuide;
                var topAnchor = contentLayoutGuide.TopAnchor;

                // Found?
                if (topAnchor != null) {
                    // Assemble constraint and activate it
                    topConstraint = topAnchor.ConstraintEqualToAnchor (topAnchor, 20);
                    topConstraint.Active = true;
                }
            }

            base.UpdateViewConstraints ();
        }
        #endregion
    }
}

Этот код создает хранилище для верхнего ограничения, которые применяются к метке (ItemTitle) чтобы убедиться, что он не сдвигаться в области заголовка и панели инструментов:This code creates storage for a top constraint that will be applied to a Label (ItemTitle) to ensure that it doesn't slip under the Title and Tool Bar area:

public NSLayoutConstraint topConstraint { get; set; }

Путем переопределения контроллер представления UpdateViewConstraints метод, разработчик может проверить, если необходимые ограничения уже собран и создать его при необходимости.By overriding the View Controller's UpdateViewConstraints method, the developer can test to see if the needed constraint has already been built and create it if needed.

Если новое ограничение должен быть построен, ContentLayoutGuide свойства окна, элемент управления, который необходимо ограничить доступ и приведен к типу NSLayoutGuide:If a new constraint needs to be built, the ContentLayoutGuide property of the Window the control that needs to be constrained is accessed and cast into a NSLayoutGuide:

var contentLayoutGuide = ItemTitle.Window?.ContentLayoutGuide as NSLayoutGuide;

Свойство TopAnchor NSLayoutGuide доступна и если он доступен, он используется для создания нового ограничения с требуемой суммой смещения и новое ограничение он станет активным, чтобы применить его:The TopAnchor property of the NSLayoutGuide is accessed and if it is available, it is used to build a new constraint with the desired offset amount and the new constraint is made active to apply it:

// Assemble constraint and activate it
topConstraint = topAnchor.ConstraintEqualToAnchor (topAnchor, 20);
topConstraint.Active = true;

Включение упрощенный панелей инструментовEnabling Streamlined Toolbars

Обычный macOS окна включает стандартным строки заголовка в запускается верхнего края окна.A normal macOS Window includes a standard Title Bar at runs along to top edge of the Window. Если окно также включает панель инструментов, он будет отображаться в этой области заголовка:If the Window also includes a Tool Bar, it will be displayed under this Title Bar area:

Когда исчезнет с помощью упрощенной панели инструментов, области заголовка и панели инструментов Перемещение вверх в позицию в строке заголовка, в строки с кнопками окна закрыть, свернуть и развернуть:When using a Streamlined Toolbar, the Title Area disappears and the Tool Bar moves up into the Title Bar's position, in-line with the Window Close, Minimize and Maximize buttons:

Упрощенный панели инструментов включен, переопределив ViewWillAppear метод NSViewController и делая это должно выглядеть следующим образом:The Streamlined Toolbar is enabled by overriding the ViewWillAppear method of the NSViewController and making it look like the following:

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

    // Enable streamlined Toolbars
    View.Window.TitleVisibility = NSWindowTitleVisibility.Hidden;
}

Этот эффект обычно используется для Shoebox приложений (одно окно приложения), такие как карты, календаря, заметок и системные настройки.This effect is typically used for Shoebox Applications (one window apps) like Maps, Calendar, Notes and System Preferences.

С помощью контроллеров представлений периферийных устройствUsing Accessory View Controllers

В зависимости от структуры приложения разработчик может потребоваться дополнить строку заголовка, область с контроллером представления периферийного устройства, отображается справа под областью панель заголовка и инструментов для предоставления контекстной элементы управления на основе действия пользователя они являются настоящее время участвует в:Depending on the design of the app, the developer might also want to complement the Title Bar area with an Accessory View Controller that appears right below the Title/Tool Bar area to provide context sensitive controls to the user based on the activity they are currently engaged in:

Контроллер представления периферийного устройства будут автоматически размыть и размер в системе, не привлекая разработчиков.The Accessory View controller will automatically be blurred and resized by the system without developer intervention.

Чтобы добавить контроллер представления периферийных устройств, сделайте следующее:To add an Accessory View Controller, do the following:

  1. В обозревателе решений дважды щелкните файл Main.storyboard, чтобы открыть его для редактирования.In the Solution Explorer, double-click the Main.storyboard file to open it for editing.

  2. Перетащите контроллер представления Custom в иерархию окна:Drag a Custom View Controller into the Window's hierarchy:

  3. Макета аксессуаров представление пользовательского интерфейса:Layout the Accessory View's UI:

  4. Предоставлять аксессуаров представлении в качестве розетки и любые другие действия или розеток для его пользовательского интерфейса:Expose the Accessory View as an Outlet and any other Actions or Outlets for its UI:

  5. Сохраните изменения.Save the changes.

  6. Вернитесь к Visual Studio для Mac синхронизировать изменения.Return to Visual Studio for Mac to sync the changes.

Изменить NSWindowController и это должно выглядеть следующим образом:Edit the NSWindowController and make it look like the following:

using System;
using Foundation;
using AppKit;

namespace MacModern
{
    public partial class MainWindowController : NSWindowController
    {
        #region Constructor
        public MainWindowController (IntPtr handle) : base (handle)
        {
        }
        #endregion

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

            // Create a title bar accessory view controller and attach
            // the view created in Interface Builder
            var accessoryView = new NSTitlebarAccessoryViewController ();
            accessoryView.View = AccessoryViewGoBar;

            // Set the location and attach the accessory view to the
            // titlebar to be displayed
            accessoryView.LayoutAttribute = NSLayoutAttribute.Bottom;
            Window.AddTitlebarAccessoryViewController (accessoryView);

        }
        #endregion
    }
}

Основные преимущества этот код, где представление имеет значение для настраиваемого представления, определенные в конструктор Interface Builder и в виде розетки:The key points of this code are where the View is set to the custom View that was defined in Interface Builder and exposed as an Outlet:

accessoryView.View = AccessoryViewGoBar;

И LayoutAttribute , определяющий где периферийного устройства будет отображаться:And the LayoutAttribute that defines where the accessory will be displayed:

accessoryView.LayoutAttribute = NSLayoutAttribute.Bottom;

Так как macOS теперь полностью локализованной, Left и Right NSLayoutAttribute свойства, которые являются устаревшими и следует заменить на Leading и Trailing.Because macOS is now fully localized, the Left and Right NSLayoutAttribute properties have been deprecated and should be replaced with Leading and Trailing.

С помощью Windows с вкладкамиUsing Tabbed Windows

Кроме того система macOS может добавить контроллеры представления периферийного устройства окна приложения.Additionally, the macOS system might add Accessory View Controllers to the app's Window. Например, чтобы создать Windows с вкладками, где некоторые из приложения Windows объединяются в одно окно виртуального:For example, to create Tabbed Windows where several of the App's Windows are merged into one virtual Window:

Обычно разработчику потребуется предпринять действия ограниченного использования Windows с вкладками в свои приложения Xamarin.Mac, система будет обрабатывать их автоматически, как показано ниже:Typically, the developer will need to take limited action use Tabbed Windows in their Xamarin.Mac apps, the system will handle them automatically as follows:

  • Windows будет автоматически с вкладками, когда OrderFront вызывается метод.Windows will automatically be Tabbed when the OrderFront method is invoked.
  • Windows будет автоматически Untabbed при OrderOut вызывается метод.Windows will automatically be Untabbed when the OrderOut method is invoked.
  • В коде, по-прежнему считаются «visible» всех окон с вкладками Однако не переднее вкладки скрыты по систему, используя CoreGraphics.In code all Tabbed windows are still considered "visible", however any non-frontmost Tabs are hidden by the system using CoreGraphics.
  • Используйте TabbingIdentifier свойство NSWindow для группы Windows друг с другом по вкладкам.Use the TabbingIdentifier property of NSWindow to group Windows together into Tabs.
  • Если это NSDocument приложения на основе, несколькими из этих возможностей будет включена автоматически (например, знак "плюс", добавляемый на панель вкладок) без вмешательства разработчика.If it is an NSDocument based app, several of these features will be enabled automatically (such as the plus button being added to the Tab Bar) without any developer action.
  • Отличным отNSDocument на основе приложений можно включить кнопку «плюс» в группе вкладок, чтобы добавить новый документ, переопределив GetNewWindowForTab метод NSWindowsController.Non-NSDocument based apps can enable the "plus" button in the Tab Group to add a new document by overriding the GetNewWindowForTab method of the NSWindowsController.

Объединяя все элементы, AppDelegate приложения, необходимо использовать Windows с вкладками на основе системы может выглядеть следующим образом:Bringing all of the pieces together, the AppDelegate of an app that wanted to use system based Tabbed Windows could look like the following:

using AppKit;
using Foundation;

namespace MacModern
{
    [Register ("AppDelegate")]
    public class AppDelegate : NSApplicationDelegate
    {
        #region Computed Properties
        public int NewDocumentNumber { get; set; } = 0;
        #endregion

        #region Constructors
        public AppDelegate ()
        {
        }
        #endregion

        #region Override Methods
        public override void DidFinishLaunching (NSNotification notification)
        {
            // Insert code here to initialize your application
        }

        public override void WillTerminate (NSNotification notification)
        {
            // Insert code here to tear down your application
        }
        #endregion

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

            // Display
            controller.ShowWindow (this);
        } 
        #endregion
    }
}

Где NewDocumentNumber свойство следит за количество новых документов, создаваемых и NewDocument метод создает новый документ и отображает его.Where the NewDocumentNumber property keeps track of the number of new documents created and the NewDocument method creates a new document and displays it.

NSWindowController Затем может выглядеть следующим образом:The NSWindowController could then look like:

using System;
using Foundation;
using AppKit;

namespace MacModern
{
    public partial class MainWindowController : NSWindowController
    {
        #region Application Access
        /// <summary>
        /// A helper shortcut to the app delegate.
        /// </summary>
        /// <value>The app.</value>
        public static AppDelegate App {
            get { return (AppDelegate)NSApplication.SharedApplication.Delegate; }
        }
        #endregion

        #region Constructor
        public MainWindowController (IntPtr handle) : base (handle)
        {
        }
        #endregion

        #region Public Methods
        public void SetDefaultDocumentTitle ()
        {
            // Is this the first document?
            if (App.NewDocumentNumber == 0) {
                // Yes, set title and increment
                Window.Title = "Untitled";
                ++App.NewDocumentNumber;
            } else {
                // No, show title and count
                Window.Title = $"Untitled {App.NewDocumentNumber++}";
            }
        }
        #endregion

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

            // Prefer Tabbed Windows
            Window.TabbingMode = NSWindowTabbingMode.Preferred;
            Window.TabbingIdentifier = "Main";

            // Set default window title
            SetDefaultDocumentTitle ();

            // Set window to use Full Size Content View
            // Window.StyleMask = NSWindowStyle.FullSizeContentView;

            // Create a title bar accessory view controller and attach
            // the view created in Interface Builder
            var accessoryView = new NSTitlebarAccessoryViewController ();
            accessoryView.View = AccessoryViewGoBar;

            // Set the location and attach the accessory view to the
            // titlebar to be displayed
            accessoryView.LayoutAttribute = NSLayoutAttribute.Bottom;
            Window.AddTitlebarAccessoryViewController (accessoryView);

        }

        public override void GetNewWindowForTab (NSObject sender)
        {
            // Ask app to open a new document window
            App.NewDocument (this);
        }
        #endregion
    }
}

Где статический App свойство существует сочетание клавиш для получения AppDelegate.Where the static App property provides a shortcut to get to the AppDelegate. SetDefaultDocumentTitle Метод задает новый заголовок документов на основе числа новых документов, создаваемых.The SetDefaultDocumentTitle method sets a new documents title based on the number of new documents created.

Следующий код, сообщает macOS, приложения которых предпочтительно использовать вкладки и предоставляет строку, которая позволяет приложения Windows, которому требуется выполнить группировку по вкладкам:The following code, tells macOS that the app prefers to use tabs and provides a string that allows the app's Windows to be grouped into Tabs:

// Prefer Tabbed Windows
Window.TabbingMode = NSWindowTabbingMode.Preferred;
Window.TabbingIdentifier = "Main";

И следующий метод переопределения добавляет "плюс" на панели вкладки, при этом будет создан новый документ при щелчке пользователем:And the following override method adds a plus button to the Tab Bar that will create a new document when clicked by the user:

public override void GetNewWindowForTab (NSObject sender)
{
    // Ask app to open a new document window
    App.NewDocument (this);
}

С помощью базовой анимацииUsing Core Animation

Анимация Core является механизм визуализации мощного графики, который встроен в macOS.Core Animation is a high powered graphics rendering engine that is built into macOS. Чтобы воспользоваться преимуществами GPU (графическом процессоре), доступного в оборудовании современных macOS в отличие от операций графики на использование ЦП, которое может замедлить работу машины был оптимизирован базовой анимации.Core Animation has been optimized to take advantage of the GPU (Graphics Processing Unit) available in modern macOS hardware as opposed to running the graphics operations on the CPU, which can slow down the machine.

CALayer, Предоставляемые Core Animation, можно использовать для задач, таких как Быстрая и плавная прокрутка и анимации.The CALayer, provided by Core Animation, can be used for tasks such as fast and fluid scrolling and animations. Пользовательский интерфейс приложения должен состоять из нескольких представлений и слоев, чтобы полностью воспользоваться преимуществами базовой анимации.An app's User Interface should be composed of multiple subviews and layers to fully take advantage of Core Animation.

Объект CALayer объект предоставляет несколько свойств, которые позволяют разработчикам управлять, чем представлено на экране, чтобы пользователь например:A CALayer object provides several properties that allow the developer to control what is presented onscreen to the user such as:

  • Content — Может быть NSImage или CGImage , предоставляющий содержимое слоя.Content - Can be a NSImage or CGImage that provides the contents of the layer.
  • BackgroundColor — Задает цвет фона слой как CGColorBackgroundColor - Sets the background color of the layer as a CGColor
  • BorderWidth — Задает ширину границы.BorderWidth - Sets the border width.
  • BorderColor — Задает цвет границы.BorderColor - Sets the border color.

Чтобы использовать двухмерной графики в пользовательском Интерфейсе приложения, его необходимо использовать слой резервного представления, которые Apple предполагает, что разработчик всегда следует включить в представление содержимого окна.To utilize Core Graphics in the app's UI, it must be using Layer Backed Views, which Apple suggests that the developer should always enable in the Window's Content View. Таким образом, все дочерние представления автоматически наследуют резервного слой также.This way, all child views will automatically inherit Layer Backing as well.

Кроме того, Apple предлагает с помощью слоя резервного представлений в отличие от добавления нового CALayer как подуровень так, как система автоматически будет обрабатывать некоторые необходимые параметры (например, предусмотренные стандартом дисплей Retina).Additionally, Apple suggests using Layer Backed Views as opposed to adding a new CALayer as a sublayer because the system will automatically handle several of the required settings (such as those required by a Retina Display).

Слой резервного можно включить, задав WantsLayer из NSView для true или внутри конструктора Interface Builder в разделе инспектор эффектов представления путем проверки слоя анимации Core:Layer Backing can be enabled by setting the WantsLayer of a NSView to true or inside of Xcode's Interface Builder under the View Effects Inspector by checking Core Animation Layer:

Перерисовка представлений с помощью слоевRedrawing Views with Layers

Еще один важный шаг, когда использование слоя резервного представлений в приложении Xamarin.Mac является установка LayerContentsRedrawPolicy из NSView для OnSetNeedsDisplay в NSViewController.Another important step when using Layer Backed Views in a Xamarin.Mac app is setting the LayerContentsRedrawPolicy of the NSView to OnSetNeedsDisplay in the NSViewController. Пример:For example:

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

    // Set the content redraw policy
    View.LayerContentsRedrawPolicy = NSViewLayerContentsRedrawPolicy.OnSetNeedsDisplay;
}

Если это свойство не задано разработчиком, представление будет перерисовку при каждом изменении источника кадра, который не требуется для повышения производительности.If the developer doesn't set this property, the View will be redrawn whenever its frame origin changes, which is not desired for performance reasons. С помощью этого свойства задано OnSetNeedsDisplay разработчик вручную будет устанавливать NeedsDisplay для true для принудительного содержимое для повторной отрисовки поверхности, тем не менее.With this property set to OnSetNeedsDisplay the developer will manually have to set NeedsDisplay to true to force the content to redraw, however.

Когда представление помечен как "грязные", система проверяет WantsUpdateLayer свойства представления.When a View is marked as dirty, the system checks the WantsUpdateLayer property of the View. Если он возвращает true то UpdateLayer вызывается метод, в противном случае DrawRect представления был вызван для обновления представления содержимого.If it returns true then the UpdateLayer method is called, else the DrawRect method of the View is called to update the View's contents.

Apple имеет следующие рекомендации для обновления содержимого представления, при необходимости.Apple has the following suggestions for updating a Views contents when required:

  • Является предпочтительным для Apple с помощью UpdateLater через DrawRect каждый раз, когда возможно, так как он обеспечивает значительный выигрыш в производительности.Apple prefers using UpdateLater over DrawRect whenever possible as it provides a significant performance boost.
  • Используйте тот же layer.Contents для элементов пользовательского интерфейса, которые выглядят.Use the same layer.Contents for UI elements that look similar.
  • Apple, также является предпочтительным для разработчиков для составления их пользовательского интерфейса, такие как использование стандартных представлений NSTextField, еще раз когда это возможно.Apple also prefers the developer to compose their UI using standard views such as NSTextField, again whenever possible.

Чтобы использовать UpdateLayer, создайте пользовательский класс для NSView и делает код более выглядеть следующим образом:To use UpdateLayer, create a custom class for the NSView and make the code look like the following:

using System;
using Foundation;
using AppKit;

namespace MacModern
{
    public partial class MainView : NSView
    {
        #region Computed Properties
        public override bool WantsLayer {
            get { return true; }
        }

        public override bool WantsUpdateLayer {
            get { return true; }
        }
        #endregion

        #region Constructor
        public MainView (IntPtr handle) : base (handle)
        {
        }
        #endregion

        #region Override Methods
        public override void DrawRect (CoreGraphics.CGRect dirtyRect)
        {
            base.DrawRect (dirtyRect);

        }

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

            // Draw view 
            Layer.BackgroundColor = NSColor.Red.CGColor;
        }
        #endregion
    }
}

С помощью современных перетаскиванияUsing Modern Drag and Drop

Чтобы представить современный интерфейс перетаскивания для пользователя, следует принять разработчику перетаскивания или косяк в их приложении операции перетаскивания.To present a modern Drag and Drop experience for the user, the developer should adopt Drag Flocking in their app's Drag and Drop operations. Перетащите Flocking —, где каждый отдельный файл или изначально перетаскиваемый элемент отображается как отдельный элемент, который потоки устремляются (группа друг с другом под курсором с числом, равным числу элементов), как пользователь продолжает операцию перетаскивания.Drag Flocking is where each individual file or item being dragged initially appears as an individual element that flocks (group together under the cursor with a count of the number of items) as the user continues the drag operation.

Если пользователь завершает операцию перетаскивания, отдельным элементам Unflock и вернуть исходное расположение.If the user terminates the Drag operation, the individual elements will Unflock and return to their original locations.

В следующем примере кода включает перетаскивания или косяк на представления:The following example code enables Drag Flocking on a custom View:

using System;
using System.Collections.Generic;
using Foundation;
using AppKit;

namespace MacModern
{
    public partial class MainView : NSView, INSDraggingSource, INSDraggingDestination
    {
        #region Constructor
        public MainView (IntPtr handle) : base (handle)
        {
        }
        #endregion

        #region Override Methods
        public override void MouseDragged (NSEvent theEvent)
        {
            // Create group of string to be dragged
            var string1 = new NSDraggingItem ((NSString)"Item 1");
            var string2 = new NSDraggingItem ((NSString)"Item 2");
            var string3 = new NSDraggingItem ((NSString)"Item 3");

            // Drag a cluster of items
            BeginDraggingSession (new [] { string1, string2, string3 }, theEvent, this);
        }
        #endregion
    }
}

Flocking эффект достигалось путем отправки каждого элемента, перетаскиваемого в BeginDraggingSession метод NSView как отдельный элемент в массиве.The flocking effect was achieved by sending each item being dragged to the BeginDraggingSession method of the NSView as a separate element in an array.

При работе с NSTableView или NSOutlineView, использовать PastboardWriterForRow метод NSTableViewDataSource класса для запуска операции перетаскивание:When working with a NSTableView or NSOutlineView, use the PastboardWriterForRow method of the NSTableViewDataSource class to start the Dragging operation:

using System;
using System.Collections.Generic;
using Foundation;
using AppKit;

namespace MacModern
{
    public class ContentsTableDataSource: NSTableViewDataSource
    {
        #region Constructors
        public ContentsTableDataSource ()
        {
        }
        #endregion

        #region Override Methods
        public override INSPasteboardWriting GetPasteboardWriterForRow (NSTableView tableView, nint row)
        {
            // Return required pasteboard writer
            ...
            
            // Pasteboard writer failed
            return null;
        }
        #endregion
    }
}

Это позволяет разработчику предоставить отдельному NSDraggingItem для каждого элемента в таблице, перетаскиваемого в отличие от старого метода WriteRowsWith , записать все строки как одну группу в буфер.This allows the developer to provide an individual NSDraggingItem for every item in the table that is being dragged as opposed to the older method WriteRowsWith that write all of the rows as a single group to the pasteboard.

При работе с NSCollectionViews, снова использовать PasteboardWriterForItemAt метод, в отличие от WriteItemsAt метод при перетаскивании начинается.When working with NSCollectionViews, again use the PasteboardWriterForItemAt method as opposed to the WriteItemsAt method when Dragging begins.

Разработчик всегда следует располагать большими файлами монтажного стола.The developer should always avoid putting large files on the pasteboard. Знакомы с macOS Sierra, обещания файл позволяют разработчику для размещения ссылки на заданное файлы монтажного стола, позже быть выполнено, когда пользователь завершает операцию перетаскивания с помощью нового NSFilePromiseProvider и NSFilePromiseReceiver классы.New to macOS Sierra, File Promises allow the developer to place references to given files on the pasteboard that will later be fulfilled when the user finishes the Drop operation using the new NSFilePromiseProvider and NSFilePromiseReceiver classes.

Использование современных событий отслеживанияUsing Modern Event Tracking

Для элемента пользовательского интерфейса (такие как NSButton), добавленный в заголовок или панели инструментов области, пользователь должен иметь возможность щелкните элемент, который будет активировать событие в обычном режиме (например, отображение всплывающего окна).For a User Interface element (such as a NSButton) that has been added to a Title or Tool Bar area, the user should be able to click the element and have it fire an event as normal (such as displaying a popup window). Тем не менее так как элемент находится в области заголовка или панели инструментов, пользователь должен иметь возможность щелкните и перетащите элемент для перемещения окна также.However, since the item is also in the Title or Tool Bar area, the user should be able to click and drag the element to move the window as well.

Чтобы сделать это в коде, создать пользовательский класс для элемента (такие как NSButton) и переопределить MouseDown событие следующим образом:To accomplish this in code, create a custom class for the element (such as NSButton) and override the MouseDown event as follows:

public override void MouseDown (NSEvent theEvent)
{
    var shouldCallSuper = false;

    Window.TrackEventsMatching (NSEventMask.LeftMouseUp, 2000, NSRunLoop.NSRunLoopEventTracking, (NSEvent evt, ref bool stop) => {
        // Handle event as normal
        stop = true;
        shouldCallSuper = true;
    });

    Window.TrackEventsMatching(NSEventMask.LeftMouseDragged, 2000, NSRunLoop.NSRunLoopEventTracking, (NSEvent evt, ref bool stop) => {
        // Pass drag event to window
        stop = true;
        Window.PerformWindowDrag (evt);
    });

    // Call super to handle mousedown
    if (shouldCallSuper) {
        base.MouseDown (theEvent);
    }
}

Этот код использует TrackEventsMatching метод NSWindow присоединяемого элемента пользовательского интерфейса для перехвата LeftMouseUp и LeftMouseDragged события.This code uses the TrackEventsMatching method of the NSWindow that the UI element is attached to intercept the LeftMouseUp and LeftMouseDragged events. Для LeftMouseUp событие, элемент пользовательского интерфейса, которая реагирует в обычном режиме.For a LeftMouseUp event, the UI element responds as normal. Для LeftMouseDragged событий, событие передается NSWindowв PerformWindowDrag метод для перемещения окна на экране.For the LeftMouseDragged event, the event is passed to the NSWindow's PerformWindowDrag method to move the window on screen.

Вызов PerformWindowDrag метод NSWindow класс предоставляет следующие преимущества:Calling the PerformWindowDrag method of the NSWindow class provides the following benefits:

  • Позволяет для окна переместить, даже если зависание приложения (например, при обработке глубокого цикла).It allows for the Window to move, even if the app is hung (such as when processing a deep loop).
  • Переключение пространства будет работать должным образом.Space switching will work as expected.
  • Панель пробелы будут отображаться в обычном режиме.The Spaces Bar will be displayed as normal.
  • Привязка окна и выравнивание работать в обычном режиме.Window snapping and alignment work as normal.

С помощью современных контейнерных элементов управления представленияUsing Modern Container View Controls

macOS Sierra позволяет улучшить многих современных существующий контейнер представления элементов управления, доступных в предыдущей версии операционной системы.macOS Sierra provides many modern improvements to the existing Container View Controls available in previous version of the OS.

Улучшения представления таблицыTable View Enhancements

Разработчику следует всегда использовать новый NSView на основе версии контейнерных элементов управления представления, такие как NSTableView.The developer should always use the new NSView based version of Container View Controls such as NSTableView. Пример:For example:

using System;
using System.Collections.Generic;
using Foundation;
using AppKit;

namespace MacModern
{
    public class ContentsTableDelegate : NSTableViewDelegate
    {
        #region Constructors
        public ContentsTableDelegate ()
        {
        }
        #endregion

        #region Override Methods
        public override NSView GetViewForItem (NSTableView tableView, NSTableColumn tableColumn, nint row)
        {
            // Build new view
            var view = new NSView ();
            ...

            // Return the view representing the item to display
            return view;
        }
        #endregion
    }
}

Это позволяет для выполнения пользовательских действий строки таблицы должны быть присоединены к заданной строки в таблице (например, проведение пальцем по экрану вправо, чтобы удалить строку).This allows for custom Table Row Actions to be attached to given rows in the table (such as swiping right to delete the row). Чтобы включить это поведение, переопределите RowActions метод NSTableViewDelegate:To enable this behavior, override the RowActions method of the NSTableViewDelegate:

using System;
using System.Collections.Generic;
using Foundation;
using AppKit;

namespace MacModern
{
    public class ContentsTableDelegate : NSTableViewDelegate
    {
        #region Constructors
        public ContentsTableDelegate ()
        {
        }
        #endregion

        #region Override Methods
        public override NSView GetViewForItem (NSTableView tableView, NSTableColumn tableColumn, nint row)
        {
            // Build new view
            var view = new NSView ();
            ...

            // Return the view representing the item to display
            return view;
        }

        public override NSTableViewRowAction [] RowActions (NSTableView tableView, nint row, NSTableRowActionEdge edge)
        {
            // Take action based on the edge
            if (edge == NSTableRowActionEdge.Trailing) {
                // Create row actions
                var editAction = NSTableViewRowAction.FromStyle (NSTableViewRowActionStyle.Regular, "Edit", (action, rowNum) => {
                    // Handle row being edited
                    ...
                });

                var deleteAction = NSTableViewRowAction.FromStyle (NSTableViewRowActionStyle.Destructive, "Delete", (action, rowNum) => {
                    // Handle row being deleted
                    ...
                });

                // Return actions
                return new [] { editAction, deleteAction };
            } else {
                // No matching actions
                return null;
            }
        }
        #endregion
    }
}

Статический NSTableViewRowAction.FromStyle используется для создания нового действия строки таблицы следующие стили:The static NSTableViewRowAction.FromStyle is used to create a new Table Row Action of the following styles:

  • Regular — Выполняет стандартного действия без уничтожения данных, например редактирование содержимое строки.Regular - Performs a standard non-destructive action such as edit the row's contents.
  • Destructive — Выполняет разрушительные действия, например удаление строки из таблицы.Destructive - Performs a destructive action such as delete the row from the table. Эти действия будут передаваться с красным фоном.These actions will be rendered with a red background.

Улучшения представления прокруткиScroll View Enhancements

При использовании представления прокрутки (NSScrollView) непосредственно или как часть другого элемента управления (такие как NSTableView), содержимое представления прокрутки можно сдвигать ползунок в области заголовка и панели инструментов в приложения Xamarin.Mac с помощью современных поиска и представления.When using a Scroll View (NSScrollView) directly, or as part of another control (such as NSTableView), the contents of the Scroll View can slide under the Title and Tool Bar areas in a Xamarin.Mac app using a Modern Look and Views.

Таким образом первый элемент в области содержимого представления могут быть частично закрыты области заголовка и панели инструментов.As a result, the first item in the Scroll View content area can be partially obscured by the Title and Tool Bar area.

Чтобы исправить эту проблему, Apple добавлено два новых свойства для NSScrollView класса:To correct this issue, Apple has added two new properties to the NSScrollView class:

  • ContentInsets -Позволяет разработчику предоставить NSEdgeInsets объект, определяющий смещение, которое будет применяться к верхней части представления.ContentInsets - Allows the developer to provide a NSEdgeInsets object defining the offset that will be applied to the top of the Scroll View.
  • AutomaticallyAdjustsContentInsets Если true представление прокрутки автоматически обработает ContentInsets для разработчиков.AutomaticallyAdjustsContentInsets - If true the Scroll View will automatically handle the ContentInsets for the developer.

С помощью ContentInsets разработчика можно настроить начало прокрутки представления, чтобы разрешить для включения "Стандартные", такие как:By using the ContentInsets the developer can adjust the start of the Scroll View to allow for the inclusion of accessories such as:

  • Индикатор сортировки, показанное в приложение "Почта".A Sort indicator like the one shown in the Mail app.
  • Поле поиска.A Search Field.
  • Кнопка обновления или обновления.A Refresh or Update button.

Автоматический макет и локализации в современных приложенияхAuto Layout and Localization in Modern Apps

Apple включила несколько технологий в Xcode, позволяют разработчикам легко создавать приложения интернационализированных macOS.Apple has included several technologies in Xcode that allow the developer to easily create an internationalized macOS app. Xcode теперь позволяет разработчику для разделения текста пользовательского интерфейса, начиная с проектирования пользовательского интерфейса приложения в его файлы раскадровки и предоставляет средства для поддержания такое разделение, если он изменяется.Xcode now allows the developer to separate user-facing text from the app's User Interface design in its Storyboard files and provides tools to maintain this separation if the UI changes.

Дополнительные сведения см. в разделе Apple интернационализации и руководство по локализации.For more information, please see Apple's Internationalization and Localization Guide.

Реализация базового интернационализацииImplementing Base Internationalization

Путем реализации базового интернационализации, разработчик может предоставить единый файл раскадровки для представления пользовательского интерфейса приложения и отделить все строки пользовательского интерфейса.By implementing Base Internationalization, the developer can provide a single Storyboard file to represent the app's UI and separate out all of the user-facing strings.

Когда разработчик создает исходный файл раскадровки (или файлы), которые определяют пользовательский интерфейс приложения, они будут собраны в интернационализации Base (язык, который говорит разработчик).When the developer is creating the initial Storyboard file (or files) that define the app's User Interface, they will be built in the Base Internationalization (the language that the developer speaks).

Затем разработчик можно экспортировать, локализации и интернационализации базовых строк (в структуры пользовательского интерфейса раскадровки), которые могут быть переведены на несколько языков.Next, the developer can export localizations and the Base Internationalization strings (in the Storyboard UI design) that can be translated into multiple languages.

Позднее можно импортировать эти локализации и Xcode создаст файлы строки, зависящей от языка для раскадровки.Later, these localizations can be imported and Xcode will generate the language-specific string files for the Storyboard.

Реализация автоматический макет для поддержки локализацииImplementing Auto Layout to Support Localization

Поскольку локализованные версии строкового значения могут иметь самые разные размеры и/или направление чтения, разработчик должен использовать автоматический макет позиция и размер пользовательского интерфейса приложения в файл раскадровки.Because localized versions of string values can have vastly different sizes and/or reading direction, the developer should use Auto Layout to position and size the app's User Interface in a Storyboard file.

Apple предложить следующим образом:Apple suggest doing the following:

  • Удалите ограничения фиксированной ширины -все текстовые представления должны для изменения размера на основе их содержимого.Remove Fixed Width Constraints - All text-based Views should be allowed to resize based on their content. Фиксированная ширина представление может обрезать их содержимое на определенных языках.Fixed width View may crop their content in specific languages.
  • Использовать внутренние размеры содержимого — по умолчанию текстового представления будет Авторазмер в соответствии с содержимым.Use Intrinsic Content Sizes - By default text-based Views will auto-size to fit their content. Для текстового представления, не размеры, выберите их в конструктора Interface Builder, затем выберите изменить > размер на размещение содержимого.For text-based View that are not sizing correctly, select them in Xcode's Interface Builder then choose Edit > Size To Fit Content.
  • Применить начальные и конечные атрибуты — так, как можно изменить направление текста на языке пользователя, используйте новый Leading и Trailing атрибутов ограничения, в отличие от существующего Right и Left атрибуты.Apply Leading and Trailing Attributes - Because the direction of the text can change based on the user's language, use the new Leading and Trailing constraint attributes as opposed to the existing Right and Left attributes. Leading и Trailing автоматически настроит зависимости от направления языков.Leading and Trailing will automatically adjust based on the languages direction.
  • ПИН-код представлений для представления рядом -это позволяет представлений для положение и размер представлений о их изменении в ответ на языке, выбранном.Pin Views to Adjacent Views - This allows the Views to reposition and resize as the Views around them change in response to the language selected.
  • Не устанавливайте Windows минимум и/или максимальные размеры -Разрешить Windows, чтобы изменить размер, как на языке, выбранном изменяет размер области их содержимого.Don't Set a Windows Minimum and/or Maximum Sizes - Allow Windows to change size as the language selected resizes their content areas.
  • Проверить изменения макета постоянно — во время разработки в приложении следует постоянно тестировать на разных языках.Test Layout Changes Constantly - During development at app should be tested constantly in different languages. См. в разделе Apple Testing Your международного приложения документации для получения дополнительных сведений.See Apple's Testing Your Internationalized app documentation for more details.
  • Использовать NSStackViews для ПИН-код представления вместе - NSStackViews позволяет их содержимое, shift и увеличение предсказуемыми и содержимое, изменить размер в зависимости от выбранного языка.Use NSStackViews to Pin Views Together - NSStackViews allows their contents to shift and grow in predictable ways and the content change size based on the language selected.

Локализация в Interface Builder в XcodeLocalizing in Xcode's Interface Builder

Apple предоставляет несколько функций конструктора Interface Builder, разработчик может использовать при разработке или изменении пользовательского интерфейса приложения для поддержки локализации.Apple has provided several features in Xcode's Interface Builder that the developer can use when designing or editing an app's UI to support localization. Направление текста раздел инспекторе атрибутов разработчик может предоставить подсказки как направление следует использовать и обновить на select текстового представления (такие как NSTextField):The Text Direction section of the Attribute Inspector allows the developer to provide hints on how direction should be used and updated on a select Text-Based View (such as NSTextField):

Существует три возможных значения для направление текста:There are three possible values for the Text Direction:

  • Естественное -макет на основе строки для элемента управления.Natural - The layout is based on the string assigned to the control.
  • Слева направо -макет всегда вынужден слева направо.Left to Right - The layout is always forced to left to right.
  • Справа налево -всегда принудительно макет справа налево.Right to Left - The layout is always forced to right to left.

Существует два возможных значения для макета:There are two possible values for the Layout:

  • Слева направо -макет всегда слева направо.Left to Right - The layout is always left to right.
  • Справа налево -всегда является макет справа налево.Right to Left - The layout is always right to left.

Обычно они не должен изменяться Если конкретное направление не требуется.Typically these should not be changed unless a specific alignment is required.

Зеркальный свойство сообщает системе перевернуть свойства определенного элемента управления (например, положение изображения ячейки).The Mirror property tells the system to flip specific control properties (such as the Cell Image Position). Он имеет три возможных значения:It has three possible values:

  • Автоматически -позиция автоматически изменяется в зависимости от направления на языке, выбранном.Automatically - The position will automatically change based on the direction of the language selected.
  • В интерфейсе для слева вправо -положение изменяются только в право слева на основе языков.In Right To Left Interface - The position will only be changed in right to left based languages.
  • Никогда не -позиция никогда не изменится.Never - The position will never change.

Если разработчик указал Center, ширине или полный выравнивания содержимого текстового представления, они никогда не будет должно быть перевернуто зависимости от выбранного языка.If the developer has specified Center, Justify or Full alignment on the content of a text-based View, these will never be flipped based on language selected.

Прежде чем macOS Sierra элементов управления, созданных в коде будет нельзя применять зеркалирование автоматически.Prior to macOS Sierra, controls created in code would not be mirrored automatically. Разработчик должен был использовать код, аналогичный следующему для обработки зеркального отображения:The developer had to use code like the following to handle mirroring:

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

    // Setting a button's mirroring based on the layout direction
    var button = new NSButton ();
    if (button.UserInterfaceLayoutDirection == NSUserInterfaceLayoutDirection.LeftToRight) {
        button.Alignment = NSTextAlignment.Right;
        button.ImagePosition = NSCellImagePosition.ImageLeft;
    } else {
        button.Alignment = NSTextAlignment.Left;
        button.ImagePosition = NSCellImagePosition.ImageRight;
    }
}

Где Alignment и ImagePosition задаются на основе UserInterfaceLayoutDirection элемента управления.Where the Alignment and ImagePosition are being set based on the UserInterfaceLayoutDirection of the control.

macOS Sierra добавляет несколько новых удобных конструкторов (через статический CreateButton метод), которые принимают несколько параметров (например, заголовок, изображение и действия) и автоматически отразит правильно.macOS Sierra adds several new convenience constructors (via the static CreateButton method) that take several parameters (such as Title, Image and Action) and will automatically mirror correctly. Пример:For example:

var button2 = NSButton.CreateButton (myTitle, myImage, () => {
    // Take action when the button is pressed
    ...
});

С помощью внешний вид системыUsing System Appearances

Приложения для современных macOS можно внедрять новый темно-внешний интерфейс, который хорошо подходит для приложений образ создания, редактирования или презентации:Modern macOS apps can adopt a new Dark Interface Appearance that works well for image creation, editing or presentation apps:

Это можно сделать путем добавления одной строки кода, прежде чем будет предоставлен окна.This can be done by adding one line of code before the Window is presented. Пример:For example:

using System;
using AppKit;
using Foundation;

namespace MacModern
{
    public partial class ViewController : NSViewController
    {
        ...
    
        #region Override Methods
        public override void ViewWillAppear ()
        {
            base.ViewWillAppear ();

            // Apply the Dark Interface Appearance
            View.Window.Appearance = NSAppearance.GetAppearance (NSAppearance.NameVibrantDark);

            ...
        }
        #endregion
    }
}

Статический GetAppearance метод NSAppearance класс используется для получения именованных внешний от системы (в данном случае NSAppearance.NameVibrantDark).The static GetAppearance method of the NSAppearance class is used to get a named appearance from the system (in this case NSAppearance.NameVibrantDark).

Apple имеет следующие рекомендации по использованию системы внешний вид:Apple has the following suggestions for using System Appearances:

  • Использовать именованные цвета вместо жестко заданных значений (таких как LabelColor и SelectedControlColor).Prefer named colors over hardcoded values (such as LabelColor and SelectedControlColor).
  • Используйте стиль стандартного элемента управления системы, где это возможно.Use system standard control style where possible.

Приложение macOS, которое использует внешний системы автоматически будет работать для пользователей, которые включили специальные возможности в приложении системные настройки.A macOS app that uses the System Appearances will automatically work correctly for users that have enabled Accessibility features from the System Preferences app. В результате Apple предполагает, что разработчику следует всегда использовать внешний вид системы в своих приложениях на macOS.As a result, Apple suggests that the developer should always use System Appearances in their macOS apps.

Разработка пользовательских интерфейсов с помощью StoryboardDesigning UIs with Storyboards

Раскадровки позволяют разработчику не только для разработки, что поток отдельных элементов интерфейса пользователя приложения, но до визуализации и разработать пользовательский Интерфейс, так и для иерархии заданные элементы.Storyboards allow the developer to not only design the individual elements that make up an app's User Interface, but to visualize and design the UI flow and the hierarchy of the given elements.

Контроллеры позволяют разработчику собирает элементы в единицу композиции и абстрактным Segues и удалить типичный «связывающим кода» для перемещения по иерархии представления требуется:Controllers allow the developer to collect elements into a unit of composition and Segues abstract and remove the typical "glue code" required to move throughout the View Hierarchy:

Дополнительные сведения см. в разделе наших введение в раскадровки документации.For more information, please see our Introduction to Storyboards documentation.

Существует несколько экземпляров, где заданного сцены, определенные в раскадровке потребует данные из предыдущего кадра в иерархию представлений.There are many instances where a given scene defined in a storyboard will require data from a previous scene in the View Hierarchy. Apple имеет следующие рекомендации для передачи данных между сценами:Apple has the following suggestions for passing information between scenes:

  • Dependancies данных следует всегда вызывать каскадные действия перемещается вниз по иерархии.Data dependancies should always cascade downwards through the hierarchy.
  • Избегайте жесткого задания структурные dependancies пользовательского интерфейса, как это ограничивает гибкость пользовательского интерфейса.Avoid hardcoding UI structural dependancies, as this limits UI flexibility.
  • Используйте C# интерфейсы для предоставления dependancies универсальных данных.Use C# Interfaces to provide generic data dependancies.

Контроллер представления, выступающего в качестве источника переход, можно переопределить PrepareForSegue метод и выполните инициализацию необходимы (например, передача данных), прежде чем переход выполняется для отображения целевой контроллер представления.The View Controller that is acting as the source of the Segue, can override the PrepareForSegue method and do any initialization required (such as passing data) before the Segue is executed to display the target View Controller. Пример:For example:

public override void PrepareForSegue (NSStoryboardSegue segue, NSObject sender)
{
    base.PrepareForSegue (segue, sender);

    // Take action based on Segue ID
    switch (segue.Identifier) {
    case "MyNamedSegue":
        // Prepare for the segue to happen
        ...
        break;
    }
}

Дополнительные сведения см. в разделе наших Segues документации.For more information, please see our Segues documentation.

Распространение действийPropagating Actions

Основываясь на дизайн приложения macOS, может существовать раз, когда обработчик рекомендации для действия в элемент управления пользовательского интерфейса может быть в другом месте в иерархии пользовательского интерфейса.Based on the design of the macOS app, there might be times when the best handler for an Action on a UI control might be in elsewhere in the UI Hierarchy. Это обычно происходит, меню и пунктов меню, live в свои собственные сцены, отдельно от остальной части пользовательского интерфейса приложения.This is typically true of Menus and Menu Items that live in their own scene, separate from the rest of the app's UI.

Чтобы решить эту проблему, разработчик можно создать настраиваемое действие и передать действия вверх по цепочке респондент.To handle this situation, the developer can create a Custom Action and pass the Action up the responder chain. Дополнительные сведения см. в разделе наших работа с окно Custom Actions документации.For more information please see our Working with Custom Window Actions documentation.

Возможности современных MacModern Mac Features

Apple включает в себя несколько функций пользовательского интерфейса в macOS Sierra, разработчик может использовать все преимущества на платформе Mac, такие как:Apple has included several user-facing features in macOS Sierra that allow the developer to make the most of the Mac platform, such as:

  • NSUserActivity -это позволяет приложению для описания действия, которое в настоящий момент участвует пользователь.NSUserActivity - This allows the app to describe the activity that the user is currently involved in. NSUserActivity изначально был создан для поддержки передачи, где действие запуска на одном из устройств пользователя может отгрузку и продолжение на другом устройстве.NSUserActivity was initially created to support HandOff, where an activity started on one of the user's devices could be picked up and continued on another device. NSUserActivity Таким образом, работает соответствующим образом в macOS, так как он делает в iOS см. статью наших введение переходной iOS документации для получения дополнительных сведений.NSUserActivity works the same in macOS as it does in iOS so please see our Introduction to Handoff iOS documentation for more details.
  • Siri на Mac -Siri использует текущее действие (NSUserActivity) для поддержки контекста команды, пользователь может выдавать.Siri on Mac - Siri uses the Current Activity (NSUserActivity) to provide context to the commands a user can issue.
  • Состояние восстановления — когда пользователь завершает работу приложения в Mac OS, а потом перезапуска его, приложение будет автоматически возвращается в предыдущее состояние.State Restoration - When the user quits an app on macOS and then later relaunches it, the app will automatically be returned to its previous state. Разработчик может использовать API восстановления состояния для кодирования и восстановить Переходные состояния пользовательского интерфейса перед отображением пользовательского интерфейса для пользователя.The developer can use the State Restoration API to encode and restore transient UI states before the User Interface is displayed to the user. Если приложение является NSDocument зависимости, восстановление состояния обрабатывается автоматически.If the app is NSDocument based, State Restoration is handled automatically. Чтобы включить восстановление состояния для отличныхNSDocument зависимости приложения задать Restorable из NSWindow класс true.To enable State Restoration for non-NSDocument based apps, set the Restorable of the NSWindow class to true.
  • Документы в облаке -до macOS Sierra, приложению должны были явно согласиться на работе с документами в пользователя iCloud Drive.Documents in the Cloud - Prior to macOS Sierra, an app had to explicitly opt-in to working with documents in the user's iCloud Drive. В macOS Sierra пользователь в Desktop и документов папки могут быть синхронизированы с их iCloud Drive автоматически системой.In macOS Sierra the user's Desktop and Documents folders may be synced with their iCloud Drive automatically by the system. В результате локальные копии документов могут быть удалены, чтобы освободить место на компьютере пользователя.As a result, local copies of documents may be deleted to free up space on the user's machine. NSDocument на основе приложений автоматически обработает это изменение.NSDocument based apps will automatically handle this change. Все другие типы приложений потребуется использовать NSFileCoordinator синхронизировать чтения и записи документов.All other app types will need to use a NSFileCoordinator to sync reading and writing of documents.

СводкаSummary

В этой статье подробно рассматривается несколько советов, возможности и методы, разработчик может использовать для создания приложения на основе современных macOS в Xamarin.Mac.This article has covered several tips, features and techniques a developer can use to build a modern macOS app in Xamarin.Mac.