Vytváření moderních aplikací macOS

Tento článek popisuje několik tipů, funkcí a technik, které vývojář může použít k vytvoření moderní aplikace pro macOS v Xamarin.Mac.

Moderní vzhled budovy s moderním výhledem

Moderní vzhled bude obsahovat moderní vzhled okna a panelu nástrojů, například ukázkovou aplikaci zobrazenou níže:

An example of a modern Mac app UI

Povolení zobrazení obsahu v plné velikosti

Aby toho bylo možné dosáhnout v aplikaci Xamarin.Mac, bude vývojář chtít použít zobrazení obsahu s plnou velikostí, což znamená, že obsah se rozšiřuje pod oblastmi nástroje a záhlaví a bude automaticky rozmazaný macOS.

Pokud chcete tuto funkci povolit v kódu, vytvořte pro ni NSWindowController vlastní třídu a udělejte ji takto:

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
    }
}

Tuto funkci lze také povolit v Tvůrci rozhraní Xcode tak, že vyberete okno a zkontrolujete zobrazení obsahu v plné velikosti:

Editing the main storyboard in Xcode's Interface Builder

Při použití zobrazení obsahu s plnou velikostí může vývojář odsazovat obsah pod oblastmi záhlaví a panelu nástrojů tak, aby se pod nimi konkrétní obsah (například popisky) nepřesunul.

Aby se tento problém komplikoval, můžou mít oblasti záhlaví a panelu nástrojů dynamickou výšku na základě akce, kterou uživatel právě provádí, verzi systému macOS, na které je uživatel nainstalovaný, nebo hardwaru Mac, na kterém je aplikace spuštěná.

V důsledku toho jednoduché kódování posunu při rozložení uživatelského rozhraní nebude fungovat. Vývojář bude muset provést dynamický přístup.

Společnost Apple zahrnula vlastnost NSWindow Key-Value ObservableContentLayoutRect třídy pro získání aktuální oblasti obsahu v kódu. Vývojář může tuto hodnotu použít k ručnímu umístění požadovaných prvků při změně oblasti obsahu.

Lepším řešením je použít třídy automatického rozložení a velikosti k umístění prvků uživatelského rozhraní v kódu nebo Tvůrci rozhraní.

Kód podobný následujícímu příkladu se dá použít k umístění prvků uživatelského rozhraní pomocí třídy AutoLayout a Size Classes v kontroleru zobrazení aplikace:

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
    }
}

Tento kód vytvoří úložiště pro horní omezení, které se použije u popisku (ItemTitle), aby se zajistilo, že se neproklouzne pod oblast záhlaví a panelu nástrojů:

public NSLayoutConstraint topConstraint { get; set; }

Přepsáním metody Kontroleru UpdateViewConstraints zobrazení může vývojář otestovat, jestli už bylo vytvořené potřebné omezení, a v případě potřeby ho vytvořit.

Pokud je potřeba vytvořit nové omezení, vlastnost Okna ovládací prvek, který musí být omezen, ContentLayoutGuide je přístupný a přetypován do NSLayoutGuide:

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

Vlastnost TopAnchor je NSLayoutGuide přístupná a pokud je k dispozici, slouží k sestavení nového omezení s požadovanou velikost posunu a nové omezení je aktivní, aby ho bylo možné použít:

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

Povolení zjednodušených panelů nástrojů

Normální okno macOS zahrnuje standardní záhlaví při spuštění podél horního okraje okna. Pokud okno obsahuje také panel nástrojů, zobrazí se pod touto oblastí záhlaví:

A standard Mac Toolbar

Při použití zjednodušeného panelu nástrojů zmizí oblast nadpisu a panel nástrojů se přesune nahoru na pozici záhlaví, v řádku s tlačítky Zavřít okno, Minimalizovat a Maximalizovat:

A streamlined Mac Toolbar

Zjednodušený panel nástrojů je povolen přepsáním ViewWillAppear metody NSViewController a tím, že bude vypadat takto:

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

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

