Condividi tramite


Immagini in Xamarin.Mac

Questo articolo illustra l'uso di immagini e icone in un'applicazione Xamarin.Mac. Descrive la creazione e la gestione delle immagini necessarie per creare l'icona dell'applicazione e l'uso di immagini sia nel codice C# che in Interface Builder di Xcode.

Panoramica

Quando si lavora con C# e .NET in un'applicazione Xamarin.Mac, è possibile accedere agli stessi strumenti Image e Icon usati da uno sviluppatore in Objective-C e Xcode .

Esistono diversi modi in cui gli asset di immagine vengono usati all'interno di un'applicazione macOS (in precedenza nota come Mac OS X). Dalla semplice visualizzazione di un'immagine come parte dell'interfaccia utente dell'applicazione a, assegnandola a un controllo dell'interfaccia utente, ad esempio una barra degli strumenti o un elemento elenco di origine, per fornire icone, Xamarin.Mac semplifica l'aggiunta di immagini eccezionali alle applicazioni macOS nei modi seguenti:

  • Elementi dell'interfaccia utente: le immagini possono essere visualizzate come sfondi o come parte dell'applicazione in una visualizzazione immagini (NSImageView).
  • Pulsante : le immagini possono essere visualizzate nei pulsanti (NSButton).
  • Cella immagine: come parte di un controllo basato su tabella (NSTableView o NSOutlineView), le immagini possono essere usate in una cella image (NSImageCell).
  • Elemento della barra degli strumenti: le immagini possono essere aggiunte a una barra degli strumenti (NSToolbar) come elemento della barra degli strumenti immagine (NSToolbarItem).
  • Icona elenco di origine - Come parte di un elenco di origine (un formato speciale NSOutlineView).
  • Icona dell'app: una serie di immagini può essere raggruppata in un .icns set e usata come icona dell'applicazione. Per altre informazioni, vedere la documentazione relativa all'icona dell'applicazione .

MacOS offre inoltre un set di immagini predefinite che possono essere usate in tutta l'applicazione.

Esempio di esecuzione dell'app

In questo articolo verranno illustrate le nozioni di base sull'uso di immagini e icone in un'applicazione Xamarin.Mac. È consigliabile usare prima di tutto l'articolo Hello, Mac , in particolare le sezioni Introduzione a Xcode e Interface Builder e Outlet e Actions , in quanto illustra i concetti e le tecniche chiave che verranno usati in questo articolo.

Aggiunta di immagini a un progetto Xamarin.Mac

Quando si aggiunge un'immagine da usare in un'applicazione Xamarin.Mac, esistono diverse posizioni e modi in cui lo sviluppatore può includere il file di immagine nell'origine del progetto:

  • Albero del progetto principale [deprecato] - Le immagini possono essere aggiunte direttamente all'albero dei progetti. Quando si chiamano immagini archiviate nell'albero del progetto principale dal codice, non viene specificato alcun percorso della cartella. Ad esempio: NSImage image = NSImage.ImageNamed("tags.png");.
  • Cartella Resources [deprecata] - La cartella Risorse speciale è destinata a qualsiasi file che diventerà parte del bundle dell'applicazione, ad esempio Icona, Schermata di avvio o immagini generali (o qualsiasi altra immagine o file che lo sviluppatore desidera aggiungere). Quando si chiamano immagini archiviate nella cartella Resources dal codice, proprio come le immagini archiviate nell'albero principale del progetto, non viene specificato alcun percorso della cartella. Ad esempio: NSImage.ImageNamed("tags.png").
  • Cartella personalizzata o sottocartella [deprecata] - Lo sviluppatore può aggiungere una cartella personalizzata all'albero di origine dei progetti e archiviare le immagini. Il percorso in cui viene aggiunto il file può essere annidato in una sottocartella per facilitare ulteriormente l'organizzazione del progetto. Ad esempio, se lo sviluppatore ha aggiunto una Card cartella al progetto e una sottocartella di Hearts a tale cartella, archiviare un'immagine Jack.png nella Hearts cartella, NSImage.ImageNamed("Card/Hearts/Jack.png") caricare l'immagine in fase di esecuzione.
  • Set di immagini del catalogo asset [preferito] - Aggiunta in OS X El Capitan, i set di immagini dei cataloghi asset contengono tutte le versioni o le rappresentazioni di un'immagine necessarie per supportare vari dispositivi e fattori di scala per l'applicazione. Invece di basarsi sul nome file degli asset di immagine (@1x, @2x).

