FluentLayout / Cirrious.FluentLayout

FluentLayout for Xamarin.iOS - sample uses MvvmCross
Microsoft Public License
149 stars 54 forks source link

Return `fluent constraint wrappers` from AddConstraints #18

Closed slodge closed 8 years ago

slodge commented 9 years ago

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...

xleon commented 8 years ago

This would be very handy. I actually need this to animate constraints as all my UI is built with your library. I¨m currently using this awful code:

_monsterOffLayoutAbove = _monsterOff.Above(ground);
View.AddConstraints(
    _monsterOffLayoutAbove,
    ...
);
var layout = _monsterOffLayoutAbove;
                var constraintToAnimate = View.Constraints
                    .FirstOrDefault(x => x.FirstItem.Equals(_monsterOff)
                    && x.Relation.Equals(layout.Relation)
                    && x.SecondItem.Equals(layout.SecondItem)
                    && x.FirstAttribute.Equals(layout.Attribute)
                    && x.SecondAttribute.Equals(layout.SecondAttribute));

                constraintToAnimate.Constant = 200;
                UIView.Animate(0.2, 0.0, UIViewAnimationOptions.CurveEaseIn, () =>
                {
                    View.LayoutIfNeeded();
                }, () => Mvx.Trace("completion"));

The perfect scenario would be something as follows:

_monsterOffLayoutAbove.NSConstraint.Constant = 200;
xleon commented 8 years ago

Another handy method instead of my previous suggestion would be to add a "name" property to the FluentLayout object, so you could do view.Name("monster_above").Above(ground); And afterwards you could get the NSConstraints with an extension method like View.GetConstraintsByName("monster_above")

alexsorokoletov commented 8 years ago

@slodge @gshackles is it this issue still valid after changes related to #23? There is now a way to update constraints by updating FluentLayout objects itself, but how does that work with animating?

xleon commented 8 years ago

Given the purpose of it:

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

I would say this issue can be closed. With the latest update (2.5) you can access and modify constraints through FluentLayout properties.

To animate constraints through FluentLayout the only thing you need is to modify its constant. ie:

_fluentLayout = thing.AtBottomOf(View, -500); // save a reference to the layout
View.AddConstraints(_fluentLayout, otherLayouts...);

// animate
_fluentLayout.Constant = 500;
UIView.Animate(duration, 0.0f, UIViewAnimationOptions.CurveEaseIn, View.LayoutIfNeeded, () => {});