Tento efekt se obvykle používá pro aplikace Shoebox (jedno okno), jako jsou Mapy, Kalendář, Poznámky a Předvolby systému.

Použití kontrolerů zobrazení přístupového objektu

V závislosti na návrhu aplikace může vývojář také chtít doplnit oblast Záhlaví kontrolerem zobrazení příslušenství, který se zobrazí přímo pod oblastí Záhlaví nebo panel nástrojů, aby uživateli poskytl kontextové citlivé ovládací prvky na základě aktivity, ve které se právě zabývá:

An example Accessory View Controller

Kontroler zobrazení přístupového objektu bude automaticky rozmazaný a změní velikost systému bez zásahu vývojáře.

Chcete-li přidat kontroler zobrazení přístupového objektu, postupujte takto:

  1. V Průzkumník řešení poklikáním Main.storyboard otevřete soubor pro úpravy.

  2. Přetáhněte vlastní kontroler zobrazení do hierarchie okna:

    Adding a new Custom View Controller

  3. Rozložení uživatelského rozhraní zobrazení přístupového objektu:

    Designing the new view

  4. Zobrazení přístupového objektu zpřístupňte jako výstup a všechny další akce nebo výstupy pro své uživatelské rozhraní:

    Adding the required OUtlet

  5. Uložte změny.

  6. Vraťte se do Visual Studio pro Mac, aby se změny synchronizovaly.

NSWindowController Upravte a udělejte ho takto:

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
    }
}

Klíčové body tohoto kódu jsou místo, kde je zobrazení nastaveno na vlastní zobrazení, které bylo definováno v Tvůrci rozhraní a vystaveno jako výstup:

accessoryView.View = AccessoryViewGoBar;

LayoutAttribute A ten definuje, kde se bude zobrazovat příslušenství:

accessoryView.LayoutAttribute = NSLayoutAttribute.Bottom;

Vzhledem k tomu, že macOS je nyní plně lokalizovaný, Left byly a RightNSLayoutAttribute vlastnosti zastaralé a měly by být nahrazeny Leading a Trailing.

Použití oken s kartami

Systém macOS navíc může do okna aplikace přidat kontrolery zobrazení přístupového objektu. Pokud chcete například vytvořit Okna s kartami, ve kterých se několik aplikací sloučí do jednoho virtuálního okna:

An example of a tabbed Mac Window

Vývojář obvykle bude muset ve svých aplikacích Xamarin.Mac použít v aplikacích Xamarin.Mac omezené akce, systém je zpracuje automaticky následujícím způsobem:

  • Systém Windows se při vyvolání metody automaticky vypíše tabulátorem OrderFront .
  • Systém Windows se OrderOut při vyvolání metody automaticky zruší.
  • V kódu jsou všechna okna s kartami stále považována za "viditelná", ale všechny karty, které nejsou na přední straně, jsou systémem skryty pomocí CoreGraphics.
  • TabbingIdentifier Pomocí vlastnosti NSWindow seskupit okna do karet.
  • Pokud se jedná o aplikaci založenou NSDocument na aplikaci, bude několik těchto funkcí povoleno automaticky (například tlačítko plus přidané na panel karet) bez jakékoli akce vývojáře.
  • NSDocument Aplikace, které nejsou založené, mohou povolit tlačítko plus ve skupině karet přidat nový dokument přepsáním GetNewWindowForTab metody NSWindowsController.

Spojení všech částí dohromady může aplikace, AppDelegate která chtěla používat systémová okna s kartami, vypadat takto:

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 Kde vlastnost sleduje počet nových dokumentů vytvořených a NewDocument metoda vytvoří nový dokument a zobrazí ho.

Pak NSWindowController by to mohlo vypadat takto:

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
    }
}

Kde statická App vlastnost poskytuje zástupce pro přístup k objektu AppDelegate. Metoda SetDefaultDocumentTitle nastaví název nových dokumentů na základě počtu vytvořených nových dokumentů.

