2015-09-06 7 views

ответ

2

Возможно изменение цвета с помощью custom renderers для каждой платформы. У вас есть доступ к встроенному api внутри настраиваемого рендеринга. Но нужно быть уверенным, что это необходимо, потому что это не рекомендуется (для iOS обязательно).

The UIAlertView class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified.

Относительная тема для прошивки here.

+0

Очень полезная информация. Однако я просто не вижу, как создать собственный визуализатор для диалогового окна DisplayAlert. Полагаю, я мог бы просто создать свой собственный модальный диалог. –

+0

Вы правы. Легче реализовать пользовательские диалоги для каждой платформы и разрешить их с помощью DI. Обратите внимание: [«Вы не можете настроить внешний вид предупреждений».] (Https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/UIKitUICatalog/UIAlertView.html#//apple_ref/doc/uid/TP40012857-UIAlertView) – bkmza

+0

Я использовал плагин Toasts вместо диалогового окна Alert в некоторых ситуациях. Он имеет множество настроек, которые могут оказаться полезными для вас. https://www.nuget.org/packages/Toasts.Forms.Plugin/ –

0

я создал пользовательские displayalert вы можете использовать вызов задачи обратно TaskCompletionSource, как Xamarin построить DisplayAlert from it

public async Task<bool> ShowDialogAsync(string title, string message, string acceptMessage, string cancelMessage) 
       { 
        Grid ShowDialogMessage = null; 
        Grid CurrentPageGrid = (App.Instance.CurrentPage as ContentPage).Content as Grid; 
        TaskCompletionSource<bool> result = new TaskCompletionSource<bool>(); 
        try 
        { 
         ShowDialogMessage = GenericView.CustomDisplayAlert(message, CurrentPageGrid.RowDefinitions.Count, CurrentPageGrid.ColumnDefinitions.Count,() => 
         { 
     //here you can add your implementation 
          CurrentPageGrid.Children.Remove(ShowDialogMessage); 

    result.SetResult(true); 

         }, 
         () => 
         { 
     //here you can add your implementation  
          CurrentPageGrid.Children.Remove(ShowDialogMessage); 
          result.SetResult(false); 
         }, title, acceptMessage, cancelMessage); 

         CurrentPageGrid.Children.Add(ShowDialogMessage); 
         return await result.Task; 
        } 
        catch (Exception ex) 
        { 
         return await App.Current.MainPage.DisplayAlert(title, message, acceptMessage, cancelMessage); 
     #if DEBUG 
         throw ex; 
     #endif 
        } 

       } 

в моем методе я добавил меры для осуществления обратного вызова ,, метод подписи вы можете добавить свой собственный дизайн

public static Grid CustomDisplayAlert(string message, int rows, int columns, Action acceptAction, Action cancelAction, string title = "", string acceptMessage = "", string cancelMessage = "") 
     {   
      Grid overlay = new Grid 
      { 
       BackgroundColor = Color.FromRgba(0, 0, 0, 190), 
       RowDefinitions = new RowDefinitionCollection { new RowDefinition { Height = GridLength.Star }, new RowDefinition { Height = GridLength.Auto }, new RowDefinition { Height = GridLength.Star } } 
      }; 

       Grid.SetRowSpan(overlay, rows); 

       Grid.SetColumnSpan(overlay, columns); 


      Grid bodyView = new Grid(); 


      StackLayout stackMainView = new StackLayout 
      { 
       Margin = new Thickness(20) 
      }; 
      StackLayout stackButtonsView = new StackLayout 
      { 
       Orientation=StackOrientation.Horizontal 
      }; 
      RoundedBox bgOverlay = new RoundedBox 
      { 
       CornerRadius = 4, 
       HorizontalOptions = LayoutOptions.FillAndExpand, 
       VerticalOptions = LayoutOptions.FillAndExpand, 
       BackgroundColor = Color.White 
      }; 

      bodyView.Children.Add(bgOverlay); 

      StackLayout elementsContainer = new StackLayout { Margin = new Thickness(10) }; 

      IconicLabel itemDescription = new IconicLabel { MoreReadable = true, Text = message, StyleId = "Myriad-Pro-L", HorizontalTextAlignment = TextAlignment.Center, HorizontalOptions = LayoutOptions.FillAndExpand, TextColor = (Color)(App.Current.Resources["OptioDark"]), FontSize = 18, Margin = new Thickness(15) }; 
      IconicLabel titleView = new IconicLabel { FontAttributes = FontAttributes.Bold, MoreReadable = true, Text = title, StyleId = "Myriad-Pro-L", HorizontalTextAlignment = TextAlignment.Center, HorizontalOptions = LayoutOptions.FillAndExpand, TextColor = (Color)(App.Current.Resources["OptioDark"]), FontSize = 22, Margin = new Thickness(15) }; 

      if (titleView.Text.Length != 0) 
       elementsContainer.Children.Add(titleView); 
      elementsContainer.Children.Add(itemDescription); 


      bodyView.Children.Add(elementsContainer); 

      IconicButton acceptBtn = new IconicButton 
      { 
       HeightRequest = 40, 
       HorizontalOptions = LayoutOptions.FillAndExpand, 
       VerticalOptions = LayoutOptions.FillAndExpand, 
       BackgroundColor = Color.White, 
       Text = acceptMessage, 
       TextColor = (Color)(App.Current.Resources["OptioDark"]) 
      }; 
      IconicButton cancelBtn = new IconicButton 
      { 
       HeightRequest = 40, 
       HorizontalOptions = LayoutOptions.FillAndExpand, 
       VerticalOptions = LayoutOptions.FillAndExpand, 
       BackgroundColor = Color.White, 
       Text = cancelMessage, 
       TextColor = (Color)(App.Current.Resources["OptioDark"]) 
      }; 
      acceptBtn.Clicked += (sender, e) => 
      { 
       acceptAction?.Invoke(); 
      }; 
      cancelBtn.Clicked += (sender, e) => 
      { 
       cancelAction?.Invoke(); 
      }; 

      stackButtonsView.Children.Add(acceptBtn); 
      stackButtonsView.Children.Add(cancelBtn); 

      stackMainView.Children.Add(bodyView); 

      stackMainView.Children.Add(stackButtonsView); 
      overlay.Children.Add(stackMainView, 0, 1); 
      return overlay; 

     } 
0

FWIW, я решил создать новую ContentPage в XAML и показать ее с помощью Navigation.PushModalAsync. В моем случае это был самый простой способ симулировать оповещение и поддерживать контроль над всеми стилями.

XAML:

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      x:Class="YourNamespace.AlertPage" 
      BackgroundColor="DarkGray" 
      Padding="40"> 
    <ContentPage.Content> 
     <StackLayout BackgroundColor="White" Padding="10"> 
      <Label x:Name="lblTitle" FontAttributes="Bold" FontSize="Large" Text="Title" HorizontalOptions="Center"></Label> 
      <BoxView HeightRequest="1" BackgroundColor="DarkGray"></BoxView> 
      <ScrollView Orientation="Vertical" VerticalOptions="FillAndExpand"> 
       <Label x:Name="lblText" FontSize="Medium"></Label> 
      </ScrollView> 
      <BoxView HeightRequest="1" BackgroundColor="DarkGray"></BoxView> 
      <StackLayout Orientation="Horizontal"> 
       <Button x:Name="btn1" Text="Button 1" HorizontalOptions="CenterAndExpand"></Button> 
       <Button x:Name="btn2" Text="Button 2" HorizontalOptions="CenterAndExpand"></Button> 
      </StackLayout> 
     </StackLayout> 
    </ContentPage.Content> 
</ContentPage> 

C#:

public partial class AlertPage : ContentPage 
{ 
    public Label LblTitle 
    { 
     get 
     { 
      return lblTitle; 
     } 
    } 

    public Label LblText 
    { 
     get 
     { 
      return lblText; 
     } 
    } 

    public Button Button1 
    { 
     get 
     { 
      return btn1; 
     } 
    } 

    public Button Button2 
    { 
     get 
     { 
      return btn2; 
     } 
    } 

    public AlertPage() 
    { 
     InitializeComponent(); 
    } 
} 

Реализация:

var ap = new AlertPage(); 
ap.LblTitle.Text = "Instructions"; 
ap.LblText.Text = "The text to display!"; 
ap.Button1.Text = "Done"; 
ap.Button1.Clicked += async (s, a) => 
{ 
    await Navigation.PopModalAsync(); 
}; 
ap.Button2.IsVisible = false; 
await Navigation.PushModalAsync(ap); 

Скриншот:

Screenshot from iPhone 7+

Смежные вопросы