Thursday 15 May 2014

ios - Auto layout - Collapsable views (vertically) -



ios - Auto layout - Collapsable views (vertically) -

i'd create "adding new credit card viewcontroller". don't want aggravate users of required fields presented @ once. action contains several steps. on each step view-controller reveals new subview (which contains 1 or more textfields) , collapses old 1 (the current text field after it's text validated).

i've created viewcontroller on storyboard. , placed of subviews 1 above other.

i've created of constraints on storyboard, each subviews' clips above subview etc'.

i.e:

nsmutablearray *constraints = [[nslayoutconstraint constraintswithvisualformat: @"v:|[titleview]-[subtitleview]-[amountview]-[cardnumview]-[cardsimagesview]-[mmyycvvview]-[billinginfoview]-[buttomview]|" options:nslayoutformatalignalltop | nslayoutformatalignallbottom metrics:nil views:variablebindings] mutablecopy];

each of these subviews contain height constraint.

in each step 1 of height constraints set 0 , 1 changed 0 required height.

i.e:

self.hgtcrtmmyycvv.constant = showfields? 50 : 0; self.hgtcrtbillinginfo.constant = showfields? 140 : 0; self.mmyycvvview.hidden = !showfields; self.billinginfoview.hidden = !showfields;

i got 2 issues:

without calling layoutifneeded initial layout valid did not alter after changing height constraints.

calling layoutifneeded did not clip bottom view lastly visible 1 - placed @ bottom of view if subviews appear @ once, since hidden gap created. changing height constraint of subviews applied on screen still gap stayed.

please advise.

calling "layoutifneeded" did not clip bottom view lastly visible 1 - placed @ bottom of view if subviews appear @ once

look @ constraints. have pinned bottom of bottom view bottom of superview! bottom must appear @ bottom of superview, since instructed do.

indeed, surprised constraints work @ all. have overdetermined them. if give every field height and pin top , bottom, every field, impossible satisfy constraints unless lucky. height of superview fixed, constraints have add together height.

i'm going suggest finish alternative approach, think find easier. instead of messing individual constants, plan right (not overdetermined) constraints each possible situation, , store constraints in properties. when want hide/reveal field, remove constraints , swap in set.

this solve layoutifneeded problem.

it happens have actual illustration showing how this. (it written in swift, i'm sure can compensate mentally.) in illustration code, have 3 rectangles; remove 1 rectangle , close gap between remaining two. preparation of 2 sets of constraints tedious elementary:

allow c1 = nslayoutconstraint.constraintswithvisualformat("h:|-(20)-[v(100)]", options: nil, metrics: nil, views: ["v":v1]) [nslayoutconstraint] allow c2 = nslayoutconstraint.constraintswithvisualformat("h:|-(20)-[v(100)]", options: nil, metrics: nil, views: ["v":v2]) [nslayoutconstraint] allow c3 = nslayoutconstraint.constraintswithvisualformat("h:|-(20)-[v(100)]", options: nil, metrics: nil, views: ["v":v3]) [nslayoutconstraint] allow c4 = nslayoutconstraint.constraintswithvisualformat("v:|-(100)-[v(20)]", options: nil, metrics: nil, views: ["v":v1]) [nslayoutconstraint] allow c5with = nslayoutconstraint.constraintswithvisualformat("v:[v1]-(20)-[v2(20)]-(20)-[v3(20)]", options: nil, metrics: nil, views: ["v1":v1, "v2":v2, "v3":v3]) [nslayoutconstraint] allow c5without = nslayoutconstraint.constraintswithvisualformat("v:[v1]-(20)-[v3(20)]", options: nil, metrics: nil, views: ["v1":v1, "v3":v3]) [nslayoutconstraint] self.constraintswith.extend(c1) self.constraintswith.extend(c2) self.constraintswith.extend(c3) self.constraintswith.extend(c4) self.constraintswith.extend(c5with) self.constraintswithout.extend(c1) self.constraintswithout.extend(c3) self.constraintswithout.extend(c4) self.constraintswithout.extend(c5without) nslayoutconstraint.activateconstraints(self.constraintswith)

but payoff comes when time swap middle view in or out of interface: it's trivial. remove or insert it, , remove constraints , insert finish new set of constraints appropriate situation, have prepared:

@ibaction func doswap(sender: anyobject) { if self.v2.superview != nil { self.v2.removefromsuperview() nslayoutconstraint.deactivateconstraints(self.constraintswith) nslayoutconstraint.activateconstraints(self.constraintswithout) } else { self.view.addsubview(v2) nslayoutconstraint.deactivateconstraints(self.constraintswithout) nslayoutconstraint.activateconstraints(self.constraintswith) } }

the preparation of multiple sets of constraints tedious can done rule, i.e. constraints can "machine-generated" in loop (writing left exercise you). swapping constraints in , out 1 time again according simple rule, since 1 set right particular set of fields wish show/hide. 1 time set much simpler , more maintainable doing now.

ios autolayout collapsable

No comments:

Post a Comment