Následující kód říká macOS, že aplikace dává přednost používání karet a poskytuje řetězec, který umožňuje seskupit Windows aplikace do karet:

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

Následující metoda přepsání přidá na panel karet tlačítko plus, které při kliknutí uživatelem vytvoří nový dokument:

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

Použití základní animace

Základní animace je vysoce výkonný grafický vykreslovací modul, který je integrovaný do macOS. Základní animace je optimalizovaná tak, aby využívala gpu (grafický procesor) dostupný v moderním hardwaru macOS, a ne na spouštění grafických operací na procesoru, což může počítač zpomalit.

Nástroj CALayer, který poskytuje základní animace, lze použít pro úlohy, jako jsou rychlé a fluidní posouvání a animace. Uživatelské rozhraní aplikace by se mělo skládat z několika dílčích zobrazení a vrstev, aby plně využívaly základní animace.

Objekt CALayer poskytuje několik vlastností, které vývojáři umožňují řídit, co se zobrazí na obrazovce uživateli, například:

  • Content - Může to být NSImage obsah vrstvy nebo CGImage který poskytuje obsah.
  • BackgroundColor - Nastaví barvu pozadí vrstvy jako CGColor
  • BorderWidth - Nastaví šířku ohraničení.
  • BorderColor - Nastaví barvu ohraničení.

Aby bylo možné využívat základní grafiku v uživatelském rozhraní aplikace, musí používat zobrazení s podporou vrstvy, což Apple naznačuje, že vývojář by měl v zobrazení obsahu okna vždy povolit. Tímto způsobem budou všechna podřízená zobrazení automaticky dědit i backing vrstvy.

Kromě toho Apple navrhuje, aby na rozdíl od přidání nového CALayer podvrtu používala zobrazení vrstvy, protože systém bude automaticky zpracovávat několik požadovaných nastavení (například těch, které vyžaduje displej Sítnice).

Backing vrstvy je možné povolit tak, že v nástroji View Effects Inspector nastavíte WantsLayerNSView v true tvůrci rozhraní Xcode nebo uvnitř něj kontrolu základní animační vrstvy:

The View Effects Inspector

Překreslení zobrazení s vrstvami

Dalším důležitým krokem při použití zobrazení založených na vrstvě v aplikaci Xamarin.Mac je nastavení LayerContentsRedrawPolicyNSView na OnSetNeedsDisplayNSViewController Příklad:

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

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

Pokud vývojář tuto vlastnost nenastaví, bude zobrazení překresleno při každé změně původu snímku, což není žádoucí z důvodů výkonu. S touto vlastností nastavenou pro OnSetNeedsDisplay vývojáře bude nutné ručně nastavit NeedsDisplay , aby true se obsah překreslil, ale.

Když je zobrazení označeno jako špinavé, systém zkontroluje WantsUpdateLayer vlastnost Zobrazení. Pokud vrátí true , UpdateLayer je volána metoda, jinak DrawRect je volána metoda View aktualizovat obsah zobrazení.

Apple v případě potřeby nabízí následující návrhy pro aktualizaci obsahu zobrazení:

  • Apple preferuje používání UpdateLater před DrawRect tím, kdy je to možné, protože poskytuje výrazné zvýšení výkonu.
  • layer.Contents Totéž použijte pro prvky uživatelského rozhraní, které vypadají podobně.
  • Apple také dává vývojáři přednost vytvoření uživatelského rozhraní pomocí standardních zobrazení, jako NSTextFieldje , a to kdykoli je to možné.

Pokud chcete použít UpdateLayer, vytvořte vlastní třídu pro kód NSView a nastavte, aby kód vypadal takto:

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
    }
}

Použití moderního přetažení

Aby vývojář uživatelům představil moderní prostředí pro přetahování, měl by v operacích Přetažení a přetažení aplikace přijmout přetahování myší. Přetažení hejna je místo, kde se každý jednotlivý soubor nebo položka přetahované zpočátku zobrazí jako jednotlivý prvek, který seskupí (seskupí pod kurzorem s počtem položek), protože uživatel pokračuje v operaci přetažení.

