[iOS] Hardcoded to Semantic colors (dark mode support) (#9840) fixes #7683 fixes #8495

* Replace all teh colors

* Last fixes

* Global updating of controls when appearance changes

* Update ViewRenderer.cs

* Update ModalWrapper.cs

* Review feedback

* [iOS] Fix NRE when running on iOS12 with XCODE 11 installed

Co-authored-by: Rui Marinho <me@ruimarinho.net>
This commit is contained in:
Gerald Versluis 2020-03-30 13:09:07 +02:00 коммит произвёл GitHub
Родитель 28b25032d7
Коммит fdb0b9368e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
32 изменённых файлов: 242 добавлений и 42 удалений

Просмотреть файл

@ -84,7 +84,7 @@ namespace Xamarin.Forms.Platform.iOS
if (!UIDevice.CurrentDevice.CheckSystemVersion(7, 0))
return;
uiBgColor = new UIColor(247f / 255f, 247f / 255f, 247f / 255f, 1);
uiBgColor = ColorExtensions.GroupedBackground;
}
else
{

Просмотреть файл

@ -8,7 +8,7 @@ namespace Xamarin.Forms.Platform.iOS
{
public class EntryCellRenderer : CellRenderer
{
static readonly Color DefaultTextColor = Color.Black;
static readonly Color DefaultTextColor = ColorExtensions.LabelColor.ToColor();
[Preserve(Conditional = true)]
public EntryCellRenderer()

Просмотреть файл

@ -6,8 +6,8 @@ namespace Xamarin.Forms.Platform.iOS
{
public class TextCellRenderer : CellRenderer
{
static readonly Color DefaultDetailColor = new Color(.32, .4, .57);
static readonly Color DefaultTextColor = Color.Black;
readonly Color DefaultDetailColor = ColorExtensions.SecondaryLabelColor.ToColor();
readonly Color DefaultTextColor = ColorExtensions.LabelColor.ToColor();
[Preserve(Conditional = true)]
public TextCellRenderer()

Просмотреть файл

@ -16,7 +16,7 @@ namespace Xamarin.Forms.Platform.iOS
{
Label = new UILabel(frame)
{
TextColor = UIColor.Black,
TextColor = ColorExtensions.LabelColor,
Lines = 1,
Font = UIFont.PreferredBody,
TranslatesAutoresizingMaskIntoConstraints = false

Просмотреть файл

@ -14,7 +14,7 @@ namespace Xamarin.Forms.Platform.iOS
var selectedBackgroundView = new UIView
{
BackgroundColor = UIColor.Gray
BackgroundColor = ColorExtensions.Gray
};
SelectedBackgroundView = selectedBackgroundView;

Просмотреть файл

@ -33,11 +33,11 @@ namespace Xamarin.Forms.Platform.iOS
UIGraphics.BeginImageContext(size);
var context = UIGraphics.GetCurrentContext();
context.SetFillColor(1, 0, 0, 1);
context.SetFillColor(ColorExtensions.Red.CGColor);
context.FillRect(rect);
DestructiveBackground = UIGraphics.GetImageFromCurrentImageContext();
context.SetFillColor(UIColor.LightGray.ToColor().ToCGColor());
context.SetFillColor(ColorExtensions.LightGray.CGColor);
context.FillRect(rect);
NormalBackground = UIGraphics.GetImageFromCurrentImageContext();

Просмотреть файл

@ -18,9 +18,144 @@ namespace Xamarin.Forms.Platform.MacOS
#if __MOBILE__
internal static readonly UIColor Black = UIColor.Black;
internal static readonly UIColor SeventyPercentGrey = new UIColor(0.7f, 0.7f, 0.7f, 1);
internal static UIColor LabelColor
{
get
{
#if __XCODE11__
if (Forms.IsiOS13OrNewer)
return UIColor.LabelColor;
#endif
return UIColor.Black;
}
}
internal static UIColor PlaceholderColor
{
get
{
#if __XCODE11__
if (Forms.IsiOS13OrNewer)
return UIColor.PlaceholderTextColor;
#endif
return SeventyPercentGrey;
}
}
internal static UIColor SecondaryLabelColor
{
get
{
#if __XCODE11__
if (Forms.IsiOS13OrNewer)
return UIColor.SecondaryLabelColor;
#endif
return new Color(.32, .4, .57).ToUIColor();
}
}
internal static UIColor BackgroundColor
{
get
{
#if __XCODE11__
if (Forms.IsiOS13OrNewer)
return UIColor.SystemBackgroundColor;
#endif
return UIColor.White;
}
}
internal static UIColor SeparatorColor
{
get
{
#if __XCODE11__
if (Forms.IsiOS13OrNewer)
return UIColor.SeparatorColor;
#endif
return UIColor.Gray;
}
}
internal static UIColor OpaqueSeparatorColor
{
get
{
#if __XCODE11__
if (Forms.IsiOS13OrNewer)
return UIColor.OpaqueSeparatorColor;
#endif
return UIColor.Black;
}
}
internal static UIColor GroupedBackground
{
get
{
#if __XCODE11__
if (Forms.IsiOS13OrNewer)
return UIColor.SystemGroupedBackgroundColor;
#endif
return new UIColor(247f / 255f, 247f / 255f, 247f / 255f, 1);
}
}
internal static UIColor AccentColor
{
get
{
#if __XCODE11__
if (Forms.IsiOS13OrNewer)
return UIColor.SystemBlueColor;
#endif
return Color.FromRgba(50, 79, 133, 255).ToUIColor();
}
}
internal static UIColor Red
{
get
{
#if __XCODE11__
if (Forms.IsiOS13OrNewer)
return UIColor.SystemRedColor;
#endif
return UIColor.FromRGBA(1, 0, 0, 1);
}
}
internal static UIColor Gray
{
get
{
#if __XCODE11__
if (Forms.IsiOS13OrNewer)
return UIColor.SystemGrayColor;
#endif
return UIColor.Gray;
}
}
internal static UIColor LightGray
{
get
{
#if __XCODE11__
if (Forms.IsiOS13OrNewer)
return UIColor.SystemGray2Color;
#endif
return UIColor.LightGray;
}
}
#else
internal static readonly NSColor Black = NSColor.Black;
internal static readonly NSColor SeventyPercentGrey = NSColor.FromRgba(0.7f, 0.7f, 0.7f, 1);
internal static readonly NSColor LabelColor = NSColor.Black;
internal static readonly NSColor AccentColor = Color.FromRgba(50, 79, 133, 255).ToNSColor();
#endif
public static CGColor ToCGColor(this Color color)

Просмотреть файл

@ -122,7 +122,8 @@ namespace Xamarin.Forms
if (IsInitialized)
return;
IsInitialized = true;
Color.SetAccent(Color.FromRgba(50, 79, 133, 255));
Color.SetAccent(ColorExtensions.AccentColor.ToColor());
Log.Listeners.Add(new DelegateLogListener((c, m) => Trace.WriteLine(m, c)));

Просмотреть файл

@ -168,7 +168,7 @@ namespace Xamarin.Forms.Platform.iOS
if (ModalPresentationStyle == UIKit.UIModalPresentationStyle.FullScreen)
{
Color modalBkgndColor = ((Page)_modal.Element).BackgroundColor;
View.BackgroundColor = modalBkgndColor.IsDefault ? UIColor.White : modalBkgndColor.ToUIColor();
View.BackgroundColor = modalBkgndColor.IsDefault ? ColorExtensions.BackgroundColor : modalBkgndColor.ToUIColor();
}
else
{

Просмотреть файл

@ -313,7 +313,7 @@ namespace Xamarin.Forms.Platform.iOS
if (_appeared)
return;
_renderer.View.BackgroundColor = UIColor.White;
_renderer.View.BackgroundColor = ColorExtensions.BackgroundColor;
_renderer.View.ContentMode = UIViewContentMode.Redraw;
#pragma warning disable CS0618 // Type or member is obsolete

Просмотреть файл

@ -91,7 +91,7 @@ namespace Xamarin.Forms.Platform.iOS
// while it's being replaced on the Window.RootViewController with a new MainPage
if (!_disposed)
{
View.BackgroundColor = UIColor.White;
View.BackgroundColor = ColorExtensions.BackgroundColor;
Platform.WillAppear();
}

Просмотреть файл

@ -367,7 +367,7 @@ namespace Xamarin.Forms.Platform.iOS
if (bgImage != null)
View.BackgroundColor = UIColor.FromPatternImage(bgImage);
else if (Element.BackgroundColor.IsDefault)
View.BackgroundColor = UIColor.White;
View.BackgroundColor = ColorExtensions.BackgroundColor;
else
View.BackgroundColor = Element.BackgroundColor.ToUIColor();
});

Просмотреть файл

@ -10,7 +10,7 @@ namespace Xamarin.Forms.Platform.iOS
public class EditorRenderer : EditorRendererBase<UITextView>
{
// Using same placeholder color as for the Entry
readonly UIColor _defaultPlaceholderColor = ColorExtensions.SeventyPercentGrey;
readonly UIColor _defaultPlaceholderColor = ColorExtensions.PlaceholderColor;
UILabel _placeholderLabel;
@ -346,7 +346,7 @@ namespace Xamarin.Forms.Platform.iOS
var textColor = Element.TextColor;
if (textColor.IsDefault)
TextView.TextColor = UIColor.Black;
TextView.TextColor = ColorExtensions.LabelColor;
else
TextView.TextColor = textColor.ToUIColor();
}

Просмотреть файл

@ -26,7 +26,7 @@ namespace Xamarin.Forms.Platform.MacOS
if (fgcolor.IsDefault)
fgcolor = defaultForegroundColor;
if (fgcolor.IsDefault)
fgcolor = Color.Black; // as defined by apple docs
fgcolor = ColorExtensions.LabelColor.ToColor();
#if __MOBILE__
return new NSAttributedString(span.Text, font == Font.Default ? null : font.ToUIFont(), fgcolor.ToUIColor(),
@ -106,7 +106,7 @@ namespace Xamarin.Forms.Platform.MacOS
if (fgcolor.IsDefault)
fgcolor = defaultForegroundColor;
if (fgcolor.IsDefault)
fgcolor = Color.Black; // as defined by apple docs
fgcolor = ColorExtensions.LabelColor.ToColor();
#if __MOBILE__
UIColor spanFgColor;

Просмотреть файл

@ -38,6 +38,16 @@ namespace Xamarin.Forms.Platform.iOS
SetupLayer();
}
public override void TraitCollectionDidChange(UITraitCollection previousTraitCollection)
{
base.TraitCollectionDidChange(previousTraitCollection);
#if __XCODE11__
// Make sure the control adheres to changes in UI theme
if (previousTraitCollection?.UserInterfaceStyle != TraitCollection.UserInterfaceStyle)
SetupLayer();
#endif
}
public virtual void SetupLayer()
{
float cornerRadius = Element.CornerRadius;
@ -49,7 +59,7 @@ namespace Xamarin.Forms.Platform.iOS
Layer.MasksToBounds = Layer.CornerRadius > 0;
if (Element.BackgroundColor == Color.Default)
Layer.BackgroundColor = UIColor.White.CGColor;
Layer.BackgroundColor = ColorExtensions.BackgroundColor.CGColor;
else
Layer.BackgroundColor = Element.BackgroundColor.ToCGColor();

Просмотреть файл

@ -245,8 +245,7 @@ namespace Xamarin.Forms.Platform.iOS
public sealed class FontImageSourceHandler : IImageSourceHandler
{
//should this be the default color on the BP for iOS?
readonly Color _defaultColor = Color.White;
readonly Color _defaultColor = ColorExtensions.LabelColor.ToColor();
[Preserve(Conditional = true)]
public FontImageSourceHandler()

Просмотреть файл

@ -516,7 +516,7 @@ namespace Xamarin.Forms.Platform.MacOS
// default value of color documented to be black in iOS docs
#if __MOBILE__
Control.TextColor = textColor.ToUIColor(ColorExtensions.Black);
Control.TextColor = textColor.ToUIColor(ColorExtensions.LabelColor);
#else
var alignment = Element.HorizontalTextAlignment.ToNativeTextAlignment(((IVisualElementController)Element).EffectiveFlowDirection);
var textWithColor = new NSAttributedString(Element.Text ?? "", font: Element.ToNSFont(), foregroundColor: textColor.ToNSColor(ColorExtensions.Black), paragraphStyle: new NSMutableParagraphStyle() { Alignment = alignment });

Просмотреть файл

@ -302,6 +302,16 @@ namespace Xamarin.Forms.Platform.iOS
UpdateHorizontalScrollBarVisibility();
}
public override void TraitCollectionDidChange(UITraitCollection previousTraitCollection)
{
base.TraitCollectionDidChange(previousTraitCollection);
#if __XCODE11__
// Make sure the cells adhere to changes UI theme
if (previousTraitCollection?.UserInterfaceStyle != TraitCollection.UserInterfaceStyle)
ReloadData();
#endif
}
NSIndexPath[] GetPaths(int section, int index, int count)
{
var paths = new NSIndexPath[count];
@ -685,7 +695,7 @@ namespace Xamarin.Forms.Platform.iOS
// ...and Steve said to the unbelievers the separator shall be gray, and gray it was. The unbelievers looked on, and saw that it was good, and
// they went forth and documented the default color. The holy scripture still reflects this default.
// Defined here: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/#//apple_ref/occ/instp/UITableView/separatorColor
Control.SeparatorColor = color.ToUIColor(UIColor.Gray);
Control.SeparatorColor = color.ToUIColor(ColorExtensions.SeparatorColor);
}
void UpdateSeparatorVisibility()

Просмотреть файл

@ -358,6 +358,17 @@ namespace Xamarin.Forms.Platform.iOS
return shown;
}
public override void TraitCollectionDidChange(UITraitCollection previousTraitCollection)
{
base.TraitCollectionDidChange(previousTraitCollection);
#if __XCODE11__
// Make sure the control adheres to changes in UI theme
if (previousTraitCollection?.UserInterfaceStyle != TraitCollection.UserInterfaceStyle)
UpdateBackgroundColor();
#endif
}
ParentingViewController CreateViewControllerForPage(Page page)
{
if (Platform.GetRenderer(page) == null)
@ -640,7 +651,7 @@ namespace Xamarin.Forms.Platform.iOS
void UpdateBackgroundColor()
{
var color = Element.BackgroundColor == Color.Default ? Color.White : Element.BackgroundColor;
var color = Element.BackgroundColor == Color.Default ? ColorExtensions.BackgroundColor.ToColor() : Element.BackgroundColor;
View.BackgroundColor = color.ToUIColor();
}

Просмотреть файл

@ -507,7 +507,7 @@ namespace Xamarin.Forms.Platform.iOS
if (bgImage != null)
NativeView.BackgroundColor = UIColor.FromPatternImage(bgImage);
else if (Element.BackgroundColor.IsDefault)
NativeView.BackgroundColor = UIColor.White;
NativeView.BackgroundColor = ColorExtensions.BackgroundColor;
else
NativeView.BackgroundColor = Element.BackgroundColor.ToUIColor();
});

Просмотреть файл

@ -195,7 +195,7 @@ namespace Xamarin.Forms.Platform.iOS
Control.Font = Element.ToUIFont();
}
readonly Color _defaultPlaceholderColor = ColorExtensions.SeventyPercentGrey.ToColor();
readonly Color _defaultPlaceholderColor = ColorExtensions.PlaceholderColor.ToColor();
protected internal virtual void UpdatePlaceholder()
{
var formatted = (FormattedString)Element.Title;

Просмотреть файл

@ -56,7 +56,7 @@ namespace Xamarin.Forms.Platform.iOS
if (_radioButton.IsChecked)
{
_containerLayer.StrokeColor = _checkBorderStrokeColor?.CGColor ?? _nativeControl.CurrentTitleColor.CGColor;
_containerLayer.FillColor = _checkMarkFillColor?.CGColor ?? UIColor.White.CGColor;
_containerLayer.FillColor = _checkMarkFillColor?.CGColor ?? ColorExtensions.BackgroundColor.CGColor;
_checkLayer.FillColor = _checkBorderFillColor?.CGColor ?? _nativeControl.CurrentTitleColor.CGColor;
_checkLayer.StrokeColor = _checkMarkStrokeColor?.CGColor ?? _nativeControl.CurrentTitleColor.CGColor;
}

Просмотреть файл

@ -139,6 +139,16 @@ namespace Xamarin.Forms.Platform.iOS
return new RadioButtonCALayer(Element, Control);
}
public override void TraitCollectionDidChange(UITraitCollection previousTraitCollection)
{
base.TraitCollectionDidChange(previousTraitCollection);
#if __XCODE11__
// Make sure the control adheres to changes in UI theme
if (previousTraitCollection?.UserInterfaceStyle != TraitCollection.UserInterfaceStyle)
_radioButtonLayer.SetNeedsDisplay();
#endif
}
void SetRadioBoxLayer(CALayer layer)
{
_radioButtonLayer = layer;

Просмотреть файл

@ -177,6 +177,16 @@ namespace Xamarin.Forms.Platform.iOS
return sizeThatFits;
}
public override void TraitCollectionDidChange(UITraitCollection previousTraitCollection)
{
base.TraitCollectionDidChange(previousTraitCollection);
#if __XCODE11__
// Make sure the control adheres to changes in UI theme
if (previousTraitCollection?.UserInterfaceStyle != TraitCollection.UserInterfaceStyle)
UpdateTextColor();
#endif
}
void OnCancelClicked(object sender, EventArgs args)
{
ElementController.SetValueFromRenderer(SearchBar.TextProperty, null);
@ -300,7 +310,7 @@ namespace Xamarin.Forms.Platform.iOS
// https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITextField_Class/index.html#//apple_ref/occ/instp/UITextField/placeholder
var color = Element.IsEnabled && !targetColor.IsDefault
? targetColor : ColorExtensions.SeventyPercentGrey.ToColor();
? targetColor : ColorExtensions.PlaceholderColor.ToColor();
_textField.AttributedPlaceholder = formatted.ToAttributed(Element, color);
_textField.AttributedPlaceholder.AddCharacterSpacing(Element.Placeholder, Element.CharacterSpacing);
@ -309,7 +319,7 @@ namespace Xamarin.Forms.Platform.iOS
else
{
_textField.AttributedPlaceholder = formatted.ToAttributed(Element, targetColor.IsDefault
? ColorExtensions.SeventyPercentGrey.ToColor() : targetColor);
? ColorExtensions.PlaceholderColor.ToColor() : targetColor);
_textField.AttributedPlaceholder.AddCharacterSpacing(Element.Placeholder, Element.CharacterSpacing);
}
}

Просмотреть файл

@ -172,7 +172,7 @@ namespace Xamarin.Forms.Platform.iOS
var formatted = (FormattedString)_searchHandler.Placeholder ?? string.Empty;
var targetColor = _searchHandler.PlaceholderColor;
var placeHolderColor = targetColor.IsDefault ? ColorExtensions.SeventyPercentGrey.ToColor() : targetColor;
var placeHolderColor = targetColor.IsDefault ? ColorExtensions.PlaceholderColor.ToColor() : targetColor;
textField.AttributedPlaceholder = formatted.ToAttributed(_searchHandler, placeHolderColor, _searchHandler.HorizontalTextAlignment);
//Center placeholder

Просмотреть файл

@ -49,7 +49,7 @@ namespace Xamarin.Forms.Platform.iOS
protected virtual void UpdateBackground()
{
var color = _shellContext.Shell.FlyoutBackgroundColor;
View.BackgroundColor = color.ToUIColor(Color.White);
View.BackgroundColor = color.ToUIColor(ColorExtensions.BackgroundColor);
if (View.BackgroundColor.CGColor.Alpha < 1)
{

Просмотреть файл

@ -252,7 +252,7 @@ namespace Xamarin.Forms.Platform.iOS
{
var color = Shell.BackgroundColor;
if (color.IsDefault)
color = Color.Black;
color = ColorExtensions.BackgroundColor.ToColor();
FlyoutRenderer.View.BackgroundColor = color.ToUIColor();
}

Просмотреть файл

@ -210,7 +210,7 @@ namespace Xamarin.Forms.Platform.iOS
{
_line = new UIView
{
BackgroundColor = UIColor.Black,
BackgroundColor = ColorExtensions.OpaqueSeparatorColor,
TranslatesAutoresizingMaskIntoConstraints = true,
Alpha = 0.2f
};

Просмотреть файл

@ -151,14 +151,7 @@ namespace Xamarin.Forms.Platform.iOS
protected override void SetBackgroundColor(Color color)
{
UIColor backgroundColor;
#if __XCODE11__
if (Forms.IsiOS13OrNewer)
backgroundColor = UIColor.SystemBackgroundColor;
else
#endif
backgroundColor = UIColor.White;
UIColor backgroundColor = ColorExtensions.BackgroundColor;
if (Element.BackgroundColor != Color.Default)
{

Просмотреть файл

@ -127,6 +127,16 @@ namespace Xamarin.Forms.Platform.iOS
base.UpdateNativeWidget();
}
public override void TraitCollectionDidChange(UITraitCollection previousTraitCollection)
{
base.TraitCollectionDidChange(previousTraitCollection);
#if __XCODE11__
// Make sure the cells adhere to changes UI theme
if (previousTraitCollection?.UserInterfaceStyle != TraitCollection.UserInterfaceStyle)
Control.ReloadData();
#endif
}
void SetSource()
{
var modeledView = Element;

Просмотреть файл

@ -372,7 +372,7 @@ namespace Xamarin.Forms.Platform.iOS
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
_masterController.View.BackgroundColor = UIColor.White;
_masterController.View.BackgroundColor = ColorExtensions.BackgroundColor;
}
public override void WillRotate(UIInterfaceOrientation toInterfaceOrientation, double duration)
@ -511,7 +511,7 @@ namespace Xamarin.Forms.Platform.iOS
if (bgImage != null)
View.BackgroundColor = UIColor.FromPatternImage(bgImage);
else if (Element.BackgroundColor == Color.Default)
View.BackgroundColor = UIColor.White;
View.BackgroundColor = ColorExtensions.BackgroundColor;
else
View.BackgroundColor = Element.BackgroundColor.ToUIColor();
});

Просмотреть файл

@ -5,6 +5,7 @@ using RectangleF = CoreGraphics.CGRect;
using SizeF = CoreGraphics.CGSize;
#if __MOBILE__
using UIKit;
using NativeColor = UIKit.UIColor;
using NativeControl = UIKit.UIControl;
using NativeView = UIKit.UIView;
@ -233,6 +234,16 @@ namespace Xamarin.Forms.Platform.MacOS
}
#if __MOBILE__
public override void TraitCollectionDidChange(UITraitCollection previousTraitCollection)
{
base.TraitCollectionDidChange(previousTraitCollection);
#if __XCODE11__
// Make sure the control adheres to changes in UI theme
if (previousTraitCollection?.UserInterfaceStyle != TraitCollection.UserInterfaceStyle)
Control.SetNeedsDisplay();
#endif
}
internal override void SendVisualElementInitialized(VisualElement element, NativeView nativeView)
{
base.SendVisualElementInitialized(element, Control);