Aggiunta di immagini a un set di immagini del catalogo di asset

Come indicato in precedenza, un set di immagini del catalogo asset contiene tutte le versioni o le rappresentazioni di un'immagine necessarie per supportare vari dispositivi e fattori di scala per l'applicazione. Invece di basarsi sul nome file degli asset di immagine (vedere le immagini indipendenti di risoluzione e la classificazione delle immagini precedente), i set di immagini usano l'editor di asset per specificare l'immagine a cui appartiene il dispositivo e/o la risoluzione.

  1. Nel riquadro della soluzione fare doppio clic sul file Assets.xcassets per aprirlo per la modifica:

    Selezione di Assets.xcassets

  2. Fare clic con il pulsante destro del mouse sull'elenco asset e scegliere Nuovo set di immagini:

    Aggiunta di un nuovo set di immagini

  3. Selezionare il nuovo set di immagini e verrà visualizzato l'editor:

    Selezione del nuovo set di immagini

  4. Da qui è possibile trascinare le immagini per ognuno dei diversi dispositivi e risoluzioni necessari.

  5. Fare doppio clic sul nome del nuovo set di immagini nell'elenco asset per modificarlo:

    Modifica del nome del set di immagini

Classe Vector speciale aggiunta a Set di immagini che consente di includere un'immagine vettoriale in formato PDF nella cassat, includendo invece singoli file bitmap con le diverse risoluzioni. Usando questo metodo, si fornisce un singolo file vettoriale per la risoluzione @1x (formattato come file PDF vettoriale) e le @2x e le versioni @3x del file verranno generate in fase di compilazione e incluse nel bundle dell'applicazione.

Interfaccia dell'editor del set di immagini

Ad esempio, se si include un MonkeyIcon.pdf file come vettore di un catalogo asset con una risoluzione di 150px x 150px, gli asset bitmap seguenti verranno inclusi nel bundle dell'app finale al momento della compilazione:

  1. MonkeyIcon@1x.png - Risoluzione 150px x 150px.
  2. MonkeyIcon@2x.png - Risoluzione 300px x 300px.
  3. MonkeyIcon@3x.png - Risoluzione 450px x 450px.

Quando si usano immagini vettoriali PDF nei cataloghi di asset, tenere in considerazione quanto segue:

  • Questo non è il supporto del vettore completo perché il PDF verrà rasterizzato in una bitmap in fase di compilazione e le bitmap fornite nell'applicazione finale.
  • Non è possibile modificare le dimensioni dell'immagine dopo che è stata impostata nel Catalogo asset. Se si tenta di ridimensionare l'immagine (nel codice o usando classi di layout automatico e dimensioni), l'immagine verrà distorta esattamente come qualsiasi altra bitmap.

Quando si usa un set di immagini in Interface Builder di Xcode, è sufficiente selezionare il nome del set dall'elenco a discesa in Controllo attributi:

Selezione di un set di immagini in Interface Builder di Xcode

Aggiunta di nuove raccolte di asset

Quando si lavora con le immagini nei cataloghi asset, potrebbero verificarsi momenti in cui si vuole creare una nuova raccolta, invece di aggiungere tutte le immagini all'insieme Assets.xcassets . Ad esempio, quando si progettano risorse su richiesta.

Per aggiungere un nuovo catalogo asset al progetto:

  1. Fare clic con il pulsante destro del mouse sul progetto nel riquadro della soluzione e scegliere Aggiungi>nuovo file...

  2. Selezionare Catalogo asset Mac>, immettere un nome per la raccolta e fare clic sul pulsante Nuovo:

    Aggiunta di un nuovo catalogo asset