Pokud uživatel ukončí operaci Přetažení, jednotlivé prvky se zruší a vrátí se do původních umístění.

Následující příklad kódu umožňuje drag Hejno ve vlastním zobrazení:

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
    }
}

Efekt hejna byl dosažen odesláním každé položky, která je přetažena do BeginDraggingSession metody NSView jako samostatného prvku v poli.

Při práci s objektem NSTableView nebo NSOutlineViewpomocí PastboardWriterForRow metody NSTableViewDataSource třídy spusťte operaci Přetahování:

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
    }
}

Vývojář tak může poskytnout jednotlivce NSDraggingItem pro každou položku v tabulce, která se přetahuje, a ne starší metodu WriteRowsWith , která zapisuje všechny řádky jako jednu skupinu do pasteboardu.

Při práci s NSCollectionViews, znovu použít metodu PasteboardWriterForItemAtWriteItemsAt na rozdíl od metody při Přetažení začíná.

Vývojář by se měl vždy vyhnout vkládání velkých souborů na pasteboard. Novinka v macOS Sierra, File Promises umožňují vývojáři umístit odkazy na dané soubory na pasteboard, který se později splní, když uživatel dokončí operaci drop pomocí nových NSFilePromiseProvider a NSFilePromiseReceiver tříd.

Používání moderního sledování událostí

U prvku uživatelského rozhraní (například NSButton) přidaného do oblasti Záhlaví nebo Panel nástrojů by měl uživatel kliknout na prvek a nechat ho aktivovat jako normální (například zobrazení automaticky otevíraného okna). Vzhledem k tomu, že položka je také v oblasti záhlaví nebo panelu nástrojů, uživatel by měl být schopen kliknout a přetáhnout prvek, aby se také okno přesunulo.

Chcete-li toho dosáhnout v kódu, vytvořte vlastní třídu pro element (například NSButton) a přepište MouseDown událost následujícím způsobem:

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);
    }
}

Tento kód používá TrackEventsMatching metodu NSWindow , kterou je prvek uživatelského rozhraní připojen k zachycení LeftMouseUp událostí a LeftMouseDragged událostí. LeftMouseUp U události element uživatelského rozhraní reaguje normálně. LeftMouseDragged U události se událost předá NSWindowPerformWindowDrag metodě pro přesunutí okna na obrazovce.

PerformWindowDrag Volání metody NSWindow třídy poskytuje následující výhody:

  • Umožňuje, aby se okno přesunulo, i když je aplikace zablokovaná (například při zpracování hluboké smyčky).
  • Přepínání místa bude fungovat podle očekávání.
  • Panel Mezery se zobrazí jako normální.
  • Přichycení a zarovnání okna funguje normálně.

Použití moderních ovládacích prvků zobrazení kontejneru

macOS Sierra nabízí mnoho moderních vylepšení stávajících ovládacích prvků zobrazení kontejnerů, které jsou k dispozici v předchozí verzi operačního systému.

Vylepšení zobrazení tabulky

Vývojář by měl vždy používat novou NSView verzi ovládacích prvků zobrazení kontejneru, jako NSTableViewje . Příklad:

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
    }
}

To umožňuje připojit vlastní akce řádků tabulky k daným řádkům v tabulce (například potáhnutím prstem doprava odstranit řádek). Chcete-li toto chování povolit, přepište metodu RowActionsNSTableViewDelegate:

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
    }
}

Static NSTableViewRowAction.FromStyle se používá k vytvoření nové akce řádku tabulky s následujícími styly:

  • Regular – Provede standardní nedestruktivní akci, jako je úprava obsahu řádku.
  • Destructive – Provede destruktivní akci, jako je odstranění řádku z tabulky. Tyto akce se vykreslí červeným pozadím.

Vylepšení zobrazení pro posouvání

