Skip to content

Commit 74888ce

Browse files
committed
Add support for general layout guides
Includes extensions for ReadableContentGuide and LayoutMarginsGuide improve consistency
1 parent 8c3afc5 commit 74888ce

File tree

8 files changed

+207
-7
lines changed

8 files changed

+207
-7
lines changed

Cirrious.FluentLayout/AdvancedFluentLayoutExtensions.cs

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,35 +20,87 @@ public static class AdvancedFluentLayoutExtensions
2020

2121
public static FluentLayout AtTopOf(this UIView view, UIView parentView, nfloat? margin = null) =>
2222
view.Top().EqualTo().TopOf(parentView).Plus(margin.GetValueOrDefault(DefaultMargin));
23+
24+
public static FluentLayout AtTopOfLayoutGuide(this UIView view, UILayoutGuide layoutGuide, nfloat? margin = null) =>
25+
view.Top().EqualTo().TopOf(layoutGuide).Plus(margin.GetValueOrDefault(DefaultMargin));
2326

2427
public static FluentLayout AtTopOfSafeArea(this UIView view, UIView parentView, nfloat? margin = null) =>
2528
UIDevice.CurrentDevice.CheckSystemVersion(11, 0)
26-
? view.Top().EqualTo().TopOf(parentView.SafeAreaLayoutGuide).Plus(margin.GetValueOrDefault(DefaultMargin))
27-
: view.AtTopOf(parentView, margin);
29+
? view.AtTopOfLayoutGuide(parentView.SafeAreaLayoutGuide, margin)
30+
: view.AtTopOf(parentView, margin);
31+
32+
public static FluentLayout AtTopOfMargins(this UIView view, UIView parentView, nfloat? margin = null) =>
33+
UIDevice.CurrentDevice.CheckSystemVersion(9, 0)
34+
? view.AtTopOfLayoutGuide(parentView.LayoutMarginsGuide, margin)
35+
: view.AtTopOf(parentView, margin);
36+
37+
public static FluentLayout AtTopOfReadableContent(this UIView view, UIView parentView, nfloat? margin = null) =>
38+
UIDevice.CurrentDevice.CheckSystemVersion(9, 0)
39+
? view.AtTopOfLayoutGuide(parentView.ReadableContentGuide, margin)
40+
: view.AtTopOf(parentView, margin);
2841

2942
public static FluentLayout AtLeftOf(this UIView view, UIView parentView, nfloat? margin = null) =>
3043
view.Left().EqualTo().LeftOf(parentView).Plus(margin.GetValueOrDefault(DefaultMargin));
44+
45+
public static FluentLayout AtLeftOfLayoutGuide(this UIView view, UILayoutGuide layoutGuide, nfloat? margin = null) =>
46+
view.Left().EqualTo().LeftOf(layoutGuide).Plus(margin.GetValueOrDefault(DefaultMargin));
3147

3248
public static FluentLayout AtLeftOfSafeArea(this UIView view, UIView parentView, nfloat? margin = null) =>
3349
UIDevice.CurrentDevice.CheckSystemVersion(11, 0)
34-
? view.Left().EqualTo().LeftOf(parentView.SafeAreaLayoutGuide).Plus(margin.GetValueOrDefault(DefaultMargin))
50+
? view.AtLeftOfLayoutGuide(parentView.SafeAreaLayoutGuide, margin)
3551
: view.AtLeftOf(parentView, margin);
52+
53+
public static FluentLayout AtLeftOfMargins(this UIView view, UIView parentView, nfloat? margin = null) =>
54+
UIDevice.CurrentDevice.CheckSystemVersion(11, 0)
55+
? AtLeftOfLayoutGuide(view, parentView.LayoutMarginsGuide, margin)
56+
: view.AtLeftOf(parentView, margin);
57+
58+
public static FluentLayout AtLeftOfReadableContent(this UIView view, UIView parentView, nfloat? margin = null) =>
59+
UIDevice.CurrentDevice.CheckSystemVersion(9, 0)
60+
? view.AtLeftOfLayoutGuide(parentView.ReadableContentGuide, margin)
61+
: view.AtLeftOf(parentView, margin);
3662