Da qui è possibile usare la raccolta nello stesso modo dell'insieme Assets.xcassets predefinito incluso automaticamente nel progetto.

Aggiunta di immagini alle risorse

Importante

Questo metodo di utilizzo delle immagini in un'app macOS è stato deprecato da Apple. Devi invece usare i set di immagini del catalogo asset per gestire le immagini dell'app.

Prima di poter usare un file di immagine nell'applicazione Xamarin.Mac (nel codice C# o da Interface Builder) deve essere incluso nella cartella Risorse del progetto come risorsa bundle. Per aggiungere un file a un progetto, eseguire le operazioni seguenti:

  1. Fare clic con il pulsante destro del mouse sulla cartella Risorse nel progetto nel riquadro della soluzione e scegliere Aggiungi>file...:

    Aggiunta di un file

  2. Nella finestra di dialogo Aggiungi file selezionare i file di immagini da aggiungere al progetto, selezionare BundleResource per l'azioneSostituisci compilazione e fare clic sul pulsante Apri:

    Selezione dei file da aggiungere

  3. Se i file non sono già presenti nella cartella Risorse, verrà chiesto se si desidera copiare, spostare o collegare i file. Scegli quali sono le tue esigenze, in genere copia:

    Selezione dell'azione di aggiunta

  4. I nuovi file verranno inclusi nel progetto e letti per l'uso:

    I nuovi file di immagine aggiunti al riquadro della soluzione

  5. Ripetere il processo per tutti i file di immagine necessari.

È possibile usare qualsiasi file png, jpg o pdf come immagine di origine nell'applicazione Xamarin.Mac. Nella sezione successiva si esaminerà l'aggiunta di versioni ad alta risoluzione delle immagini e delle icone per supportare i Mac basati su Retina.

Importante

Se si aggiungono immagini alla cartella Risorse, è possibile lasciare l'azione di compilazione Override impostata su Predefinito. L'azione di compilazione predefinita per questa cartella è BundleResource.

Fornire versioni ad alta risoluzione di tutte le risorse grafiche dell'app

Qualsiasi asset grafico aggiunto a un'applicazione Xamarin.Mac (icone, controlli personalizzati, cursori personalizzati, grafica personalizzata e così via) deve avere versioni ad alta risoluzione oltre alle versioni a risoluzione standard. Questo è necessario in modo che l'applicazione avrà un aspetto migliore quando viene eseguito su un computer Mac dotato di Display Retina.

Adottare la convenzione di denominazione @2x

Importante

Questo metodo di utilizzo delle immagini in un'app macOS è stato deprecato da Apple. Devi invece usare i set di immagini del catalogo asset per gestire le immagini dell'app.

Quando si creano le versioni standard e ad alta risoluzione di un'immagine, seguire questa convenzione di denominazione per la coppia di immagini quando vengono incluse nel progetto Xamarin.Mac:

  • Standard-Resolution - ImageName.filename-extension (esempio: tags.png)
  • Estensione ad alta risoluzione - ImageName@2x.filename (esempio: ) tags@2x.png

Quando vengono aggiunti a un progetto, vengono visualizzati come segue:

File di immagine nel riquadro della soluzione

Quando un'immagine viene assegnata a un elemento dell'interfaccia utente in Interface Builder, è sufficiente selezionare il file in ImageName.formato filename-extension (esempio: tags.png). Lo stesso per l'uso di un'immagine nel codice C#, si selezionerà il file in ImageName.formato dell'estensione filename.

Quando si esegue l'applicazione Xamarin.Mac in un Mac, ImageName.l'immagine del formato di estensione filename verrà usata in Display risoluzione standard, l'immagine ImageName@2x.filename-extension verrà selezionata automaticamente nei Mac di base display Retina.

Uso di immagini in Interface Builder

Qualsiasi risorsa immagine aggiunta alla cartella Risorse nel progetto Xamarin.Mac e ha impostato l'azione di compilazione su BundleResource verrà visualizzata automaticamente in Interface Builder e può essere selezionata come parte di un elemento dell'interfaccia utente (se gestisce le immagini).