Při použití zobrazení pro posouvání (NSScrollView) přímo nebo jako součást jiného ovládacího prvku (například NSTableView) se obsah zobrazení posuvníku může posunout pod oblasti záhlaví a panelu nástrojů v aplikaci Xamarin.Mac pomocí moderního vzhledu a zobrazení.

V důsledku toho může být první položka v oblasti obsahu Zobrazení posuvníku částečně zakrytá oblastí Záhlaví a Panel nástrojů.

Pro opravu tohoto problému společnost Apple přidala do NSScrollView třídy dvě nové vlastnosti:

  • ContentInsets - Umožňuje vývojáři poskytnout NSEdgeInsets objekt definující posun, který se použije na začátek zobrazení posouvání.
  • AutomaticallyAdjustsContentInsets - Pokud true se zobrazení posuvníku ContentInsets automaticky zpracuje pro vývojáře.

Pomocí ContentInsets vývojáři můžete upravit začátek zobrazení posuvníku, aby bylo možné zahrnout příslušenství, jako například:

  • Indikátor řazení, jako je ten zobrazený v aplikaci Pošta.
  • Vyhledávací pole.
  • Tlačítko Aktualizovat nebo Aktualizovat

Automatické rozložení a lokalizace v moderních aplikacích

Společnost Apple zahrnula do Xcode několik technologií, které vývojářům umožňují snadno vytvořit mezinárodní aplikaci pro macOS. Xcode teď umožňuje vývojáři oddělit uživatelem orientovaný text od návrhu uživatelského rozhraní aplikace v souborech storyboardu a poskytuje nástroje pro zachování tohoto oddělení, pokud uživatelské rozhraní změní.

Další informace najdete v průvodci internationalizací a lokalizací společnosti Apple.

Implementace základní internationalizace

Implementací základní internationalizace může vývojář poskytnout jeden soubor Storyboard, který představuje uživatelské rozhraní aplikace a oddělit všechny uživatelem přístupné řetězce.

Když vývojář vytváří počáteční soubor storyboardu (nebo soubory), které definují uživatelské rozhraní aplikace, budou sestaveny v základní internationalizaci (jazyk, který vývojář mluví).

Dále může vývojář exportovat lokalizace a základní řetězce internationalizace (v návrhu uživatelského rozhraní storyboardu), které lze přeložit do více jazyků.

Později je možné tyto lokalizace importovat a Xcode vygeneruje soubory řetězců specifické pro jazyk pro Storyboard.

Implementace automatického rozložení pro podporu lokalizace

Vzhledem k tomu, že lokalizované verze řetězcových hodnot můžou mít výrazně odlišné velikosti nebo směr čtení, měl by vývojář použít automatické rozložení k umístění a velikosti uživatelského rozhraní aplikace v souboru scénáře.

Apple navrhuje následující:

  • Odebrat omezení s pevnou šířkou – Všechna textová zobrazení by měla mít povoleno měnit velikost na základě jejich obsahu. Zobrazení s pevnou šířkou může oříznout jejich obsah v konkrétních jazycích.
  • Použití vnitřních velikostí obsahu – Ve výchozím nastavení se textová zobrazení automaticky přizpůsobí jejich obsahu. Pro textové zobrazení, které nejsou správně dimenzované, vyberte je v Tvůrci rozhraní Xcode a pak zvolte Upravit>velikost přizpůsobit obsah.
  • Použít úvodní a koncové atributy – vzhledem k tomu, že směr textu se může změnit na základě jazyka uživatele, použijte nové Leading a Trailing omezující atributy na rozdíl od existujících Right a Left atributů. Leading a Trailing automaticky se upraví na základě směru jazyků.
  • Připnout zobrazení k sousedním zobrazením – Zobrazení se tak dají přemístit a změnit jejich velikost v reakci na vybraný jazyk.
  • Nenastavujte minimální nebo maximální velikosti Windows – Umožňuje systému Windows změnit velikost, když vybraný jazyk změní velikost oblastí obsahu.
  • Neustále se mění rozložení testů – během vývoje v aplikaci by se měly testovat v různých jazycích. Další podrobnosti najdete v dokumentaci k testování vaší mezinárodní aplikace společnosti Apple.
  • Použití NSStackViews k připnutí zobrazení dohromady - NSStackViews umožňuje jejich obsah posunout a růst předvídatelným způsobem a změnit velikost obsahu na základě vybraného jazyka.