3763
public static FluentLayout AtRightOf(this UIView view, UIView parentView, nfloat? margin = null) =>
3864
view.Right().EqualTo().RightOf(parentView).Minus(margin.GetValueOrDefault(DefaultMargin));
65+
66+
public static FluentLayout AtRightOfLayoutGuide(this UIView view, UILayoutGuide layoutGuide, nfloat? margin = null) =>
67+
view.Right().EqualTo().RightOf(layoutGuide).Plus(margin.GetValueOrDefault(DefaultMargin));
3968

4069
public static FluentLayout AtRightOfSafeArea(this UIView view, UIView parentView, nfloat? margin = null) =>
4170
UIDevice.CurrentDevice.CheckSystemVersion(11, 0)
42-
? view.Right().EqualTo().RightOf(parentView.SafeAreaLayoutGuide).Minus(margin.GetValueOrDefault(DefaultMargin))
71+
? view.AtRightOfLayoutGuide(parentView.SafeAreaLayoutGuide, margin)
4372
: view.AtRightOf(parentView, margin);
73+
74+
public static FluentLayout AtRightOfMargins(this UIView view, UIView parentView, nfloat? margin = null) =>
75+
UIDevice.CurrentDevice.CheckSystemVersion(11, 0)
76+
? view.AtRightOfLayoutGuide(parentView.LayoutMarginsGuide, margin)
77+
: view.AtRightOf(parentView, margin);
78+
79+
public static FluentLayout AtRightOfReadableContent(this UIView view, UIView parentView, nfloat? margin = null) =>
80+
UIDevice.CurrentDevice.CheckSystemVersion(9, 0)
81+
? view.AtRightOfLayoutGuide(parentView.ReadableContentGuide, margin)
82+
: view.AtRightOf(parentView, margin);
4483

4584
public static FluentLayout AtBottomOf(this UIView view, UIView parentView, nfloat? margin = null) =>
4685
view.Bottom().EqualTo().BottomOf(parentView).Minus(margin.GetValueOrDefault(DefaultMargin));
86+
87+
public static FluentLayout AtBottomOfLayoutGuide(this UIView view, UILayoutGuide layoutGuide, nfloat? margin = null) =>
88+
view.Bottom().EqualTo().BottomOf(layoutGuide).Plus(margin.GetValueOrDefault(DefaultMargin));
4789

4890
public static FluentLayout AtBottomOfSafeArea(this UIView view, UIView parentView, nfloat? margin = null) =>
4991
UIDevice.CurrentDevice.CheckSystemVersion(11, 0)
50-
? view.Bottom().EqualTo().BottomOf(parentView.SafeAreaLayoutGuide).Minus(margin.GetValueOrDefault(DefaultMargin))
92+
? view.AtBottomOfLayoutGuide(parentView.SafeAreaLayoutGuide, margin)
5193
: view.AtBottomOf(parentView, margin);
94+
95+
public static FluentLayout AtBottomOfMargins(this UIView view, UIView parentView, nfloat? margin = null) =>
96+
UIDevice.CurrentDevice.CheckSystemVersion(11, 0)
97+
? view.AtBottomOfLayoutGuide(parentView.LayoutMarginsGuide, margin)
98+
: view.AtBottomOf(parentView, margin);
99+
100+
public static FluentLayout AtBottomOfReadableContent(this UIView view, UIView parentView, nfloat? margin = null) =>
101+
UIDevice.CurrentDevice.CheckSystemVersion(9, 0)
102+
? view.AtBottomOfLayoutGuide(parentView.ReadableContentGuide, margin)
103+
: view.AtBottomOf(parentView, margin);
52104

53105
public static FluentLayout AtLeadingOf(this UIView view, UIView parentView, nfloat? margin = null) =>
54106
view.Leading().EqualTo().LeadingOf(parentView).Plus(margin.GetValueOrDefault(DefaultMargin));

QuickLayout.Core/ViewModels/FirstViewModel.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using MvvmCross.Logging;
1+
using MvvmCross.Logging;
22
using MvvmCross.Navigation;
33
using MvvmCross.ViewModels;
44

