Udostępnij za pośrednictwem


Obrazy na platformie Xamarin.Mac

W tym artykule opisano pracę z obrazami i ikonami w aplikacji platformy Xamarin.Mac. W tym artykule opisano tworzenie i konserwowanie obrazów potrzebnych do utworzenia ikony aplikacji oraz używanie obrazów zarówno w kodzie C#, jak i w narzędziu Interface Builder programu Xcode.

Omówienie

Podczas pracy z językami C# i .NET w aplikacji platformy Xamarin.Mac masz dostęp do tych samych narzędzi obrazów i ikon, które wykonuje deweloper pracujący w Objective-C środowisku Xcode.

Istnieje kilka sposobów użycia zasobów obrazów w aplikacji systemu macOS (wcześniej znanej jako Mac OS X). Od prostego wyświetlania obrazu w ramach interfejsu użytkownika aplikacji do, przypisywania go do kontrolki interfejsu użytkownika, takiej jak pasek narzędzi lub element listy źródłowej, do udostępniania ikon, platforma Xamarin.Mac ułatwia dodawanie doskonałej grafiki do aplikacji systemu macOS w następujący sposób:

  • Elementy interfejsu użytkownika — obrazy mogą być wyświetlane jako tła lub jako część aplikacji w widoku obrazu (NSImageView).
  • Przycisk — obrazy mogą być wyświetlane w przyciskach (NSButton).
  • Komórka obrazu — w ramach kontrolki opartej na tabeli (NSTableView lub NSOutlineView) obrazy mogą być używane w komórce obrazu (NSImageCell).
  • Element paska narzędzi — obrazy można dodać do paska narzędzi (NSToolbar) jako elementu paska narzędzi obrazu (NSToolbarItem).
  • Ikona listy źródłowej — jako część listy źródłowej (specjalnie sformatowana ).NSOutlineView
  • Ikona aplikacji — serię obrazów można zgrupować w .icns zestaw i użyć jako ikony aplikacji. Aby uzyskać więcej informacji, zobacz dokumentację ikony aplikacji.

Ponadto system macOS udostępnia zestaw wstępnie zdefiniowanych obrazów, które mogą być używane w całej aplikacji.

Przykładowy przebieg aplikacji

W tym artykule omówimy podstawy pracy z obrazami i ikonami w aplikacji platformy Xamarin.Mac. Zdecydowanie zaleca się, aby najpierw zapoznać się z artykułem Hello, Mac , w szczególności wprowadzenie do narzędzi Xcode i Interface Builder i Outlet and Actions , ponieważ obejmuje ona kluczowe pojęcia i techniki, których będziemy używać w tym artykule.

Dodawanie obrazów do projektu platformy Xamarin.Mac

Podczas dodawania obrazu do użycia w aplikacji Xamarin.Mac istnieje kilka miejsc i sposobów dołączania pliku obrazu do źródła projektu:

  • Główne drzewo projektu [przestarzałe] — obrazy można dodać bezpośrednio do drzewa projektów. Podczas wywoływania obrazów przechowywanych w głównym drzewie projektu z kodu nie określono lokalizacji folderu. Na przykład: NSImage image = NSImage.ImageNamed("tags.png");.
  • Folder resources [przestarzałe] — specjalny folder Resources dotyczy dowolnego pliku, który stanie się częścią pakietu aplikacji, takiego jak Ikona, Ekran uruchamiania lub obrazy ogólne (lub dowolny inny obraz lub plik, który deweloper chce dodać). Podczas wywoływania obrazów przechowywanych w folderze Resources z kodu, podobnie jak obrazy przechowywane w głównym drzewie projektu, nie określono lokalizacji folderu. Na przykład: NSImage.ImageNamed("tags.png").
  • Folder niestandardowy lub podfolder [przestarzałe] — deweloper może dodać folder niestandardowy do drzewa źródłowego projektów i zapisać tam obrazy. Lokalizacja, w której jest dodawany plik, może być zagnieżdżona w podfolderze, aby ułatwić organizowanie projektu. Jeśli na przykład deweloper dodał Card folder do projektu i podfolder tego Hearts folderu, zapisze obraz Jack.png w folderzeHearts, NSImage.ImageNamed("Card/Hearts/Jack.png") załaduje obraz w czasie wykonywania.
  • Zestawy obrazów wykazu zasobów [preferowane] — dodano w zestawie obrazów OS X El Capitan, zestawy obrazów wykazów zasobów zawierają wszystkie wersje lub reprezentacje obrazu, które są niezbędne do obsługi różnych urządzeń i czynników skalowania dla aplikacji. Zamiast polegać na nazwie pliku zasobów obrazów (@1x, @2x).