Lokalizace v Tvůrci rozhraní Xcode

Apple poskytuje několik funkcí v Tvůrci rozhraní Xcode, které může vývojář použít při návrhu nebo úpravě uživatelského rozhraní aplikace pro podporu lokalizace. Část Směr textu v inspektoru atributů umožňuje vývojáři poskytnout informace o tom, jak se má směr použít a aktualizovat ve vybraném zobrazení na základě textu (napříkladNSTextField):

The Text Direction options

Směr textu má tři možné hodnoty:

  • Přirozené – Rozložení je založeno na řetězci přiřazeného ovládacímu prvku.
  • Zleva doprava – Rozložení je vždy nuceno zleva doprava.
  • Zprava doleva – rozložení je vždy nuceno zprava doleva.

Rozložení má dvě možné hodnoty:

  • Zleva doprava – Rozložení je vždy zleva doprava.
  • Zprava doleva – Rozložení je vždy zprava doleva.

Obvykle by se nemělo měnit, pokud není vyžadováno konkrétní zarovnání.

Vlastnost Mirror říká systému, aby překlopil specifické vlastnosti ovládacího prvku (například umístění obrázku buňky). Má tři možné hodnoty:

  • Automaticky – Pozice se automaticky změní podle směru vybraného jazyka.
  • V rozhraní zprava doleva – Pozice se změní pouze v jazycích založených na zprava doleva.
  • Nikdy - Pozice se nikdy nezmění.

Pokud vývojář zadal Střed, Zarovnání do bloku nebo Úplné zarovnání obsahu textového zobrazení, nikdy se nepřeklopí na základě vybraného jazyka.

Před macOS Sierra se ovládací prvky vytvořené v kódu nebudou zrcadlit automaticky. Vývojář musel pro zpracování zrcadlení použít kód podobný následujícímu:

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;
    }
}

Kde je Alignment ovládací prvek nastavený a ImagePosition je nastaven na UserInterfaceLayoutDirection základě ovládacího prvku.

macOS Sierra přidává několik nových konstruktorů pohodlí (prostřednictvím statické CreateButton metody), které přebírají několik parametrů (například Název, Obrázek a Akce) a automaticky se zrcadlí správně. Příklad:

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

Použití vzhledů systému

Moderní aplikace pro macOS můžou využívat nový vzhled tmavého rozhraní, který je vhodný pro vytváření, úpravy nebo prezentační aplikace:

An example of a dark Mac Window UI

Můžete to udělat tak, že před zobrazením okna přidáte jeden řádek kódu. Příklad:

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
    }
}

Statická GetAppearance metoda NSAppearance třídy se používá k získání pojmenovaného vzhledu ze systému (v tomto případě NSAppearance.NameVibrantDark).

Apple nabízí následující návrhy pro používání vzhledů systému:

  • Preferujte pojmenované barvy před pevně zakódovanými hodnotami (například LabelColor a SelectedControlColor).
  • Pokud je to možné, použijte standardní styl ovládacího prvku systému.

Aplikace pro macOS, která používá vzhledy systému, bude automaticky fungovat pro uživatele, kteří mají povolené funkce přístupnosti z aplikace Předvolby systému. Apple proto navrhuje, aby vývojář ve svých aplikacích pro macOS vždy používal vzhledy systému.

Navrhování uživatelských rozhraní s využitím scénářů

Scénáře umožňují vývojářům navrhovat nejen jednotlivé prvky, které tvoří uživatelské rozhraní aplikace, ale vizualizovat a navrhovat tok uživatelského rozhraní a hierarchii daných prvků.