@@ -35,5 +35,9 @@ public FirstViewModel(IMvxLogProvider logProvider, IMvxNavigationService navigat
3535
public void GoViewWithSafeArea() => NavigationService.Navigate<ViewWithSafeAreaViewModel>();
3636

3737
public void GoCenterConstraints() => NavigationService.Navigate<ToCenterConstraintsViewModel>();
38+
39+
public void GoViewWithReadableContentGuide() => NavigationService.Navigate<ViewWithReadableContentGuideViewModel>();
40+
41+
public void GoViewWithMarginsGuide() => NavigationService.Navigate<ViewWithMarginsGuideViewModel>();
3842
}
3943
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using MvvmCross.ViewModels;
2+
3+
namespace QuickLayout.Core.ViewModels
4+
{
5+
6+
public class ViewWithMarginsGuideViewModel
7+
: MvxViewModel
8+
{
9+
}
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using MvvmCross.ViewModels;
2+
3+
namespace QuickLayout.Core.ViewModels
4+
{
5+
6+
public class ViewWithReadableContentGuideViewModel
7+
: MvxViewModel
8+
{
9+
}
10+
}

QuickLayout.Touch/QuickLayout.Touch.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@
102102
<Compile Include="Views\AdvancedVerticalStackView.cs" />
103103
<Compile Include="Views\DirectionFormView.cs" />
104104
<Compile Include="Views\RightToLeftView.cs" />
105+
<Compile Include="Views\ViewWithMarginsGuideView.cs" />
106+
<Compile Include="Views\ViewWithReadableContentGuideView.cs" />
105107
<Compile Include="Views\ViewWithSafeAreaView.cs" />
106108
</ItemGroup>
107109
<ItemGroup>

QuickLayout.Touch/Views/FirstView.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace QuickLayout.Touch.Views
1313
[MvxRootPresentation(WrapInNavigationController = true)]
1414
public class FirstView : MvxViewController
1515
{
16-
private UIButton _viewForm, _viewFormGrid, _viewDetails, _viewSearch, _viewTip, _viewUpdateConstaints, _viewAdvancedVerticalStack, _fullSize, _directionFormView, _rightToLeft, _viewSafeArea, _viewCenterConstraints;
16+
private UIButton _viewForm, _viewFormGrid, _viewDetails, _viewSearch, _viewTip, _viewUpdateConstaints, _viewAdvancedVerticalStack, _fullSize, _directionFormView, _rightToLeft, _viewSafeArea, _viewCenterConstraints, _viewReadableContentGuide, _viewMarginsGuide;
1717

1818
public override void ViewDidLoad()
1919
{
@@ -71,6 +71,14 @@ public override void ViewDidLoad()
7171
_viewCenterConstraints = new UIButton(UIButtonType.RoundedRect);
7272
_viewCenterConstraints.SetTitle("View Contraining to centers", UIControlState.Normal);
7373
Add(_viewCenterConstraints);
74+
75+
_viewReadableContentGuide = new UIButton(UIButtonType.RoundedRect);
76+
_viewReadableContentGuide.SetTitle("View with Readable Content Guide", UIControlState.Normal);
77+
Add(_viewReadableContentGuide);
78+
79+
_viewMarginsGuide = new UIButton(UIButtonType.RoundedRect);
80+
_viewMarginsGuide.SetTitle("View with Margins Guide", UIControlState.Normal);
81+
Add(_viewMarginsGuide);
7482

7583
View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
7684

@@ -87,6 +95,8 @@ public override void ViewDidLoad()
8795
set.Bind(_rightToLeft).To("GoRightToLeft");
8896
set.Bind(_viewSafeArea).To("GoViewWithSafeArea");
8997
set.Bind(_viewCenterConstraints).To("GoCenterConstraints");
98+
set.Bind(_viewReadableContentGuide).To("GoViewWithReadableContentGuide");
99+
set.Bind(_viewMarginsGuide).To("GoViewWithMarginsGuide");
90100
set.Apply();
91101

92102
var constraints = View.VerticalStackPanelConstraints(
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using Cirrious.FluentLayouts.Touch;
2+
using Foundation;
3+
using MvvmCross.Platforms.Ios.Views;
4+
using UIKit;
5+
6+
namespace QuickLayout.Touch.Views
7+
{
8+
[Register("ViewWithMarginsGuideView")]
9+
public class ViewWithMarginsGuideView : MvxViewController
10+
{
11+
public override void ViewDidLoad()
12+
{
13+
base.ViewDidLoad();
14+
15+
View.BackgroundColor = UIColor.FromRGB(248, 191, 120);
16+
17+
var viewContainer = new UIView {BackgroundColor = UIColor.Clear};
18+
19+
var sampleText = new UITextView
20+
{
21+
Editable = false,
22+
Selectable = false,
23+
Text =
24+
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam aliquet massa eu tempus semper. Nulla elementum mi quis erat blandit eleifend. Quisque dictum, sem eget volutpat scelerisque, quam orci lobortis enim, ut luctus enim massa in nisi. Mauris sed mi id leo lacinia lobortis. Integer elementum, erat gravida vestibulum rhoncus, enim velit consectetur est, dignissim condimentum urna turpis ac ex. Nulla arcu mauris, hendrerit nec tortor in, feugiat ullamcorper mauris. Aliquam eget tempus eros. Curabitur suscipit, arcu eu luctus mollis, nunc erat ornare erat, id viverra nisl ligula sit amet ex. Etiam in quam vitae est convallis eleifend. Fusce gravida arcu in orci lobortis pulvinar. Morbi tortor mi, elementum nec purus quis, eleifend imperdiet mi. Nunc commodo et sem vitae finibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc nec erat eget orci malesuada vulputate. \n \nPhasellus vulputate dolor eu massa varius efficitur. Sed sed tortor eu elit ornare mollis id non sapien. Nam at turpis volutpat ligula aliquam aliquet placerat sed purus. Phasellus magna urna, maximus vitae erat et, malesuada tincidunt velit. Mauris efficitur velit fermentum imperdiet convallis. In eget erat nisi. Curabitur ut leo sodales, consectetur lorem ut, iaculis est. Nullam ornare, justo id condimentum pharetra, enim nisl posuere ex, a fermentum justo enim sit amet dolor. Sed suscipit sapien augue, nec dignissim nisl laoreet eu. Maecenas eros enim, aliquet vitae arcu id, fermentum dignissim lorem. Etiam sit amet commodo nunc. In vitae ullamcorper velit. Integer in mauris eget erat mattis feugiat at id neque.",
25+
TextColor = UIColor.Black,
26+
BackgroundColor = UIColor.Clear
27+
};
28+
sampleText.TextContainer.LineBreakMode = UILineBreakMode.WordWrap;
29+
sampleText.Font = UIFont.BoldSystemFontOfSize(18f);
30+
31+
View.AddSubview(viewContainer);
32+
viewContainer.AddSubview(sampleText);
33+
34+
View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
35+
viewContainer.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
36+
37+
View.AddConstraints(
38+
viewContainer.AtLeftOf(View),
39+
viewContainer.AtTopOf(View),
40+
viewContainer.AtRightOf(View),
41+
viewContainer.AtBottomOf(View)
42+
);
43+
44+
viewContainer.AddConstraints(
45+
sampleText.AtTopOfMargins(viewContainer),
46+
// sampleText.AtTopOfSafeArea(viewContainer), -> use this when UINavigationBar not present to avoid content overlap under iPhone X notch
47+
sampleText.AtLeftOfMargins(viewContainer),
48+
//sampleText.AtLeftOf(viewContainer), -> if this is used, content overlaps under notch on landscape
49+
sampleText.AtRightOfMargins(viewContainer),
50+
//sampleText.AtRightOf(viewContainer), -> if this is used, content overlaps under notch on landscape
51+
sampleText.AtBottomOfMargins(viewContainer)
52+
//sampleText.AtBottomOf(viewContainer) -> if this is used, content overlaps under notch on landscape
53+
);
54+
}
55+
}
56+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using Cirrious.FluentLayouts.Touch;
2+
using Foundation;
3+
using MvvmCross.Platforms.Ios.Views;
4+
using UIKit;
5+
6+
namespace QuickLayout.Touch.Views
7+
{
8+
[Register("ViewWithReadableContentGuideView")]
9+
public class ViewWithReadableContentGuideView : MvxViewController
10+
{
11+
public override void ViewDidLoad()
12+
{
13+
base.ViewDidLoad();
14+
15+
View.BackgroundColor = UIColor.FromRGB(248, 191, 120);
16+
17+
var viewContainer = new UIView {BackgroundColor = UIColor.Clear};
18+
19+
var sampleText = new UITextView
20+
{
21+
Editable = false,
22+
Selectable = false,
23+
Text =
24+
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam aliquet massa eu tempus semper. Nulla elementum mi quis erat blandit eleifend. Quisque dictum, sem eget volutpat scelerisque, quam orci lobortis enim, ut luctus enim massa in nisi. Mauris sed mi id leo lacinia lobortis. Integer elementum, erat gravida vestibulum rhoncus, enim velit consectetur est, dignissim condimentum urna turpis ac ex. Nulla arcu mauris, hendrerit nec tortor in, feugiat ullamcorper mauris. Aliquam eget tempus eros. Curabitur suscipit, arcu eu luctus mollis, nunc erat ornare erat, id viverra nisl ligula sit amet ex. Etiam in quam vitae est convallis eleifend. Fusce gravida arcu in orci lobortis pulvinar. Morbi tortor mi, elementum nec purus quis, eleifend imperdiet mi. Nunc commodo et sem vitae finibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc nec erat eget orci malesuada vulputate. \n \nPhasellus vulputate dolor eu massa varius efficitur. Sed sed tortor eu elit ornare mollis id non sapien. Nam at turpis volutpat ligula aliquam aliquet placerat sed purus. Phasellus magna urna, maximus vitae erat et, malesuada tincidunt velit. Mauris efficitur velit fermentum imperdiet convallis. In eget erat nisi. Curabitur ut leo sodales, consectetur lorem ut, iaculis est. Nullam ornare, justo id condimentum pharetra, enim nisl posuere ex, a fermentum justo enim sit amet dolor. Sed suscipit sapien augue, nec dignissim nisl laoreet eu. Maecenas eros enim, aliquet vitae arcu id, fermentum dignissim lorem. Etiam sit amet commodo nunc. In vitae ullamcorper velit. Integer in mauris eget erat mattis feugiat at id neque.",
25+
TextColor = UIColor.Black,
26+
BackgroundColor = UIColor.Clear
27+
};
28+
sampleText.TextContainer.LineBreakMode = UILineBreakMode.WordWrap;
29+
sampleText.Font = UIFont.BoldSystemFontOfSize(18f);
30+
31+
View.AddSubview(viewContainer);
32+
viewContainer.AddSubview(sampleText);
33+
34+
View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
35+
viewContainer.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
36+
37+
View.AddConstraints(
38+
viewContainer.AtLeftOf(View),
39+
viewContainer.AtTopOf(View),
40+
viewContainer.AtRightOf(View),
41+
viewContainer.AtBottomOf(View)
42+
);
43+
44+
viewContainer.AddConstraints(
45+
sampleText.AtTopOfReadableContent(viewContainer),
46+
// sampleText.AtTopOfSafeArea(viewContainer), -> use this when UINavigationBar not present to avoid content overlap under iPhone X notch
47+
sampleText.AtLeftOfReadableContent(viewContainer),
48+
//sampleText.AtLeftOf(viewContainer), -> if this is used, content overlaps under notch on landscape
49+
sampleText.AtRightOfReadableContent(viewContainer),
50+
//sampleText.AtRightOf(viewContainer), -> if this is used, content overlaps under notch on landscape
51+
sampleText.AtBottomOfSafeArea(viewContainer)
52+
//sampleText.AtBottomOf(viewContainer) -> if this is used, content overlaps under notch on landscape
53+
);
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)