fluentlayout / cirrious.fluentlayout Goto Github PK
View Code? Open in Web Editor NEWFluentLayout for Xamarin.iOS - sample uses MvvmCross
License: Microsoft Public License
FluentLayout for Xamarin.iOS - sample uses MvvmCross
License: Microsoft Public License
Hi,
I really like this implementation of a layouting framework.
However, I have have a problem to show a UIWebView inline with other controls. Is there a recommended way to go when I have a UIWebView that should be viewed inline with some Labels?
Regards,
Marcel
Is there a way to use the new View.SafeAreaLayoutGuide
with FluentLayout?
I poked around last night trying to make View.SafeAreaLayoutGuide
fit into FluentLayout, but didn't have much luck. Everything else works great in iOS 11 and the iPhone X, except if I do something like:
scrollView.AtLeftOf(View),
scrollView.Width().EqualTo().WidthOf(View),
When I rotate the phone the notch will eat my scrollView
.
This has been on my "todo" list for soooo long and I havent gotten around to it...
One key problem (IMHO) with FluentLayout is that AddConstraints
doesn't return anything.
I would love AddConstraints
to return something.
At a simple level, it could return IEnumerable<NSLayoutConstraint>
just like ToLayoutConstraints
currently does....
At a more advanced level, both AddConstraints
and ToLayoutConstraints
could instead return some new fluent wrapper of the created constraint. If we did this, then it could then be easier for users to remove the created constraints or to adjust/animate them (there's lots of info out there on animating constraints - e.g. http://stackoverflow.com/a/16662187/373321)
I've not thought (let alone worked) this through fully, but if the returned "constraint wrapper" shared an interface with the original "constraint creator" (or maybe they are even the same class?) then some of the extension methods could be shared between them...
Back to SQL here...
Could you add this method ?
It extends the existing method to accept both FuentLayout
and IEnumerable<FluentLayout>
Usage:
View.AddConstraints(
back.WithSameRectOf(View),
topBack.WithSameTop(okButton).Minus(5),
topBack.AtLeftRightOf(View),
topBack.Bottom().EqualTo().TopOf(picker),
actionButton.Height().EqualTo(70),
actionButton.AtLeftRightOf(View),
actionButton.AtBottomOf(View)
);
Example:
public static IEnumerable<FluentLayout> WidthEqualHeight(this UIView view, UIView previous=null)
{
yield return view.Width().EqualTo().HeightOf(previous ?? view);
}
Source
/// <summary>
/// </summary>
/// <param name="view"></param>
/// <param name="fluentLayouts">Either FluentLayout or IEnumerable<FluentLayout></param>
public static void AddConstraints(this UIView view, params object[] fluentLayouts)
{
view.AddConstraints((fluentLayouts
.Where(fluent => fluent != null)
.OfType<FluentLayout>()
.SelectMany(fluent => fluent.ToLayoutConstraints())
).Concat(fluentLayouts
.OfType<IEnumerable<FluentLayout>>()
.SelectMany(fluent => fluent.SelectMany(fluent2 => fluent2.ToLayoutConstraints()))
).ToArray());
}
Other examples:
public static IEnumerable<FluentLayout> WithSameRectOf(this UIView view, UIView parent, nfloat? margin = null)
{
return
view.FullWidthOf(parent, margin)
.Concat(view.FullHeightOf(parent, margin))
.Concat(view.AtTopLeftOf(parent, margin));
}
public static IEnumerable<FluentLayout> AtTopLeftOf(this UIView view, UIView parentView, nfloat? margin = null)
{
var marg = margin.GetValueOrDefault(DefaultMargin);
yield return view.Top().EqualTo().TopOf(parentView).Plus(marg);
yield return view.Left().EqualTo().LeftOf(parentView).Plus(marg);
}
public static IEnumerable<FluentLayout> AtTopRightOf(this UIView view, UIView parentView, nfloat? margin = null)
{
var marg = margin.GetValueOrDefault(DefaultMargin);
yield return view.Top().EqualTo().TopOf(parentView).Plus(marg);
yield return view.Right().EqualTo().RightOf(parentView).Minus(marg);
}
public static IEnumerable<FluentLayout> AtLeftRightOf(this UIView view, UIView parentView, nfloat? margin = null)
{
var marg = margin.GetValueOrDefault(DefaultMargin);
yield return view.Left().EqualTo().LeftOf(parentView).Plus(marg);
yield return view.Right().EqualTo().RightOf(parentView).Minus(marg);
}
public static IEnumerable<FluentLayout> AtTopLeftRightOf(this UIView view, UIView parentView, nfloat? margin = null)
{
var marg = margin.GetValueOrDefault(DefaultMargin);
yield return view.Top().EqualTo().TopOf(parentView).Plus(marg);
yield return view.Left().EqualTo().LeftOf(parentView).Plus(marg);
yield return view.Right().EqualTo().RightOf(parentView).Minus(marg);
}
public static IEnumerable<FluentLayout> BelowAtLeftRightOf(this UIView view, UIView belowView, UIView parentView, nfloat? belowMargin = null, nfloat? margin = null)
{
var marg = margin.GetValueOrDefault(DefaultMargin);
yield return view.Top().EqualTo().BottomOf(belowView).Plus(belowMargin.GetValueOrDefault(DefaultMargin));
yield return view.Left().EqualTo().LeftOf(parentView).Plus(marg);
yield return view.Right().EqualTo().RightOf(parentView).Minus(marg);
}
public static IEnumerable<FluentLayout> EqualRectOf(this UIView view, UIView parentView, nfloat? margin = null)
{
var marg = margin.GetValueOrDefault(DefaultMargin);
yield return view.Top().EqualTo().TopOf(parentView).Plus(marg);
yield return view.Left().EqualTo().LeftOf(parentView).Plus(marg);
yield return view.Right().EqualTo().RightOf(parentView).Minus(marg);
yield return view.Bottom().EqualTo().BottomOf(parentView).Minus(marg);
}
public static IEnumerable<FluentLayout> WithSameCenter(this UIView view, UIView previous)
{
yield return view.WithSameCenterX(previous);
yield return view.WithSameCenterY(previous);
}
I really like FluentLayout, I now create constraint only with him. But I seen that the aspect ration is not included. Is there a reason or I miss it?
The constraints that are returned cause my content inside of the parent to no longer be visible.
Sorry) My bad. Small sample is here -
https://github.com/bondarenkod/xam-ios-fluent-layout-test/blob/master/TableTest/TableTest/RuntimeCell.cs
"All code must be recompiled to support .NET 6. Existing assemblies (such as NuGets built for the old TargetFrameworkIdentifier xamarinios10) won’t work and won’t be supported. Non-xamarin specific assets for net4.x, netstandard, netcoreapp, net5.0+, etc. will work fine however." - Link
I have had some issues recently with AutoLayout of cells with variable height in Tables. The issues are outlined in this SO question, https://stackoverflow.com/questions/30099363/uilabel-not-wrapping-in-uitableview-until-device-rotate-ios8
One of my key takeaways from this was ensuring that i gave AutoLayout enough information to do its job of saying how tall each cell should be. The info that I was forgetting was telling the bottom row of UI to hug or "dock" to the BottomOf the container. You can see the changes made by SharpMobileCode to my GitHub Repro https://github.com/munkii/TableCellResizeIssue/blob/c54a21f322b6ede26dd92346fab4364c1a29b1da/TableCellResizeIssue/Controls/CustomCells/CustomerItemCell.cs
I am currently working with a custom control that vertically stacks a variable number of Labels based on binding to a List of strings. If use FluentLayout's VerticalStackPanelConstraints the labels layout (initially) but overflow into subsequent rows and after scrolling are then clipped.
If I remove the check that the container view is a UIScrollView causing the last item in the "stack" to be constrained to the bottom, always, it works.
I have updated by TableReSizeIssue repro to demonstrate the issue. Check out Lines 90-92, https://github.com/munkii/TableCellResizeIssue/blob/master/TableCellResizeIssue/Controls/StringStackPanel.cs#L90
LayoutManually(), is just me laying out myself
LayoutWithFluent(), is a copy of the code from GitHub but I have edited it to remove the UIScrollView check
There is also a version that just uses VerticalStackPanelConstraints to show what happens as is
Is it possible to setup following constraint in terms of fluent layout:
View.AddConstraint(NSLayoutConstraint.Create(table, NSLayoutAttribute.Top, NSLayoutRelation.Equal, TopLayoutGuide, NSLayoutAttribute.Bottom, 1f, 0f))
?
TopLayoutGuide is of type IUILayoutSupport.
I use ToLayoutConstraints()
in the following manner:
FluentLayout heightFluentLayout = view.Height().EqualTo(100);
NSLayoutConstraint heightConstraint = heightFluentLayout.ToLayoutConstraints().First();
(where view
is some UIView
), and then add this constraint to the parent view. I can now use heightConstraint
to change the height of the view, e.g. as follows:
heightConstraint.Constant = 130;
Now that ToLayoutConstraints()
is destined for obsoletion, is there another way to achieve the above?
Thanks!
It is telling me that it only supports net6.0-ios16.0. Visual Studio only goes up to net6.0-ios15.4. Is there a workaround for this?
With error
Could not install package 'Cirrious.FluentLayout 2.0.0'. You are trying to install this package into a project that targets 'MonoTouch,Version=v1.0', but the package does not contain any assembly references or content files that are compatible with that framework.
My project is not targeting the Unified API (yet) - could that be the reason for the error? If so, what earlier version can I install?
Thanks!
It appears the Active flag doesn't get set inside the CreateConstraint() method inside FluentLayout.
This means, if you create 2 or more competing constraints, set the one you want to active, then call UIView.AddConstraints they will all get set to Active = true and you'll get a bunch of errors about constraints not being satisfied.
You then need to set Active flags after setting UIView.AddConstraints.
Ideally, CreateConstraint() should set the active flag so we can add them in UIVew.AddConstraints and not get any issues or have the state reset.
Hi,
What's iOS supported?
Thanks so much!
Hi, how can we make a square constraint? In other words, a control's or view's width equal to its own height. I don't find any code to make it in the source code.
this code is working fine:
button.AtBottomOf(View).WithMultiplier(0.667f),
but if I change the float to some expression like the following, it will not work:
button.AtBottomOf(View).WithMultiplier((float)(4/6)),
it crashes at runtime with exception:
Received unhandled ObjectiveC exception: NSInvalidArgumentException NSLayoutConstraint for <UIButton: 0x17264840; frame = (0 0; 0 0); opaque = NO; layer = <CALayer: 0x17264660>>: A multiplier of 0 or a nil second item together with a location for the first attribute creates an illegal constraint of a location equal to a constant. Location attributes must be specified in pairs.
For ipad resolutions It would be very practical to be able to specify an scale factor when adding constraints. ie:
View.AddConstraints(2, // <- scale
view1.AtTopOf(View, 30),
view1.AtRightOf(View, 30)
)
That way, 30 would be 30 * 2 = 60
This factor would be applied to all margins.
The use case:
I found myself doing this on every screen:
about.AtTopOf(aboutBackground, 15 * Multiplier),
about.AtBottomOf(aboutBackground, 15 * Multiplier),
about.AtLeftOf(aboutBackground, 15 * Multiplier),
about.AtRightOf(aboutBackground, 15 * Multiplier),
info.AtBottomOf(View, 10 * Multiplier),
info.WithSameWidth(View),
info.Height().EqualTo(15 * Multiplier),
And that´s not very pretty
hi, i am meeting a constraints issue.
var cyan = new UIView { BackgroundColor = UIColor.Cyan };
var red = new UIView { BackgroundColor = UIColor.Red };
View.AddSubviews(cyan, red);
View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
View.AddConstraints(cyan.FullSizeOf(View, 20));
View.AddConstraints(red.FullSizeOf(cyan, new Margins(10, 30)));
above code is working.
for my ios project, i want to set the red view as a subview for cyan view.
so i changed the code to
var cyan = new UIView { BackgroundColor = UIColor.Cyan };
var red = new UIView { BackgroundColor = UIColor.Red };
View.AddSubview(cyan);
cyan.AddSubview(red);
View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
View.AddConstraints(cyan.FullSizeOf(View, 20));
cyan.AddConstraints(red.FullSizeOf(cyan, new Margins(10, 30)));
The constraints are not woking. then i do not see the red view.
Is something wrong for me? Please check this. Thanks!
I added the Nuget package (2.5.0) to my iOS project , but noticed that it hasn't been updated to include ToLeftMargin, ToRightMargin, etc.
Any chance you could add a sample that specifically addresses the use of a UIScrollView that contains a UITextView and how to allow scrolling when the keyboard appears? This would be really helpful. Thanks.
Inspired by Softlion's latest pull - #16 - I've been thinking about optional parameters.
Part of me doesn't really like optional parameters as they don't feel very Fluent....
However, they do help reduce the code size down....
With this in mind, I'm wondering... should Plus
and Minus
take optional parameters?
If they did then we could have:
public FluentLayout Plus(nfloat? constant)
{
if (constant.HasValue)
Constant += constant.Value;
return this;
}
and this would then mean that "advanced" methods could just pass optionals straight through - e.g.:
public static FluentLayout AtTopOf(this UIView view, UIView parentView, nfloat? margin = null)
{
return view.Top().EqualTo().TopOf(parentView).Plus(margin.GetValueOrDefault(DefaultMargin));
}
would become:
public static FluentLayout AtTopOf(this UIView view, UIView parentView, nfloat? margin = null)
{
return view.Top().EqualTo().TopOf(parentView).Plus(margin);
}
This would allow having a much better description when a constraint breaks. Basically ObjC Description method would be replaced by our .NET counterpart.
Note: this should only be done in debug since swizzling can lead to other kind of bugs.
Kent Boogaart did the same in his AutoLayout library:
http://kent-boogaart.com/blog/reducing-auto-layout-friction/
What would you think of such an addition?
I wonder if you are interested in help to integrate Cake and make some improvements/updates to the code.
We have Priority in the fluent interface, but it's not used when creating NSLayoutContraint.
Is there any chance of getting a nuget package for this?
Usually if I want a square which is as high as it is wide I do something like this:
AddConstraint (NSLayoutConstraint.Create (view, NSLayoutAttribute.Height,
NSLayoutRelation.Equal, view, NSLayoutAttribute.Width, 1, 0));
However, I can't seem to see a way to do exactly this with FluentLayout.
I only see methods to replicate another views bounds, with the methods prefixed with WithSame
or WithRelative
. Or you can position the view at top, bottom, left or right of a view. However, there are no expressions to add the constraint above?
This version of AddConstraints permits the use of both simple and advanced constraints in the same call. If you remove ToLayoutConstraints it will not work anymore.
Advanced constraints methods use more than one Constraint object to achieve the result.
public static void AddConstraints(this UIView view, params object[] fluentLayouts)
{
view.AddConstraints((fluentLayouts
.Where(fluent => fluent != null)
.OfType<FluentLayout>()
.SelectMany(fluent => fluent.ToLayoutConstraints())
).Concat(fluentLayouts
.OfType<IEnumerable<FluentLayout>>()
.SelectMany(fluent => fluent.SelectMany(fluent2 => fluent2.ToLayoutConstraints()))
).ToArray());
}
public static IEnumerable<FluentLayout> WithSameRectOf(this UIView view, UIView parent, nfloat? margin = null)
{
return
view.FullWidthOf(parent, margin)
.Concat(view.FullHeightOf(parent, margin))
.Concat(view.AtTopLeftOf(parent, margin));
}
Sample usage:
ContentView.AddConstraints(
title.AtLeftOf(ContentView, 2.5f),
title.AtTopOf(ContentView, ItemSize.Width + 2.5f),
image.WithSameRectOf(imageSvg)
);
Without this extension methods, WithSameRectOf can not be used.
Hi, i am very happy to use this framework to write an ios project. But there is a block for me. I am not clear that how to create a tableview with a variable height tablecell?
Is it possbile that we have a demo code for that? Many thanks!
This is a magnificent project and I'd like to make the macOS implementation of it.
I've seen #49 and I'd like to ask you that if you want I could implement this as a multi target project and add the macOS part. Not sure if @rogerwcpt has already started implementing it but if not I could do it.
Also I can make some previous PRs to update the Mvx packages if you want and nobody else is working on it 😄
Hi, this isn't an issue, more a query and thought this might be the best place to ask.
I'm not really referring to Adaptive layouts, but if adaptive layouts are possible with FluentLayout then is there an example somewhere?
I'm more thinking, is it possible to setup a bunch of contraints for Landscape and a bunch for Portrait and switch between the two on orientation changes? Or is there another way to handle different layout setups for Landscape and Portrait using FluentLayout?
If I have to go the route of AdaptiveLayouts in a xib then fair enough, just trying to avoid and do everything in code with FluentLayout!
Just noticed that FluentLayout.ToLayoutConstraints() is obsolete now.
I often use it like this:
var c = _title.AtBottomOf(_view).ToLayoutConstraints().First();
c.Active = false;
//something happened and I need update constrains
c.Active = true;
Propose to and "Active" property to FluentLayout if you want make resulting constraint private.
So I will be able to keep reference to FluentLayout instead of NSConstraint and update Active value when needed.
That is common technique I use to implement collapse/expand cases, or hide single view inside large hierarchy if there is nothing to display in this view (making couple of constraints active/inactive is good alternative for removing all and reacreating whole set of constraints again).
I downloaded and built the sample just to experience the following result on an iPhone6 device:
What is going on here?
=== Visual Studio Community 2019 for Mac (Preview) ===
Version 8.5 Preview (8.5 build 3152)
Installation UUID: a0a93683-c1fc-4d6c-ba00-0c39219f47dd
GTK+ 2.24.23 (Raleigh theme)
Xamarin.Mac 6.14.1.39 (d16-5 / 30e8706b4)
Package version: 608000121
=== Mono Framework MDK ===
Runtime:
Mono 6.8.0.121 (2019-10/fb4d8f5eb1c) (64-bit)
Package version: 608000121
=== Roslyn (Language Service) ===
3.5.0-beta4-20125-04+1baa0b3063238ed752ad1f0368b1df6b6901373e
=== NuGet ===
Version: 5.4.0.6315
=== .NET Core SDK ===
SDK: /usr/local/share/dotnet/sdk/3.1.102/Sdks
SDK Versions:
3.1.102
3.1.100
3.1.100-preview3-014645
3.1.100-preview2-014569
3.0.100
3.0.100-rc1-014190
3.0.100-preview9-014004
3.0.100-preview8-013656
2.1.701
MSBuild SDKs: /Library/Frameworks/Mono.framework/Versions/6.8.0/lib/mono/msbuild/Current/bin/Sdks
=== .NET Core Runtime ===
Runtime: /usr/local/share/dotnet/dotnet
Runtime Versions:
3.1.2
3.1.0
3.1.0-preview3.19553.2
3.1.0-preview2.19525.6
3.0.0
3.0.0-rc1-19456-20
3.0.0-preview9-19423-09
2.1.14
2.1.13
2.1.12
=== Xamarin.Profiler ===
Version: 1.6.12.29
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler
=== Updater ===
Version: 11
=== Apple Developer Tools ===
Xcode 11.3 (15710)
Build 11C24b
=== Xamarin.iOS ===
Version: 13.14.1.39 (Visual Studio Community)
Hash: 30e8706b4
Branch: d16-5
Build date: 2020-02-20 16:41:48-0500
=== Xamarin Designer ===
Version: 16.5.0.471
Hash: 35aa4889d
Branch: remotes/origin/d16-5
Build date: 2020-02-25 01:52:08 UTC
=== Xamarin Inspector ===
Version: 1.4.3
Hash: db27525
Branch: 1.4-release
Build date: Mon, 09 Jul 2018 21:20:18 GMT
Client compatibility: 1
=== Build Information ===
Release ID: 805003152
Git revision: 6d4e2cce7b323bc2a7b4990b7bae09aa0d3a23b8
Build date: 2020-03-06 06:28:27-05
Build branch: release-8.5
Xamarin extensions: 6d4e2cce7b323bc2a7b4990b7bae09aa0d3a23b8
=== Operating System ===
Mac OS X 10.15.4
Darwin 19.4.0 Darwin Kernel Version 19.4.0
Tue Mar 3 02:26:52 PST 2020
root:xnu-6153.101.6~8/RELEASE_X86_64 x86_64
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.