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
lubNSOutlineView
) 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.
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 tegoHearts
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.
W okienku rozwiązania kliknij dwukrotnie plik Assets.xcassets, aby otworzyć go do edycji:
Kliknij prawym przyciskiem myszy listę zasobów i wybierz pozycję Nowy zestaw obrazów:
Wybierz nowy zestaw obrazów, a edytor zostanie wyświetlony:
W tym miejscu możemy przeciągnąć obrazy dla każdego z różnych wymaganych urządzeń i rozdzielczości.
Kliknij dwukrotnie nazwę nowego zestawu obrazów na liście zasobów, aby go edytować:
Specjalna klasa wektorów została dodana do zestawów obrazów, która umożliwia dołączenie obrazu wektora sformatowanego 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.
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:
- MonkeyIcon@1x.png - Rozdzielczość 150 pikseli x 150 pikseli.
- MonkeyIcon@2x.png - Rozdzielczość 300 pikseli x 300 pikseli.
- 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:
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:
Kliknij prawym przyciskiem myszy projekt w okienku rozwiązania i wybierz polecenie Dodaj>nowy plik...
Wybierz pozycję Katalog zasobów dla komputerów Mac>, wprowadź nazwę kolekcji i kliknij przycisk Nowy:
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:
Kliknij prawym przyciskiem myszy folder Resources w projekcie w okienku rozwiązania i wybierz pozycję Dodaj>pliki...:
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: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:
Nowe pliki zostaną uwzględnione w projekcie i odczytane do użycia:
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:
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:
Dodaj obraz do folderu Resources za pomocą akcji kompilacji :
BundleResource
Kliknij dwukrotnie plik Main.storyboard, aby otworzyć go do edycji w narzędziu Interface Builder:
Przeciągnij element interfejsu użytkownika, który pobiera obrazy na powierzchnię projektową (na przykład element paska narzędzi obrazu):
Wybierz obraz dodany do folderu Resources na liście rozwijanej Nazwa obrazu:
Wybrany obraz zostanie wyświetlony na powierzchni projektowej:
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:
W narzędziu Interface Builder programu Xcode przypisz zasób obrazu do kontrolki interfejsu użytkownika:
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 NSTableView
obiekcie , należy zmienić sposób zwracania danych przez metodę Widoku GetViewForItem
NSTableViewDelegate's
tabeli, aby użyć NSTableCellView
elementu zamiast typowego NSTextField
elementu . 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:
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 NSOutlineView
obiekcie , należy zmienić sposób zwracania danych przez metodę widoku NSTableViewDelegate's
GetView
konspektu, aby użyć elementu NSTableCellView
zamiast typowego NSTextField
elementu . 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:
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#.