Kontrolery umožňují vývojářům shromažďovat prvky do jednotky složení a Segues abstraktní a odebrat typický "připevněný kód" potřebný k pohybu v hierarchii zobrazení:

Editing the UI in Xcode's Interface Builder

Další informace najdete v naší dokumentaci úvodu ke scénářům .

Existuje mnoho případů, kdy daná scéna definovaná ve scénáři bude vyžadovat data z předchozí scény v hierarchii zobrazení. Apple nabízí následující návrhy pro předávání informací mezi scénami:

  • Data dependancies by měla vždy kaskádovat směrem dolů přes hierarchii.
  • Vyhněte se strukturálním závislostem uživatelského rozhraní pevně zakódování, protože to omezuje flexibilitu uživatelského rozhraní.
  • Pomocí rozhraní jazyka C# můžete poskytovat obecná data dependancies.

View Controller, který funguje jako zdroj Segue, může přepsat PrepareForSegue metodu a provést jakékoli inicializace požadované (například předávání dat) před spuštěním Segue zobrazit cílový kontroler zobrazení. Příklad:

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;
    }
}

Další informace najdete v naší dokumentaci k segues .

Šíření akcí

Na základě návrhu aplikace pro macOS může být někdy nejlepší obslužná rutina pro akci na ovládacím prvku uživatelského rozhraní na jiném místě v hierarchii uživatelského rozhraní. To obvykle platí pro nabídky a položky nabídek, které žijí ve své vlastní scéně, odděleně od zbytku uživatelského rozhraní aplikace.

Aby se tato situace zvládla, může vývojář vytvořit vlastní akci a předat akci do řetězu respondérů. Další informace najdete v dokumentaci k práci s akcemi vlastních oken .

Moderní funkce Macu

Společnost Apple zahrnula několik uživatelských funkcí v systému macOS Sierra, které vývojářům umožňují využívat většinu platformy Mac, například:

  • NSUserActivity – To aplikaci umožňuje popsat aktivitu, do které se uživatel aktuálně zapojuje. NSUserActivity byl původně vytvořen pro podporu HandOff, kde se mohla aktivita spuštěná na jednom ze zařízení uživatele vyzvednout a pokračovat na jiném zařízení. NSUserActivity funguje stejně v macOS jako v iOSu, takže další podrobnosti najdete v naší dokumentaci Úvod k předání iOS.
  • Siri na Macu – Siri používá aktuální aktivitu (NSUserActivity) k poskytnutí kontextu příkazů, které může uživatel vydat.
  • Obnovení stavu – Když uživatel ukončí aplikaci v systému macOS a později ji znovu odešle, aplikace se automaticky vrátí do předchozího stavu. Vývojář může pomocí rozhraní API pro obnovení stavu kódovat a obnovit přechodné stavy uživatelského rozhraní před zobrazením uživatelského rozhraní uživateli. Pokud je NSDocument aplikace založená, obnovení stavu se zpracuje automaticky. Chcete-li povolit obnovení stavu pro jinéNSDocument než založené aplikace, nastavte Restorable třídu NSWindow na true.
  • Dokumenty v cloudu – Před macOS Sierra musela aplikace explicitně vyjádřit výslovný souhlas s prací s dokumenty na iCloud Disku uživatele. V systému macOS Sierra se složky Desktop a Documents uživatele můžou automaticky synchronizovat se svým iCloud Drivem. V důsledku toho je možné odstranit místní kopie dokumentů, aby se uvolnilo místo na počítači uživatele. NSDocument aplikace založené na aplikacích budou tuto změnu automaticky zpracovávat. Všechny ostatní typy aplikací budou muset používat NSFileCoordinator k synchronizaci čtení a zápisu dokumentů.

Shrnutí

Tento článek popisuje několik tipů, funkcí a technik, které vývojář může použít k vytvoření moderní aplikace pro macOS v Xamarin.Mac.