Dodawanie obrazów do zestawu obrazów wykazu zasobów

Jak wspomniano powyżej, zestawy obrazów wykazu zasobów zawierają wszystkie wersje lub reprezentacje obrazu, które są niezbędne do obsługi różnych urządzeń i czynników skalowania dla aplikacji. Zamiast polegać na nazwie pliku zasobów obrazów (zobacz rozpoznawanie niezależnych obrazów i nomenklatury obrazów powyżej), zestawy obrazów używają Edytora zasobów, aby określić, który obraz należy do którego urządzenia i/lub rozdzielczości.

  1. W okienku rozwiązania kliknij dwukrotnie plik Assets.xcassets, aby otworzyć go do edycji:

    Wybieranie zasobów Assets.xcassets

  2. Kliknij prawym przyciskiem myszy listę zasobów i wybierz pozycję Nowy zestaw obrazów:

    Dodawanie nowego zestawu obrazów

  3. Wybierz nowy zestaw obrazów, a edytor zostanie wyświetlony:

    Wybieranie nowego zestawu obrazów

  4. W tym miejscu możemy przeciągnąć obrazy dla każdego z różnych wymaganych urządzeń i rozdzielczości.

  5. Kliknij dwukrotnie nazwę nowego zestawu obrazów na liście zasobów, aby go edytować:

    Edytowanie nazwy zestawu obrazów

Specjalna klasa wektorów została dodana do zestawów obrazów, która umożliwia dołączenie obrazu wektorasformatowanego w formacie PDF do zestawu casset, w tym pojedynczych plików map bitowych w różnych rozdzielczościach. Przy użyciu tej metody należy podać pojedynczy plik wektorowy dla rozdzielczości @1x (sformatowanej jako plik PDF wektora), a @2x i @3x wersje pliku zostaną wygenerowane w czasie kompilacji i uwzględnione w pakiecie aplikacji.

Interfejs edytora zestawu obrazów

Jeśli na przykład dołączysz MonkeyIcon.pdf plik jako wektor wykazu zasobów z rozdzielczością 150 pikseli x 150 pikseli, następujące zasoby mapy bitowej zostaną uwzględnione w ostatnim pakiecie aplikacji podczas kompilacji:

  1. MonkeyIcon@1x.png - Rozdzielczość 150 pikseli x 150 pikseli.
  2. MonkeyIcon@2x.png - Rozdzielczość 300 pikseli x 300 pikseli.
  3. MonkeyIcon@3x.png - Rozdzielczość 450 pikseli x 450 pikseli.

Podczas korzystania z obrazów wektorów PDF w wykazach zasobów należy wziąć pod uwagę następujące kwestie:

  • Nie jest to pełna obsługa wektorów, ponieważ plik PDF będzie rasteryzowany do mapy bitowej w czasie kompilacji, a mapy bitowe dostarczane w końcowej aplikacji.
  • Nie można dostosować rozmiaru obrazu po ustawieniu go w wykazie zasobów. Jeśli spróbujesz zmienić rozmiar obrazu (w kodzie lub za pomocą klas automatycznego układu i rozmiaru), obraz zostanie zniekształcony tak samo jak każda inna mapa bitowa.

W przypadku korzystania z zestawu obrazów w narzędziu Interface Builder programu Xcode możesz po prostu wybrać nazwę zestawu z listy rozwijanej w Inspektorze atrybutów:

Wybieranie zestawu obrazów w narzędziu Xcode Interface Builder

Dodawanie nowych kolekcji zasobów