Per usare un'immagine nel generatore di interfacce, eseguire le operazioni seguenti:

  1. Aggiungere un'immagine alla cartella Risorse con un'azionedi compilazione di BundleResource:

    Una risorsa immagine nel riquadro della soluzione

  2. Fare doppio clic sul file Main.storyboard per aprirlo per la modifica in Interface Builder:

    Modifica dello storyboard principale

  3. Trascinare un elemento dell'interfaccia utente che acquisisce immagini nell'area di progettazione(ad esempio, un elemento della barra degli strumenti immagine):

    Modifica di un elemento della barra degli strumenti

  4. Selezionare l'immagine aggiunta alla cartella Risorse nell'elenco a discesa Nome immagine:

    Selezione di un'immagine per un elemento della barra degli strumenti

  5. L'immagine selezionata verrà visualizzata nell'area di progettazione:

    Immagine visualizzata nell'editor della barra degli strumenti

  6. Salvare le modifiche e tornare a Visual Studio per Mac per la sincronizzazione con Xcode.

I passaggi precedenti funzionano per qualsiasi elemento dell'interfaccia utente che consente di impostare la proprietà image in Controllo attributi. Anche in questo caso, se è stata inclusa una versione @2x del file di immagine, verrà usata automaticamente su Mac basati su Retina Display.

Importante

Se l'immagine non è disponibile nell'elenco a discesa Nome immagine, chiudere il progetto con estensione storyboard in Xcode e riaprirlo da Visual Studio per Mac. Se l'immagine non è ancora disponibile, verificare che l'azione di compilazione sia BundleResource e che l'immagine sia stata aggiunta alla cartella Risorse .

Uso di immagini nel codice C#

Quando si carica un'immagine in memoria usando codice C# nell'applicazione Xamarin.Mac, l'immagine verrà archiviata in un NSImage oggetto . Se il file di immagine è stato incluso nel bundle dell'applicazione Xamarin.Mac (incluso nelle risorse), usare il codice seguente per caricare l'immagine:

NSImage image = NSImage.ImageNamed("tags.png");

Il codice precedente usa il metodo statico ImageNamed("...") della NSImage classe per caricare l'immagine specificata in memoria dalla cartella Resources , se non è possibile trovare l'immagine, null verrà restituita. Come le immagini assegnate in Interface Builder, se è stata inclusa una versione @2x del file di immagine, verrà usata automaticamente su Mac basati su Retina Display.

Per caricare immagini all'esterno del bundle dell'applicazione (dal file system Mac), usare il codice seguente:

NSImage image = new NSImage("/Users/KMullins/Documents/photo.jpg")

Uso delle immagini modello

In base alla progettazione dell'app macOS, potrebbero verificarsi momenti in cui è necessario personalizzare un'icona o un'immagine all'interno dell'interfaccia utente in modo che corrisponda a una modifica della combinazione di colori (ad esempio, in base alle preferenze utente).

Per ottenere questo effetto, impostare la modalità di rendering dell'asset immagine su Immagine modello:

Impostazione di un'immagine modello

Da Interface Builder di Xcode assegnare l'asset immagine a un controllo dell'interfaccia utente:

Selezione di un'immagine in Interface Builder di Xcode

Oppure, facoltativamente, impostare l'origine dell'immagine nel codice:

MyIcon.Image = NSImage.ImageNamed ("MessageIcon");

Aggiungere la funzione pubblica seguente al controller di visualizzazione:

public NSImage ImageTintedWithColor(NSImage sourceImage, NSColor tintColor)
    => NSImage.ImageWithSize(sourceImage.Size, false, rect => {
        // Draw the original source image
        sourceImage.DrawInRect(rect, CGRect.Empty, NSCompositingOperation.SourceOver, 1f);

        // Apply tint
        tintColor.Set();
        NSGraphics.RectFill(rect, NSCompositingOperation.SourceAtop);

        return true;
    });

Importante

