diff --git a/Xamarin.Forms.Controls/App.cs b/Xamarin.Forms.Controls/App.cs index e56e635ab4e..c9989f34407 100644 --- a/Xamarin.Forms.Controls/App.cs +++ b/Xamarin.Forms.Controls/App.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Xamarin.Forms.Internals; using Xamarin.Forms.PlatformConfiguration; +using Xamarin.Forms.PlatformConfiguration.iOSSpecific; using Xamarin.Forms.PlatformConfiguration.WindowsSpecific; namespace Xamarin.Forms.Controls @@ -47,10 +48,14 @@ public App() public Page CreateDefaultMainPage() { + var layout = new StackLayout { BackgroundColor = Color.Red }; + layout.Children.Add(new Label { Text ="This is master Page" }); + var master = new ContentPage { Title = "Master", Content = layout, BackgroundColor = Color.SkyBlue }; + master.On().SetUseSafeArea(true); return new MasterDetailPage { AutomationId = DefaultMainPageId, - Master = new ContentPage { Title = "Master", Content = new View { BackgroundColor = Color.Red } }, + Master = master, Detail = CoreGallery.GetMainPage() }; } diff --git a/Xamarin.Forms.Controls/CoreGallery.cs b/Xamarin.Forms.Controls/CoreGallery.cs index 26e9a5905d2..307f3fdd2a5 100644 --- a/Xamarin.Forms.Controls/CoreGallery.cs +++ b/Xamarin.Forms.Controls/CoreGallery.cs @@ -11,6 +11,8 @@ using Xamarin.Forms.Controls.GalleryPages; using Xamarin.Forms.CustomAttributes; using Xamarin.Forms.Internals; +using Xamarin.Forms.PlatformConfiguration; +using Xamarin.Forms.PlatformConfiguration.iOSSpecific; namespace Xamarin.Forms.Controls { @@ -33,6 +35,7 @@ internal class CoreContentPage : ContentPage { public CoreContentPage () { + On().SetUseSafeArea(true); AutomationId = "ContentPageRoot"; Content = new StackLayout { Children = { new CoreRootView (), new CorePageView (this, NavigationBehavior.PushModalAsync) } }; } @@ -80,6 +83,8 @@ public CoreNavigationPage () return false; }); + On().SetPrefersLargeTitles(true); + Navigation.PushAsync (new CoreRootPage (this)); } } diff --git a/Xamarin.Forms.Controls/GalleryPages/PlatformSpecificsGalleries/LargeTitlesPageiOS.cs b/Xamarin.Forms.Controls/GalleryPages/PlatformSpecificsGalleries/LargeTitlesPageiOS.cs new file mode 100644 index 00000000000..313eeee8113 --- /dev/null +++ b/Xamarin.Forms.Controls/GalleryPages/PlatformSpecificsGalleries/LargeTitlesPageiOS.cs @@ -0,0 +1,59 @@ +using System; +using System.Windows.Input; +using Xamarin.Forms.PlatformConfiguration; +using Xamarin.Forms.PlatformConfiguration.iOSSpecific; + +namespace Xamarin.Forms.Controls.GalleryPages.PlatformSpecificsGalleries +{ + public class LargeTitlesPageiOS : ContentPage + { + public LargeTitlesPageiOS(ICommand restore) + { + Title = "Large Titles"; + + var offscreenPageLimit = new Label(); + var content = new StackLayout + { + VerticalOptions = LayoutOptions.Fill, + HorizontalOptions = LayoutOptions.Fill, + Children = + { + new Button + { + Text = "LargeTitleDisplayMode.Never", + Command = new Command(() => On().SetLargeTitleDisplay(LargeTitleDisplayMode.Never)) + }, + new Button + { + Text = "LargeTitleDisplayMode.Always", + Command = new Command(() => On().SetLargeTitleDisplay(LargeTitleDisplayMode.Always)) + }, + new Button + { + Text = "LargeTitleDisplayMode.Automatic -> next page will have same LargeTitleDisplayMode as this one", + Command = new Command(async () =>{ + var page = new ContentPage { Title = "Page Title" }; + page.On().SetLargeTitleDisplay(LargeTitleDisplayMode.Automatic); + await Navigation.PushAsync(page); + } ) + }, + new Button + { + Text = "Tooggle UseLargeTitles on Navigation", + Command = new Command( () =>{ + var navPage = (Parent as NavigationPage); + navPage.On().SetPrefersLargeTitles(!navPage.On().PrefersLargeTitles()); + } ) + }, + offscreenPageLimit + } + }; + + var restoreButton = new Button { Text = "Back To Gallery" }; + restoreButton.Clicked += async (sender, args) => await Navigation.PopAsync(); + content.Children.Add(restoreButton); + + Content = content; + } + } +} diff --git a/Xamarin.Forms.Controls/GalleryPages/PlatformSpecificsGalleries/SafeAreaPageiOS.cs b/Xamarin.Forms.Controls/GalleryPages/PlatformSpecificsGalleries/SafeAreaPageiOS.cs new file mode 100644 index 00000000000..e94d2d4b493 --- /dev/null +++ b/Xamarin.Forms.Controls/GalleryPages/PlatformSpecificsGalleries/SafeAreaPageiOS.cs @@ -0,0 +1,348 @@ +using System; +using System.Collections.Generic; +using System.Windows.Input; +using Xamarin.Forms.Internals; +using Xamarin.Forms.PlatformConfiguration; +using Xamarin.Forms.PlatformConfiguration.iOSSpecific; +using static Xamarin.Forms.Controls.Issues.Issue2259; + +namespace Xamarin.Forms.Controls.GalleryPages.PlatformSpecificsGalleries +{ + public class SafeAreaPageiOS : ContentPage + { + Label safeLimits; + + public SafeAreaPageiOS(ICommand restore, Command setRoot) + { + Title = "Safe Area"; + BackgroundColor = Color.Azure; + On().SetUseSafeArea(true); + + Construct(this, restore, setRoot); + } + + void Construct(ContentPage page, ICommand restore, Command setRoot) + { + safeLimits = new Label { Text = "nothing" }; + var grid = new Grid + { + VerticalOptions = LayoutOptions.Fill, + HorizontalOptions = LayoutOptions.Fill, + }; + grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); + grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star }); + grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); + var safeLimitsTop = new Label + { + Text = "top", + BackgroundColor = Color.Pink, + HorizontalOptions = LayoutOptions.Start, + VerticalOptions = LayoutOptions.Start, + InputTransparent = true + }; + grid.Children.Add(safeLimitsTop); + Grid.SetRow(safeLimitsTop, 0); + var safeLimitsBottom = new Label + { + Text = "bottom", + BackgroundColor = Color.Pink, + HorizontalOptions = LayoutOptions.End, + VerticalOptions = LayoutOptions.End, + InputTransparent = true + }; + grid.Children.Add(safeLimitsBottom); + Grid.SetRow(safeLimitsBottom, 2); + + var content = new ScrollView + { + Content = new StackLayout + { + VerticalOptions = LayoutOptions.Fill, + HorizontalOptions = LayoutOptions.Fill, + Children = { + safeLimits, + new Button + { + Text = "Set Content as root", + Command = new Command(() => + { + var pageSafe = new SafeAreaPageiOS(restore,setRoot); + setRoot.Execute(pageSafe); + }) + }, + new Button + { + Text = "Set NavigationPage as root", + Command = new Command(() => + { + var pageSafe = new SafeAreaPageiOS(restore,setRoot); + setRoot.Execute(new NavigationPage(pageSafe)); + }) + }, + new Button + { + Text = "Set TabbedPage as root", + Command = new Command(() => + { + var pageSafe = new SafeAreaPageiOS(restore,setRoot); + var pageNotSafe = new SafeAreaPageiOS(restore,setRoot); + pageNotSafe.On().SetUseSafeArea(false); + pageNotSafe.Title ="Not Using Safe Area"; + var tabbedPage = new TabbedPage(); + tabbedPage.Children.Add(pageSafe); + tabbedPage.Children.Add(pageNotSafe); + setRoot.Execute(tabbedPage); + }) + }, + new Button + { + Text = "Set TabbedPage and NavigationPage as root", + Command = new Command(() => + { + var pageSafe = new SafeAreaPageiOS(restore,setRoot); + var pageNotSafe = new SafeAreaPageiOS(restore,setRoot); + pageNotSafe.On().SetUseSafeArea(false); + pageNotSafe.Title ="Not Using Safe Area"; + var tabbedPage = new TabbedPage(); + tabbedPage.Children.Add(new NavigationPage(pageSafe) { Title = pageSafe.Title}); + tabbedPage.Children.Add(new NavigationPage(pageNotSafe) { Title = pageNotSafe.Title}); + setRoot.Execute(tabbedPage); + }) + }, + new Button + { + Text = "Set CarouselPage as root", + Command = new Command(() => + { + var pageSafe = new SafeAreaPageiOS(restore,setRoot); + var pageNotSafe = new SafeAreaPageiOS(restore,setRoot); + pageNotSafe.On().SetUseSafeArea(false); + pageNotSafe.Title ="Not Using Safe Area"; + var carouselPage = new CarouselPage(); + carouselPage.Children.Add(pageSafe); + carouselPage.Children.Add(pageNotSafe); + setRoot.Execute(carouselPage); + }) + }, + new Button + { + Text = "Toggle use safe area", + Command = new Command(() => On().SetUseSafeArea(!On().UsingSafeArea())) + }, + new Button + { + Text = "ListViewPage with safe area", + Command = new Command(()=>{ + var pageLIST = new ListViewPage("1", restore); + pageLIST.On().SetUseSafeArea(true); + setRoot.Execute(pageLIST); + }) + },new Button + { + Text = "ListViewPage with no safe area", + Command = new Command(()=>{ + var pageLIST = new ListViewPage("1", restore); + setRoot.Execute(pageLIST); + }), + + },new Button + { + Text = "ListViewPageGrouping with no safe area", + Command = new Command(()=>{ + var pageLIST = GetGroupedListView(restore); + (pageLIST.Content as ListView).Header = new Button { Text = "Go back To gallery", Command = restore }; + setRoot.Execute(pageLIST); + }) + },new Button + { + Text = "ListViewPageGrouping using SafeAreaInsets", + Command = new Command(()=>{ + var pageLIST = GetGroupedListView(restore); + pageLIST.PropertyChanged += (sender, e) => { + if(e.PropertyName == "SafeAreaInsets") + { + var safeAreaInsets = pageLIST.On().SafeAreaInsets(); + //we always want to pad the top when using grouping + pageLIST.Padding = new Thickness(0,safeAreaInsets.Top,0,0); + } + }; + setRoot.Execute(pageLIST); + }) + }, + new Button + { + Text = "ListViewPageGrouping with safe area", + Command = new Command(()=>{ + var pageLIST = GetGroupedListView(restore); + pageLIST.On().SetUseSafeArea(true); + setRoot.Execute(pageLIST); + }) + }, + new Button + { + Text = "TableView+TextCell with safe area", + Command = new Command(()=>{ + var pageTable = new TableViewPage(restore); + pageTable.On().SetUseSafeArea(true); + setRoot.Execute(pageTable); + }) + }, + new Button + { + Text = "TableView+TextCell with no safe area", + Command = new Command(()=>{ + var pageTable = new TableViewPage(restore); + setRoot.Execute(pageTable); + }) + }, + new Button + { + Text = "Back To Gallery", + Command = restore + }, + + } + } + }; + grid.Children.Add(content); + Grid.SetRow(content, 1); + + page.Content = grid; + } + + protected override void OnPropertyChanged(string propertyName = null) + { + if (propertyName == "SafeAreaInsets") + { + safeLimits.Text = $" Top:{On().SafeAreaInsets().Top} - Bottom:{On().SafeAreaInsets().Bottom} - Left:{On().SafeAreaInsets().Left} - Right:{On().SafeAreaInsets().Right}"; + } + base.OnPropertyChanged(propertyName); + } + + ContentPage GetGroupedListView(ICommand restore) + { + var pageLIST = new GroupedListActionsGallery(); + NavigationPage.SetHasNavigationBar(pageLIST, true); + (pageLIST.Content as ListView).Header = new Button { Text = "Go back To gallery", Command = restore }; + return pageLIST; + } + + [Preserve(AllMembers = true)] + class MViewCell : ViewCell + { + Label firstNameLabel = new Label(); + Label lastNameLabel = new Label(); + Label cityLabel = new Label(); + Label stateLabel = new Label { HorizontalOptions = LayoutOptions.End }; + + public MViewCell() + { + View = new StackLayout + { + Orientation = StackOrientation.Horizontal, + Children = + { + firstNameLabel, + lastNameLabel, + cityLabel, + stateLabel + } + }; + firstNameLabel.SetBinding(Label.TextProperty, "FirstName"); + lastNameLabel.SetBinding(Label.TextProperty, "LastName"); + cityLabel.SetBinding(Label.TextProperty, "City"); + stateLabel.SetBinding(Label.TextProperty, "State"); + + } + } + + [Preserve(AllMembers = true)] + class TableViewPage : ContentPage + { + public TableViewPage(ICommand restore) + { + Content = new TableView + { + Intent = TableIntent.Form, + Root = new TableRoot("Table Title") { + new TableSection ("Section 1 Title") { + new ViewCell { + View = new Button{ BackgroundColor = Color.Red, Command = restore, Text = "Back To Gallery", HorizontalOptions = LayoutOptions.Start } + } + }, + new TableSection ("Section 1 Title") { + new ViewCell { + View = new Label { Text = "ViewCell Text with 10 margin top", Margin = new Thickness(0,10,0,0), BackgroundColor = Color.Pink }, + }, + new TextCell { + Text = "TextCell Text", + Detail = "TextCell Detail" + }, + new TextCell { + Text = "TextCell Text", + Detail = "TextCell Detail" + }, + new TextCell { + Text = "TextCell Text", + Detail = "TextCell Detail" + }, + new EntryCell { + Label = "EntryCell:", + Placeholder = "default keyboard", + Keyboard = Keyboard.Default + } + }, + new TableSection ("Section 2 Title") { + new EntryCell { + Label = "Another EntryCell:", + Placeholder = "phone keyboard", + Keyboard = Keyboard.Telephone + }, + new SwitchCell { + Text = "SwitchCell:" + } + } + } + }; + } + } + + [Preserve(AllMembers = true)] + class ListViewPage : ContentPage + { + ListView _listview; + List _People = new List(); + + public ListViewPage(string id, ICommand restore) + { + Title = $"List {id}"; + + for (var x = 0; x < 1000; x++) + { + _People.Add(new Person($"Bob {x}", $"Bobson {x}", "San Francisco", "California")); + } + + _listview = new ListView(ListViewCachingStrategy.RecycleElementAndDataTemplate) { ItemTemplate = new DataTemplate(typeof(MViewCell)) }; + _listview.ItemsSource = _People; + _listview.Header = new Button { Text = "Go back To gallery", Command = restore }; + Content = _listview; + } + } + + [Preserve(AllMembers = true)] + class Person + { + public Person(string firstName, string lastName, string city, string state) + { + FirstName = firstName; + LastName = lastName; + City = city; + State = state; + } + public string FirstName { get; set; } + public string LastName { get; set; } + public string City { get; set; } + public string State { get; set; } + } + } +} diff --git a/Xamarin.Forms.Controls/GalleryPages/PlatformSpecificsGallery.cs b/Xamarin.Forms.Controls/GalleryPages/PlatformSpecificsGallery.cs index dbfa554c2ef..e1c51b8df83 100644 --- a/Xamarin.Forms.Controls/GalleryPages/PlatformSpecificsGallery.cs +++ b/Xamarin.Forms.Controls/GalleryPages/PlatformSpecificsGallery.cs @@ -18,6 +18,8 @@ public PlatformSpecificsGallery() var appAndroidButton = new Button() { Text = "Application (Android)" }; var tbAndroidButton = new Button { Text = "TabbedPage (Android)" }; var entryiOSButton = new Button() { Text = "Entry (iOS)" }; + var largeTitlesiOSButton = new Button() { Text = "Large Title (iOS)" }; + var safeareaiOSButton = new Button() { Text = "SafeArea (iOS)" }; mdpiOSButton.Clicked += (sender, args) => { SetRoot(new MasterDetailPageiOS(new Command(RestoreOriginal))); }; mdpWindowsButton.Clicked += (sender, args) => { SetRoot(new MasterDetailPageWindows(new Command(RestoreOriginal))); }; @@ -29,11 +31,17 @@ public PlatformSpecificsGallery() appAndroidButton.Clicked += (sender, args) => { SetRoot(new ApplicationAndroid(new Command(RestoreOriginal))); }; tbAndroidButton.Clicked += (sender, args) => { SetRoot(new TabbedPageAndroid(new Command(RestoreOriginal))); }; entryiOSButton.Clicked += (sender, args) => { Navigation.PushAsync(new EntryPageiOS()); }; - + largeTitlesiOSButton.Clicked += (sender, args) => { Navigation.PushAsync(new LargeTitlesPageiOS(new Command(RestoreOriginal))); }; + safeareaiOSButton.Clicked += (sender, args) => { SetRoot(new SafeAreaPageiOS(new Command(RestoreOriginal), new Command( p => SetRoot(p)))); }; - Content = new StackLayout + + Content = new ScrollView { - Children = { mdpiOSButton, mdpWindowsButton, npWindowsButton, tbiOSButton, tbWindowsButton, viselemiOSButton, appAndroidButton, tbAndroidButton, entryiOSButton } + Content = new StackLayout + { + Children = { mdpiOSButton, mdpWindowsButton, npWindowsButton, tbiOSButton, tbWindowsButton, viselemiOSButton, + appAndroidButton, tbAndroidButton, entryiOSButton, largeTitlesiOSButton, safeareaiOSButton } + } }; } diff --git a/Xamarin.Forms.Controls/Xamarin.Forms.Controls.csproj b/Xamarin.Forms.Controls/Xamarin.Forms.Controls.csproj index eda7b8526ab..6acca850543 100644 --- a/Xamarin.Forms.Controls/Xamarin.Forms.Controls.csproj +++ b/Xamarin.Forms.Controls/Xamarin.Forms.Controls.csproj @@ -261,6 +261,8 @@ MacTwitterDemo.xaml + + diff --git a/Xamarin.Forms.Core/PlatformConfiguration/iOSSpecific/LargeTitleDisplayMode.cs b/Xamarin.Forms.Core/PlatformConfiguration/iOSSpecific/LargeTitleDisplayMode.cs new file mode 100644 index 00000000000..32612b81f7a --- /dev/null +++ b/Xamarin.Forms.Core/PlatformConfiguration/iOSSpecific/LargeTitleDisplayMode.cs @@ -0,0 +1,10 @@ +using System; +namespace Xamarin.Forms.PlatformConfiguration.iOSSpecific +{ + public enum LargeTitleDisplayMode + { + Automatic, + Always, + Never + } +} diff --git a/Xamarin.Forms.Core/PlatformConfiguration/iOSSpecific/NavigationPage.cs b/Xamarin.Forms.Core/PlatformConfiguration/iOSSpecific/NavigationPage.cs index 1f4472db0b8..9edc618098e 100644 --- a/Xamarin.Forms.Core/PlatformConfiguration/iOSSpecific/NavigationPage.cs +++ b/Xamarin.Forms.Core/PlatformConfiguration/iOSSpecific/NavigationPage.cs @@ -71,5 +71,28 @@ public static StatusBarTextColorMode GetStatusBarTextColorMode(this IPlatformEle return config; } #endregion + + public static readonly BindableProperty PrefersLargeTitlesProperty = BindableProperty.Create(nameof(PrefersLargeTitles), typeof(bool), typeof(Page), false); + + public static bool GetPrefersLargeTitles(BindableObject element) + { + return (bool)element.GetValue(PrefersLargeTitlesProperty); + } + + public static void SetPrefersLargeTitles(BindableObject element, bool value) + { + element.SetValue(PrefersLargeTitlesProperty, value); + } + + public static IPlatformElementConfiguration SetPrefersLargeTitles(this IPlatformElementConfiguration config, bool value) + { + SetPrefersLargeTitles(config.Element, value); + return config; + } + + public static bool PrefersLargeTitles(this IPlatformElementConfiguration config) + { + return GetPrefersLargeTitles(config.Element); + } } } diff --git a/Xamarin.Forms.Core/PlatformConfiguration/iOSSpecific/Page.cs b/Xamarin.Forms.Core/PlatformConfiguration/iOSSpecific/Page.cs index a32a152131c..0a4cc9ce416 100644 --- a/Xamarin.Forms.Core/PlatformConfiguration/iOSSpecific/Page.cs +++ b/Xamarin.Forms.Core/PlatformConfiguration/iOSSpecific/Page.cs @@ -56,5 +56,91 @@ public static UIStatusBarAnimation PreferredStatusBarUpdateAnimation(this IPlatf SetPreferredStatusBarUpdateAnimation(config.Element, value); return config; } + + public static readonly BindableProperty UseSafeAreaProperty = BindableProperty.Create("UseSafeArea", typeof(bool), typeof(Page), false, propertyChanged: (bindable, oldValue, newValue) => + { + var page = bindable as Xamarin.Forms.Page; + if ((bool)oldValue && !(bool)newValue) + { + page.Padding = default(Thickness); + } + }); + + public static bool GetUseSafeArea(BindableObject element) + { + return (bool)element.GetValue(UseSafeAreaProperty); + } + + public static void SetUseSafeArea(BindableObject element, bool value) + { + element.SetValue(UseSafeAreaProperty, value); + } + + public static IPlatformElementConfiguration SetUseSafeArea(this IPlatformElementConfiguration config, bool value) + { + SetUseSafeArea(config.Element, value); + return config; + } + + public static bool UsingSafeArea(this IPlatformElementConfiguration config) + { + return GetUseSafeArea(config.Element); + } + + public static readonly BindableProperty LargeTitleDisplayProperty = BindableProperty.Create(nameof(LargeTitleDisplay), typeof(LargeTitleDisplayMode), typeof(Page), LargeTitleDisplayMode.Automatic); + + public static LargeTitleDisplayMode GetLargeTitleDisplay(BindableObject element) + { + return (LargeTitleDisplayMode)element.GetValue(LargeTitleDisplayProperty); + } + + public static void SetLargeTitleDisplay(BindableObject element, LargeTitleDisplayMode value) + { + element.SetValue(LargeTitleDisplayProperty, value); + } + + public static LargeTitleDisplayMode LargeTitleDisplay(this IPlatformElementConfiguration config) + { + return GetLargeTitleDisplay(config.Element); + } + + public static IPlatformElementConfiguration SetLargeTitleDisplay(this IPlatformElementConfiguration config, LargeTitleDisplayMode value) + { + SetLargeTitleDisplay(config.Element, value); + return config; + } + + static readonly BindablePropertyKey SafeAreaInsetsPropertyKey = BindableProperty.CreateReadOnly(nameof(SafeAreaInsets), typeof(Thickness), typeof(Page), default(Thickness), propertyChanged: (bindable, oldValue, newValue) => + { + var page = bindable as Xamarin.Forms.Page; + if (page.On().UsingSafeArea()) + { + page.Padding = (Thickness)newValue; + } + }); + + public static readonly BindableProperty SafeAreaInsetsProperty = SafeAreaInsetsPropertyKey.BindableProperty; + + public static Thickness GetSafeAreaInsets(BindableObject element) + { + return (Thickness)element.GetValue(SafeAreaInsetsProperty); + } + + static void SetSafeAreaInsets(BindableObject element, Thickness value) + { + element.SetValue(SafeAreaInsetsPropertyKey, value); + } + + public static Thickness SafeAreaInsets(this IPlatformElementConfiguration config) + { + return GetSafeAreaInsets(config.Element); + } + + public static IPlatformElementConfiguration SetSafeAreaInsets(this IPlatformElementConfiguration config, Thickness value) + { + SetSafeAreaInsets(config.Element, value); + return config; + } + } } diff --git a/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj b/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj index 3ef9a2a69b2..65ab157e0af 100644 --- a/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj +++ b/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj @@ -463,6 +463,7 @@ + diff --git a/Xamarin.Forms.Platform.iOS/Cells/CellRenderer.cs b/Xamarin.Forms.Platform.iOS/Cells/CellRenderer.cs index 0abf7f809ae..8c558b4c0d3 100644 --- a/Xamarin.Forms.Platform.iOS/Cells/CellRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Cells/CellRenderer.cs @@ -24,12 +24,17 @@ public virtual UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, return tvc; } + public virtual void SetBackgroundColor(UITableViewCell tableViewCell, Cell cell, UIColor color) + { + tableViewCell.BackgroundColor = color; + } + protected void UpdateBackground(UITableViewCell tableViewCell, Cell cell) { if (cell.GetIsGroupHeader, Cell>()) { if (UIDevice.CurrentDevice.CheckSystemVersion(7, 0)) - tableViewCell.BackgroundColor = new UIColor(247f / 255f, 247f / 255f, 247f / 255f, 1); + SetBackgroundColor(tableViewCell, cell, new UIColor(247f / 255f, 247f / 255f, 247f / 255f, 1)); } else { @@ -40,7 +45,7 @@ protected void UpdateBackground(UITableViewCell tableViewCell, Cell cell) if (element != null) bgColor = element.BackgroundColor == Color.Default ? bgColor : element.BackgroundColor.ToUIColor(); - tableViewCell.BackgroundColor = bgColor; + SetBackgroundColor(tableViewCell, cell, bgColor); } } diff --git a/Xamarin.Forms.Platform.iOS/Cells/ViewCellRenderer.cs b/Xamarin.Forms.Platform.iOS/Cells/ViewCellRenderer.cs index d30d4397f14..f5a693043d3 100644 --- a/Xamarin.Forms.Platform.iOS/Cells/ViewCellRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Cells/ViewCellRenderer.cs @@ -30,6 +30,16 @@ public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, return cell; } + public override void SetBackgroundColor(UITableViewCell tableViewCell, Cell cell, UIColor color) + { + if (cell is ViewCell && Forms.IsiOS11OrNewer) + { + color = (cell as ViewCell).View.BackgroundColor == Color.Default ? color : (cell as ViewCell).View.BackgroundColor.ToUIColor(); + tableViewCell.BackgroundColor = color; + } + base.SetBackgroundColor(tableViewCell, cell, color); + } + static void UpdateIsEnabled(ViewTableCell cell, ViewCell viewCell) { cell.UserInteractionEnabled = viewCell.IsEnabled; @@ -84,6 +94,12 @@ public override void LayoutSubviews() var contentFrame = ContentView.Frame; var view = ViewCell.View; + if (Forms.IsiOS11OrNewer) + { + var rect = new Rectangle(ContentView.LayoutMargins.Left, 0, contentFrame.Width - ContentView.LayoutMargins.Left, contentFrame.Height); + contentFrame = rect.ToRectangleF(); + } + Layout.LayoutChildIntoBoundingRegion(view, contentFrame.ToRectangle()); if (_rendererRef == null) diff --git a/Xamarin.Forms.Platform.iOS/Renderers/NavigationRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/NavigationRenderer.cs index 67078440b86..25dec56c252 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/NavigationRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/NavigationRenderer.cs @@ -8,6 +8,7 @@ using Xamarin.Forms.Internals; using Xamarin.Forms.PlatformConfiguration.iOSSpecific; using static Xamarin.Forms.PlatformConfiguration.iOSSpecific.Page; +using static Xamarin.Forms.PlatformConfiguration.iOSSpecific.NavigationPage; using PageUIStatusBarAnimation = Xamarin.Forms.PlatformConfiguration.iOSSpecific.UIStatusBarAnimation; using PointF = CoreGraphics.CGPoint; using RectangleF = CoreGraphics.CGRect; @@ -148,11 +149,12 @@ public override void ViewDidLayoutSubviews() base.ViewDidLayoutSubviews(); UpdateToolBarVisible(); - var navBarFrame = NavigationBar.Frame; + //var navBarFrameBotton = Forms.IsiOS11OrNewer ? View.SafeAreaInsets.Top : NavigationBar.Frame.Bottom; + var navBarFrameBotton = NavigationBar.Frame.Bottom; var toolbar = _secondaryToolbar; // Use 0 if the NavBar is hidden or will be hidden - var toolbarY = NavigationBarHidden || NavigationBar.Translucent || !NavigationPage.GetHasNavigationBar(Current) ? 0 : navBarFrame.Bottom; + var toolbarY = NavigationBarHidden || NavigationBar.Translucent || !NavigationPage.GetHasNavigationBar(Current) ? 0 : navBarFrameBotton; toolbar.Frame = new RectangleF(0, toolbarY, View.Frame.Width, toolbar.Frame.Height); double trueBottom = toolbar.Hidden ? toolbarY : toolbar.Frame.Bottom; @@ -205,6 +207,7 @@ public override void ViewDidLoad() UpdateTint(); UpdateBarBackgroundColor(); UpdateBarTextColor(); + UpdateUseLargeTitles(); // If there is already stuff on the stack we need to push it navPage.Pages.ForEach(async p => await PushPageAsync(p, false)); @@ -442,6 +445,9 @@ void HandlePropertyChanged(object sender, PropertyChangedEventArgs e) UpdateTranslucent(); else if (e.PropertyName == PreferredStatusBarUpdateAnimationProperty.PropertyName) UpdateCurrentPagePreferredStatusBarUpdateAnimation(); + else if (e.PropertyName == PrefersLargeTitlesProperty.PropertyName) + UpdateUseLargeTitles(); + } void UpdateCurrentPagePreferredStatusBarUpdateAnimation() @@ -452,6 +458,14 @@ void UpdateCurrentPagePreferredStatusBarUpdateAnimation() PlatformConfiguration.iOSSpecific.Page.SetPreferredStatusBarUpdateAnimation(Current.OnThisPlatform(), animation); } + void UpdateUseLargeTitles() + { + var navPage = (Element as NavigationPage); + if (Forms.IsiOS11OrNewer && navPage != null) + NavigationBar.PrefersLargeTitles = navPage.OnThisPlatform().PrefersLargeTitles(); + } + + void UpdateTranslucent() { NavigationBar.Translucent = ((NavigationPage)Element).OnThisPlatform().IsNavigationBarTranslucent(); @@ -599,6 +613,12 @@ void UpdateBarTextColor() NavigationBar.TitleTextAttributes = titleAttributes; } + if(Forms.IsiOS11OrNewer) + { + NavigationBar.LargeTitleTextAttributes = NavigationBar.TitleTextAttributes; + } + + var statusBarColorMode = (Element as NavigationPage).OnThisPlatform().GetStatusBarTextColorMode(); // set Tint color (i. e. Back Button arrow and Text) @@ -782,6 +802,7 @@ public Page Child _child.PropertyChanged += HandleChildPropertyChanged; UpdateHasBackButton(); + UpdateLargeTitles(); } } @@ -887,6 +908,8 @@ void HandleChildPropertyChanged(object sender, PropertyChangedEventArgs e) UpdateHasBackButton(); else if (e.PropertyName == PrefersStatusBarHiddenProperty.PropertyName) UpdatePrefersStatusBarHidden(); + else if (e.PropertyName == LargeTitleDisplayProperty.PropertyName) + UpdateLargeTitles(); } void UpdatePrefersStatusBarHidden() @@ -958,6 +981,27 @@ void UpdateToolbarItems() n.UpdateToolBarVisible(); } + void UpdateLargeTitles() + { + var page = Child; + if (page != null && Forms.IsiOS11OrNewer) + { + var largeTitleDisplayMode = page.OnThisPlatform().LargeTitleDisplay(); + switch (largeTitleDisplayMode) + { + case LargeTitleDisplayMode.Always: + NavigationItem.LargeTitleDisplayMode = UINavigationItemLargeTitleDisplayMode.Always; + break; + case LargeTitleDisplayMode.Automatic: + NavigationItem.LargeTitleDisplayMode = UINavigationItemLargeTitleDisplayMode.Automatic; + break; + case LargeTitleDisplayMode.Never: + NavigationItem.LargeTitleDisplayMode = UINavigationItemLargeTitleDisplayMode.Never; + break; + } + } + } + public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations() { IVisualElementRenderer childRenderer; diff --git a/Xamarin.Forms.Platform.iOS/Renderers/PageRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/PageRenderer.cs index cd7bdc6245f..fb42b9684d2 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/PageRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/PageRenderer.cs @@ -63,6 +63,23 @@ public void SetElementSize(Size size) Element.Layout(new Rectangle(Element.X, Element.Y, size.Width, size.Height)); } + public override void ViewSafeAreaInsetsDidChange() + { + + var page = (Element as Page); + if (page != null && Forms.IsiOS11OrNewer) + { + var insets = NativeView.SafeAreaInsets; + if(page.Parent is TabbedPage) + { + insets.Bottom = 0; + } + page.On().SetSafeAreaInsets(new Thickness(insets.Left, insets.Top, insets.Right, insets.Bottom)); + + } + base.ViewSafeAreaInsetsDidChange(); + } + public UIViewController ViewController => _disposed ? null : this; public override void ViewDidAppear(bool animated) diff --git a/docs/Xamarin.Forms.Core/Xamarin.Forms.PlatformConfiguration.iOSSpecific/LargeTitleDisplayMode.xml b/docs/Xamarin.Forms.Core/Xamarin.Forms.PlatformConfiguration.iOSSpecific/LargeTitleDisplayMode.xml new file mode 100644 index 00000000000..3a7371b8a1c --- /dev/null +++ b/docs/Xamarin.Forms.Core/Xamarin.Forms.PlatformConfiguration.iOSSpecific/LargeTitleDisplayMode.xml @@ -0,0 +1,59 @@ + + + + + Xamarin.Forms.Core + 2.0.0.0 + + + System.Enum + + + To be added. + To be added. + + + + + + Field + + 2.0.0.0 + + + Xamarin.Forms.PlatformConfiguration.iOSSpecific.LargeTitleDisplayMode + + + To be added. + + + + + + Field + + 2.0.0.0 + + + Xamarin.Forms.PlatformConfiguration.iOSSpecific.LargeTitleDisplayMode + + + To be added. + + + + + + Field + + 2.0.0.0 + + + Xamarin.Forms.PlatformConfiguration.iOSSpecific.LargeTitleDisplayMode + + + To be added. + + + + diff --git a/docs/Xamarin.Forms.Core/Xamarin.Forms.PlatformConfiguration.iOSSpecific/NavigationPage.xml b/docs/Xamarin.Forms.Core/Xamarin.Forms.PlatformConfiguration.iOSSpecific/NavigationPage.xml index c9464e72d01..c219fadfe49 100644 --- a/docs/Xamarin.Forms.Core/Xamarin.Forms.PlatformConfiguration.iOSSpecific/NavigationPage.xml +++ b/docs/Xamarin.Forms.Core/Xamarin.Forms.PlatformConfiguration.iOSSpecific/NavigationPage.xml @@ -74,6 +74,26 @@ To be added. + + + + Method + + 2.0.0.0 + + + System.Boolean + + + + + + To be added. + To be added. + To be added. + To be added. + + @@ -149,6 +169,41 @@ To be added. + + + + Method + + 2.0.0.0 + + + System.Boolean + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Field + + 2.0.0.0 + + + Xamarin.Forms.BindableProperty + + + To be added. + To be added. + + @@ -192,6 +247,49 @@ To be added. + + + + Method + + 2.0.0.0 + + + System.Void + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 2.0.0.0 + + + Xamarin.Forms.IPlatformElementConfiguration<Xamarin.Forms.PlatformConfiguration.iOS,Xamarin.Forms.NavigationPage> + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + diff --git a/docs/Xamarin.Forms.Core/Xamarin.Forms.PlatformConfiguration.iOSSpecific/Page.xml b/docs/Xamarin.Forms.Core/Xamarin.Forms.PlatformConfiguration.iOSSpecific/Page.xml index a2280967ac0..5eae73b3f11 100644 --- a/docs/Xamarin.Forms.Core/Xamarin.Forms.PlatformConfiguration.iOSSpecific/Page.xml +++ b/docs/Xamarin.Forms.Core/Xamarin.Forms.PlatformConfiguration.iOSSpecific/Page.xml @@ -14,6 +14,26 @@ To be added. + + + + Method + + 2.0.0.0 + + + Xamarin.Forms.PlatformConfiguration.iOSSpecific.LargeTitleDisplayMode + + + + + + To be added. + To be added. + To be added. + To be added. + + @@ -54,6 +74,81 @@ To be added. + + + + Method + + 2.0.0.0 + + + Xamarin.Forms.Thickness + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 2.0.0.0 + + + System.Boolean + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 2.0.0.0 + + + Xamarin.Forms.PlatformConfiguration.iOSSpecific.LargeTitleDisplayMode + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Field + + 2.0.0.0 + + + Xamarin.Forms.BindableProperty + + + To be added. + To be added. + + @@ -124,6 +219,84 @@ To be added. + + + + Method + + 2.0.0.0 + + + Xamarin.Forms.Thickness + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Field + + 2.0.0.0 + + + Xamarin.Forms.BindableProperty + + + To be added. + To be added. + + + + + + Method + + 2.0.0.0 + + + System.Void + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 2.0.0.0 + + + Xamarin.Forms.IPlatformElementConfiguration<Xamarin.Forms.PlatformConfiguration.iOS,Xamarin.Forms.Page> + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + @@ -210,5 +383,105 @@ To be added. + + + + Method + + 2.0.0.0 + + + Xamarin.Forms.IPlatformElementConfiguration<Xamarin.Forms.PlatformConfiguration.iOS,Xamarin.Forms.Page> + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 2.0.0.0 + + + System.Void + + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Method + + 2.0.0.0 + + + Xamarin.Forms.IPlatformElementConfiguration<Xamarin.Forms.PlatformConfiguration.iOS,Xamarin.Forms.Page> + + + + + + + To be added. + To be added. + To be added. + To be added. + To be added. + + + + + + Field + + 2.0.0.0 + + + Xamarin.Forms.BindableProperty + + + To be added. + To be added. + + + + + + Method + + 2.0.0.0 + + + System.Boolean + + + + + + To be added. + To be added. + To be added. + To be added. + + diff --git a/docs/Xamarin.Forms.Core/index.xml b/docs/Xamarin.Forms.Core/index.xml index 1b13e335fa4..499199e0e5a 100644 --- a/docs/Xamarin.Forms.Core/index.xml +++ b/docs/Xamarin.Forms.Core/index.xml @@ -510,6 +510,7 @@ + @@ -2109,6 +2110,27 @@ + + + + + + + + ExtensionMethod + + System.Boolean + + + + + + To be added. + To be added. + + + + @@ -2132,6 +2154,29 @@ + + + + + + + + ExtensionMethod + + Xamarin.Forms.IPlatformElementConfiguration<Xamarin.Forms.PlatformConfiguration.iOS,Xamarin.Forms.NavigationPage> + + + + + + + To be added. + To be added. + To be added. + + + + @@ -2155,6 +2200,27 @@ + + + + + + + + ExtensionMethod + + Xamarin.Forms.PlatformConfiguration.iOSSpecific.LargeTitleDisplayMode + + + + + + To be added. + To be added. + + + + @@ -2197,6 +2263,50 @@ + + + + + + + + ExtensionMethod + + Xamarin.Forms.Thickness + + + + + + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + Xamarin.Forms.IPlatformElementConfiguration<Xamarin.Forms.PlatformConfiguration.iOS,Xamarin.Forms.Page> + + + + + + + To be added. + To be added. + To be added. + + + + @@ -2243,6 +2353,73 @@ + + + + + + + + ExtensionMethod + + Xamarin.Forms.IPlatformElementConfiguration<Xamarin.Forms.PlatformConfiguration.iOS,Xamarin.Forms.Page> + + + + + + + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + Xamarin.Forms.IPlatformElementConfiguration<Xamarin.Forms.PlatformConfiguration.iOS,Xamarin.Forms.Page> + + + + + + + To be added. + To be added. + To be added. + + + + + + + + + + + + ExtensionMethod + + System.Boolean + + + + + + To be added. + To be added. + + + +