Podczas pracy z obrazami w wykazach zasobów mogą wystąpić czasy, kiedy chcesz utworzyć nową kolekcję, zamiast dodawać wszystkie obrazy do kolekcji Assets.xcassets . Na przykład podczas projektowania zasobów na żądanie.

Aby dodać nowy katalog zasobów do projektu:

  1. Kliknij prawym przyciskiem myszy projekt w okienku rozwiązania i wybierz polecenie Dodaj>nowy plik...

  2. Wybierz pozycję Katalog zasobów dla komputerów Mac>, wprowadź nazwę kolekcji i kliknij przycisk Nowy:

    Dodawanie nowego wykazu zasobów

W tym miejscu możesz pracować z kolekcją w taki sam sposób, jak domyślna kolekcja zasobów Assets.xc automatycznie uwzględniona w projekcie.

Dodawanie obrazów do zasobów

Ważne

Ta metoda pracy z obrazami w aplikacji systemu macOS została uznana za przestarzałą przez firmę Apple. Zamiast tego należy użyć zestawów obrazów wykazu zasobów do zarządzania obrazami aplikacji.

Aby można było użyć pliku obrazu w aplikacji Xamarin.Mac (w kodzie języka C# lub w narzędziu Interface Builder), należy dołączyć go do folderu Zasoby projektu jako zasób pakietu. Aby dodać plik do projektu, wykonaj następujące czynności:

  1. Kliknij prawym przyciskiem myszy folder Resources w projekcie w okienku rozwiązania i wybierz pozycję Dodaj>pliki...:

    Dodawanie pliku

  2. W oknie dialogowym Dodawanie plików wybierz pliki obrazów do dodania do projektu, wybierz BundleResource akcję Przesłoń kompilację i kliknij przycisk Otwórz:

    Wybieranie plików do dodania

  3. Jeśli pliki nie znajdują się jeszcze w folderze Resources , zostanie wyświetlony monit o skopiowanie, przeniesienie lub połączenie plików. Wybierz, które elementy pasują do Twoich potrzeb, zazwyczaj będzie to Kopia:

    Wybieranie akcji dodawania

  4. Nowe pliki zostaną uwzględnione w projekcie i odczytane do użycia:

    Nowe pliki obrazów dodane do okienka rozwiązania

  5. Powtórz proces dla wszystkich wymaganych plików obrazów.

Możesz użyć dowolnego pliku png, jpg lub pdf jako obrazu źródłowego w aplikacji Xamarin.Mac. W następnej sekcji przyjrzymy się dodawaniu wersji obrazów i ikon o wysokiej rozdzielczości w celu obsługi komputerów Mac opartych na siatkówki.

Ważne

Jeśli dodasz obrazy do folderu Resources, możesz pozostawić akcję Przesłonięcia kompilacji ustawioną na Wartość domyślna. Domyślna akcja kompilacji dla tego folderu to BundleResource.

Udostępnianie wersji wysokiej rozdzielczości wszystkich zasobów graficznych aplikacji

Każdy zasób graficzny dodany do aplikacji Xamarin.Mac (ikony, kontrolki niestandardowe, kursory niestandardowe, grafika niestandardowa itp.) muszą mieć wersje o wysokiej rozdzielczości oprócz wersji standardowej rozdzielczości. Jest to wymagane, aby aplikacja wyglądała najlepiej po uruchomieniu na komputerze Mac wyposażonym w siatkówkę wyświetlacza.

Przyjęcie konwencji nazewnictwa @2x

Ważne

Ta metoda pracy z obrazami w aplikacji systemu macOS została uznana za przestarzałą przez firmę Apple. Zamiast tego należy użyć zestawów obrazów wykazu zasobów do zarządzania obrazami aplikacji.

Podczas tworzenia standardowych i wysokiej rozdzielczości wersji obrazu należy postępować zgodnie z tą konwencją nazewnictwa pary obrazów podczas dołączania ich do projektu Xamarin.Mac:

  • Standard-Resolution - ImageName.filename-extension (Przykład: tags.png)
  • Rozszerzenie o wysokiej rozdzielczości - ImageName@2x.filename (przykład: ) tags@2x.png

Po dodaniu do projektu będą one wyświetlane w następujący sposób:

Pliki obrazów w okienku rozwiązania

Po przypisaniu obrazu do elementu interfejsu użytkownika w narzędziu Interface Builder po prostu wybierz plik w polu ImageName.format rozszerzenia nazwy pliku (przykład: tags.png). W przypadku używania obrazu w kodzie języka C# wybierzesz plik w polu ImageName.format nazwy pliku i rozszerzenia.

Po uruchomieniu aplikacji Xamarin.Mac na komputerze Mac nazwa_obrazu.Obraz formatu nazwy pliku zostanie użyty na ekranach rozdzielczości w warstwie Standardowa. ImageName@2x.filenameObraz -extension zostanie automatycznie wybrany na komputerach Mac z bazami siatkówki.

Używanie obrazów w narzędziu Interface Builder

Każdy zasób obrazu dodany do folderu Resources w projekcie Xamarin.Mac i ustawił akcję kompilacji na BundleResource będzie automatycznie wyświetlany w narzędziu Interface Builder i można go wybrać jako część elementu interfejsu użytkownika (jeśli obsługuje obrazy).

Aby użyć obrazu w konstruktorze interfejsu, wykonaj następujące czynności:

  1. Dodaj obraz do folderu Resources za pomocą akcji kompilacji :BundleResource

    Zasób obrazu w okienku rozwiązania

  2. Kliknij dwukrotnie plik Main.storyboard, aby otworzyć go do edycji w narzędziu Interface Builder:

    Edytowanie głównego scenorysu

  3. Przeciągnij element interfejsu użytkownika, który pobiera obrazy na powierzchnię projektową (na przykład element paska narzędzi obrazu):

    Edytowanie elementu paska narzędzi

  4. Wybierz obraz dodany do folderu Resources na liście rozwijanej Nazwa obrazu:

    Wybieranie obrazu dla elementu paska narzędzi

  5. Wybrany obraz zostanie wyświetlony na powierzchni projektowej:

    Obraz wyświetlany w edytorze paska narzędzi

  6. Zapisz zmiany i wróć do Visual Studio dla komputerów Mac, aby przeprowadzić synchronizację z programem Xcode.

Powyższe kroki działają dla dowolnego elementu interfejsu użytkownika, który umożliwia ustawienie właściwości obrazu w Inspektorze atrybutów. Ponownie, jeśli dołączysz @2x wersję pliku obrazu, zostanie on automatycznie użyty na wyświetlaczu Siatkówki na komputerach Mac.

Ważne

Jeśli obraz nie jest dostępny na liście rozwijanej Nazwa obrazu, zamknij projekt scenorysu w programie Xcode i otwórz go ponownie z Visual Studio dla komputerów Mac. Jeśli obraz nadal nie jest dostępny, upewnij się, że jego akcja kompilacji jest BundleResource i że obraz został dodany do folderu Zasoby .

Używanie obrazów w kodzie języka C#

Podczas ładowania obrazu do pamięci przy użyciu kodu C# w aplikacji Xamarin.Mac obraz będzie przechowywany w NSImage obiekcie. Jeśli plik obrazu został uwzględniony w pakiecie aplikacji Xamarin.Mac (dołączonym do zasobów), użyj następującego kodu, aby załadować obraz:

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

Powyższy kod używa metody NSImage statycznej ImageNamed("...") klasy do załadowania danego obrazu do pamięci z folderu Resources, jeśli nie można odnaleźć obrazu, null zostanie zwrócony. Podobnie jak obrazy przypisane w narzędziu Interface Builder, jeśli dołączono @2x wersję pliku obrazu, będzie on automatycznie używany na komputerach Mac opartych na siatkówce.

Aby załadować obrazy poza pakietem aplikacji (z systemu plików Mac), użyj następującego kodu:

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

Praca z obrazami szablonów

Na podstawie projektu aplikacji systemu macOS może wystąpić potrzeba dostosowania ikony lub obrazu wewnątrz interfejsu użytkownika w celu dopasowania zmiany schematu kolorów (na przykład na podstawie preferencji użytkownika).

Aby osiągnąć ten efekt, przełącz tryb renderowania elementu zawartości obrazu na obraz szablonu:

Ustawianie obrazu szablonu

W narzędziu Interface Builder programu Xcode przypisz zasób obrazu do kontrolki interfejsu użytkownika:

Wybieranie obrazu w narzędziu Xcode Interface Builder

Możesz też opcjonalnie ustawić źródło obrazu w kodzie:

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

Dodaj następującą funkcję publiczną do kontrolera widoku:

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

Ważne

Szczególnie w przypadku pojawienia się trybu ciemnego w systemie macOS Mojave ważne jest, aby uniknąć interfejsu LockFocus API podczas ponownego renderowania NSImage obiektów niestandardowych. Takie obrazy stają się statyczne i nie zostaną automatycznie zaktualizowane pod kątem zmian wyglądu ani gęstości wyświetlania.

Dzięki użyciu powyższego mechanizmu opartego na procedurze obsługi ponowne renderowanie warunków dynamicznych nastąpi automatycznie, gdy NSImage obiekt jest hostowany, na przykład w obiekcie NSImageView.

Na koniec, aby zabarwić obraz szablonu, wywołaj tę funkcję względem obrazu, aby kolorować:

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

Używanie obrazów z widokami tabel

Aby dołączyć obraz jako część komórki w NSTableViewobiekcie , należy zmienić sposób zwracania danych przez metodę WidokuGetViewForItemNSTableViewDelegate'stabeli, aby użyć NSTableCellView elementu zamiast typowego NSTextFieldelementu . Na przykład:

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

Istnieje kilka linii zainteresowania tutaj. Najpierw w przypadku kolumn, które chcemy dołączyć do obrazu, tworzymy nowy NSImageView wymagany rozmiar i lokalizację, tworzymy również nową NSTextField i umieszczamy jej domyślną pozycję na podstawie tego, czy używamy obrazu:

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

Po drugie musimy uwzględnić nowy widok obrazu i pole tekstowe w obiekcie nadrzędnym NSTableCellView:

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

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

Na koniec musimy poinformować pole tekstowe, że może on zmniejszać się i rozwijać za pomocą komórki Widok tabeli:

view.TextField.AutoresizingMask = NSViewResizingMask.WidthSizable;

Przykładowe wyjście:

Przykład wyświetlania obrazu w aplikacji

Aby uzyskać więcej informacji na temat pracy z widokami tabel, zobacz dokumentację widoków tabel.

Używanie obrazów z widokami konspektu

Aby dołączyć obraz jako część komórki w NSOutlineViewobiekcie , należy zmienić sposób zwracania danych przez metodę widoku NSTableViewDelegate'sGetView konspektu, aby użyć elementu NSTableCellView zamiast typowego NSTextFieldelementu . Na przykład:

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

Istnieje kilka linii zainteresowania tutaj. Najpierw w przypadku kolumn, które chcemy dołączyć do obrazu, tworzymy nowy NSImageView wymagany rozmiar i lokalizację, tworzymy również nową NSTextField i umieszczamy jej domyślną pozycję na podstawie tego, czy używamy obrazu:

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

Po drugie musimy uwzględnić nowy widok obrazu i pole tekstowe w obiekcie nadrzędnym NSTableCellView:

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

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

Na koniec musimy poinformować pole tekstowe, że może on zmniejszać się i rozwijać za pomocą komórki Widok tabeli:

view.TextField.AutoresizingMask = NSViewResizingMask.WidthSizable;

Przykładowe wyjście:

Przykład obrazu wyświetlanego w widoku konspektu

Aby uzyskać więcej informacji na temat pracy z widokami konspektu, zobacz dokumentację widoków konspektu.

Podsumowanie

W tym artykule szczegółowo przedstawiono pracę z obrazami i ikonami w aplikacji platformy Xamarin.Mac. Zobaczyliśmy różne typy i zastosowania obrazów, jak używać obrazów i ikon w narzędziu Interface Builder programu Xcode oraz jak pracować z obrazami i ikonami w kodzie języka C#.