In particolare con l'avvento della modalità scura in macOS Mojave, è importante evitare l'API LockFocus quando si ricreano oggetti sottoposti a rendering personalizzato NSImage . Tali immagini diventano statiche e non verranno aggiornate automaticamente per tenere conto delle modifiche di densità di visualizzazione o aspetto.

Usando il meccanismo basato sul gestore precedente, il rendering delle condizioni dinamiche verrà eseguito automaticamente quando l'oggetto NSImage è ospitato, ad esempio, in un oggetto NSImageView.

Infine, per tintare un'immagine modello, chiamare questa funzione sull'immagine per colorare:

MyIcon.Image = ImageTintedWithColor (MyIcon.Image, NSColor.Red);

Uso di immagini con viste tabella

Per includere un'immagine come parte della cella in un NSTableViewoggetto , è necessario modificare il modo in cui i dati vengono restituiti dal metodo di NSTableViewDelegate'sGetViewForItem Visualizzazione tabella per usare un NSTableCellView anziché il tipico NSTextField. Ad esempio:

public override NSView GetViewForItem (NSTableView tableView, NSTableColumn tableColumn, nint row)
{

    // This pattern allows you reuse existing views when they are no-longer in use.
    // If the returned view is null, you instance up a new view
    // If a non-null view is returned, you modify it enough to reflect the new data
    NSTableCellView view = (NSTableCellView)tableView.MakeView (tableColumn.Title, this);
    if (view == null) {
        view = new NSTableCellView ();
        if (tableColumn.Title == "Product") {
            view.ImageView = new NSImageView (new CGRect (0, 0, 16, 16));
            view.AddSubview (view.ImageView);
            view.TextField = new NSTextField (new CGRect (20, 0, 400, 16));
        } else {
            view.TextField = new NSTextField (new CGRect (0, 0, 400, 16));
        }
        view.TextField.AutoresizingMask = NSViewResizingMask.WidthSizable;
        view.AddSubview (view.TextField);
        view.Identifier = tableColumn.Title;
        view.TextField.BackgroundColor = NSColor.Clear;
        view.TextField.Bordered = false;
        view.TextField.Selectable = false;
        view.TextField.Editable = true;

        view.TextField.EditingEnded += (sender, e) => {

            // Take action based on type
            switch(view.Identifier) {
            case "Product":
                DataSource.Products [(int)view.TextField.Tag].Title = view.TextField.StringValue;
                break;
            case "Details":
                DataSource.Products [(int)view.TextField.Tag].Description = view.TextField.StringValue;
                break;
            }
        };
    }

    // Tag view
    view.TextField.Tag = row;

    // Setup view based on the column selected
    switch (tableColumn.Title) {
    case "Product":
        view.ImageView.Image = NSImage.ImageNamed ("tags.png");
        view.TextField.StringValue = DataSource.Products [(int)row].Title;
        break;
    case "Details":
        view.TextField.StringValue = DataSource.Products [(int)row].Description;
        break;
    }

    return view;
}

Ci sono alcune linee di interesse qui. Prima di tutto, per le colonne che si desidera includere un'immagine, viene creata una nuova NSImageView delle dimensioni e della posizione necessarie, viene creata una nuova NSTextField posizione e la posizione predefinita in base al fatto che si stia usando o meno un'immagine:

if (tableColumn.Title == "Product") {
    view.ImageView = new NSImageView (new CGRect (0, 0, 16, 16));
    view.AddSubview (view.ImageView);
    view.TextField = new NSTextField (new CGRect (20, 0, 400, 16));
} else {
    view.TextField = new NSTextField (new CGRect (0, 0, 400, 16));
}

In secondo luogo, è necessario includere la nuova visualizzazione immagini e il campo di testo nell'elemento padre NSTableCellView:

view.AddSubview (view.ImageView);
...

view.AddSubview (view.TextField);
...

Infine, è necessario indicare al campo di testo che può ridursi e crescere con la cella di visualizzazione tabella:

view.TextField.AutoresizingMask = NSViewResizingMask.WidthSizable;

Output di esempio:

Esempio di visualizzazione di un'immagine in un'app

Per altre informazioni sull'uso delle viste tabella, vedere la documentazione delle viste tabella.

Uso di immagini con visualizzazioni struttura

Per includere un'immagine come parte della cella in un NSOutlineViewoggetto , è necessario modificare il modo in cui i dati vengono restituiti dal metodo della NSTableViewDelegate'sGetView visualizzazione struttura per usare un NSTableCellView anziché il tipico NSTextField. Ad esempio:

public override NSView GetView (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item) {
    // Cast item
    var product = item as Product;

    // This pattern allows you reuse existing views when they are no-longer in use.
    // If the returned view is null, you instance up a new view
    // If a non-null view is returned, you modify it enough to reflect the new data
    NSTableCellView view = (NSTableCellView)outlineView.MakeView (tableColumn.Title, this);
    if (view == null) {
        view = new NSTableCellView ();
        if (tableColumn.Title == "Product") {
            view.ImageView = new NSImageView (new CGRect (0, 0, 16, 16));
            view.AddSubview (view.ImageView);
            view.TextField = new NSTextField (new CGRect (20, 0, 400, 16));
        } else {
            view.TextField = new NSTextField (new CGRect (0, 0, 400, 16));
        }
        view.TextField.AutoresizingMask = NSViewResizingMask.WidthSizable;
        view.AddSubview (view.TextField);
        view.Identifier = tableColumn.Title;
        view.TextField.BackgroundColor = NSColor.Clear;
        view.TextField.Bordered = false;
        view.TextField.Selectable = false;
        view.TextField.Editable = !product.IsProductGroup;
    }

    // Tag view
    view.TextField.Tag = outlineView.RowForItem (item);

    // Allow for edit
    view.TextField.EditingEnded += (sender, e) => {

        // Grab product
        var prod = outlineView.ItemAtRow(view.Tag) as Product;

        // Take action based on type
        switch(view.Identifier) {
        case "Product":
            prod.Title = view.TextField.StringValue;
            break;
        case "Details":
            prod.Description = view.TextField.StringValue;
            break;
        }
    };

    // Setup view based on the column selected
    switch (tableColumn.Title) {
    case "Product":
        view.ImageView.Image = NSImage.ImageNamed (product.IsProductGroup ? "tags.png" : "tag.png");
        view.TextField.StringValue = product.Title;
        break;
    case "Details":
        view.TextField.StringValue = product.Description;
        break;
    }

    return view;
}

Ci sono alcune linee di interesse qui. Prima di tutto, per le colonne che si desidera includere un'immagine, viene creata una nuova NSImageView delle dimensioni e della posizione necessarie, viene creata una nuova NSTextField posizione e la posizione predefinita in base al fatto che si stia usando o meno un'immagine:

if (tableColumn.Title == "Product") {
    view.ImageView = new NSImageView (new CGRect (0, 0, 16, 16));
    view.AddSubview (view.ImageView);
    view.TextField = new NSTextField (new CGRect (20, 0, 400, 16));
} else {
    view.TextField = new NSTextField (new CGRect (0, 0, 400, 16));
}

In secondo luogo, è necessario includere la nuova visualizzazione immagini e il campo di testo nell'elemento padre NSTableCellView:

view.AddSubview (view.ImageView);
...

view.AddSubview (view.TextField);
...

Infine, è necessario indicare al campo di testo che può ridursi e crescere con la cella di visualizzazione tabella:

view.TextField.AutoresizingMask = NSViewResizingMask.WidthSizable;

Output di esempio:

Esempio di immagine visualizzata in una visualizzazione struttura

Per altre informazioni sull'uso delle visualizzazioni struttura, vedere la documentazione sulle visualizzazioni struttura.

Riepilogo

Questo articolo ha esaminato in dettaglio l'uso di immagini e icone in un'applicazione Xamarin.Mac. Sono stati illustrati i diversi tipi e usi delle immagini, come usare immagini e icone in Interface Builder di Xcode e come usare immagini e icone nel codice C#.