ios - What's wrong with my auto layout constraints? -
here uiviewcontroller before press button (i didn't put there not relevant):
when press button, uiview containing 2 uipickerview appear top. right under uiview 2 uibuttons. everthing works auto layout:
here code when create constraints:
let okbuttonheight: cgfloat = 53 let okbuttonwidth: cgfloat = 53 let leftpickerviewwidth: cgfloat = 80 let leftpickerviewheight: cgfloat = 200 let margin: cgfloat = 8 // frame let constraint0 = nslayoutconstraint(item: okbutton, attribute: .bottom, relatedby: .equal, toitem: self.view, attribute: .top, multiplier: 1, constant: 0) let constraint1 = nslayoutconstraint(item: frameview, attribute: .centerx, relatedby: .equal, toitem: view, attribute: .centerx, multiplier: 1, constant: 0) // left & right pickerviews let constraint2 = nslayoutconstraint(item: leftpickerview, attribute: .width, relatedby: .equal, toitem: rightpickerview, attribute: .width, multiplier: 1, constant: 0) let constraint3 = nslayoutconstraint(item: leftpickerview, attribute: .height, relatedby: .equal, toitem: rightpickerview, attribute: .height, multiplier: 1, constant: 0) let constraint4 = nslayoutconstraint(item: leftpickerview, attribute: .trailing, relatedby: .equal, toitem: rightpickerview, attribute: .leading, multiplier: 1, constant: -margin) let constraint5 = nslayoutconstraint(item: leftpickerview, attribute: .top, relatedby: .equal, toitem: rightpickerview, attribute: .top, multiplier: 1, constant: 0) // left pickerview let constraint6 = nslayoutconstraint(item: leftpickerview, attribute: .height, relatedby: .equal, toitem: nil, attribute: .notanattribute, multiplier: 1, constant: leftpickerviewheight) let constraint7 = nslayoutconstraint(item: leftpickerview, attribute: .width, relatedby: .equal, toitem: nil, attribute: .notanattribute, multiplier: 1, constant: leftpickerviewwidth) let constraint8 = nslayoutconstraint(item: leftpickerview, attribute: .top, relatedby: .equal, toitem: frameview, attribute: .top, multiplier: 1, constant: -margin) let constraint9 = nslayoutconstraint(item: leftpickerview, attribute: .bottom, relatedby: .equal, toitem: frameview, attribute: .bottom, multiplier: 1, constant: margin) let constraint10 = nslayoutconstraint(item: leftpickerview, attribute: .leading, relatedby: .equal, toitem: frameview, attribute: .leading, multiplier: 1, constant: margin) // right pickerview let constraint11 = nslayoutconstraint(item: rightpickerview, attribute: .trailing, relatedby: .equal, toitem: frameview, attribute: .trailing, multiplier: 1, constant: -margin) // ok & cancel buttons let constraint12 = nslayoutconstraint(item: okbutton, attribute: .top, relatedby: .equal, toitem: cancelbutton, attribute: .top, multiplier: 1, constant: 0) let constraint13 = nslayoutconstraint(item: okbutton, attribute: .bottom, relatedby: .equal, toitem: cancelbutton, attribute: .bottom, multiplier: 1, constant: 0) let constraint14 = nslayoutconstraint(item: okbutton, attribute: .width, relatedby: .equal, toitem: cancelbutton, attribute: .width, multiplier: 1, constant: 0) let constraint15 = nslayoutconstraint(item: okbutton, attribute: .height, relatedby: .equal, toitem: cancelbutton, attribute: .height, multiplier: 1, constant: 0) // ok button let constraint16 = nslayoutconstraint(item: view, attribute: .centerx, relatedby: .equal, toitem: okbutton, attribute: .trailing, multiplier: 1, constant: 10) let constraint17 = nslayoutconstraint(item: okbutton, attribute: .width, relatedby: .equal, toitem: nil, attribute: .notanattribute, multiplier: 1, constant: okbuttonwidth) let constraint18 = nslayoutconstraint(item: okbutton, attribute: .height, relatedby: .equal, toitem: nil, attribute: .notanattribute, multiplier: 1, constant: okbuttonheight) let constraint19 = nslayoutconstraint(item: okbutton, attribute: .top, relatedby: .equal, toitem: frameview, attribute: .bottom, multiplier: 1, constant: 10) // cancel button let constraint20 = nslayoutconstraint(item: view, attribute: .centerx, relatedby: .equal, toitem: cancelbutton, attribute: .leading, multiplier: 1, constant: -10) view.addconstraint(constraint0) view.addconstraint(constraint1) view.addconstraint(constraint12) view.addconstraint(constraint13) view.addconstraint(constraint14) view.addconstraint(constraint15) view.addconstraint(constraint16) view.addconstraint(constraint17) view.addconstraint(constraint18) view.addconstraint(constraint19) view.addconstraint(constraint20) frameview.addconstraint(constraint2) frameview.addconstraint(constraint3) frameview.addconstraint(constraint4) frameview.addconstraint(constraint5) frameview.addconstraint(constraint6) frameview.addconstraint(constraint7) frameview.addconstraint(constraint8) frameview.addconstraint(constraint9) frameview.addconstraint(constraint10) frameview.addconstraint(constraint11) selectioncurrencyconstraintlist = [constraint0, constraint1, constraint2, constraint3, constraint4, constraint5, constraint6, constraint7, constraint8, constraint9, constraint10, constraint11, constraint12, constraint13, constraint14, constraint15, constraint16, constraint17, constraint18, constraint19, constraint20] frameview.hidden = true okbutton.hidden = true cancelbutton.hidden = true
at point, uiview , 2 buttons hidden above top of screen.
when press button make appear, execute code:
frameview.hidden = hide okbutton.hidden = hide cancelbutton.hidden = hide if var constraints = selectioncurrencyconstraintlist { let topframeconstraint = constraints[0] view.removeconstraint(topframeconstraint) constraints.removeatindex(0) let newtopconstraint: nslayoutconstraint! if hide { newtopconstraint = nslayoutconstraint(item: okbutton, attribute: .bottom, relatedby: .equal, toitem: self.view, attribute: .top, multiplier: 1, constant: 0) } else { newtopconstraint = nslayoutconstraint(item: frameview, attribute: .top, relatedby: .equal, toitem: topview, attribute: .bottom, multiplier: 1, constant: margin) } constraints.insert(newtopconstraint, atindex: 0) view.addconstraint(newtopconstraint) } uiview.animatewithduration(0.5) { self.view.layoutifneeded() }
when replace constraint nslayoutconstraint(item: okbutton, attribute: .bottom, relatedby: .equal, toitem: self.view, attribute: .top, multiplier: 1, constant: 0)
1 nslayoutconstraint(item: frameview, attribute: .top, relatedby: .equal, toitem: topview, attribute: .bottom, multiplier: 1, constant: margin)
works fine.
when reverse it, got constraints cannot satisfied:
2015-05-15 20:17:25.374 currencyex[624:42779] unable simultaneously satisfy constraints. @ least 1 of constraints in following list 1 don't want. try this: (1) @ each constraint , try figure out don't expect; (2) find code added unwanted constraint or constraints , fix it. (note: if you're seeing nsautoresizingmasklayoutconstraints don't understand, refer documentation uiview property translatesautoresizingmaskintoconstraints) ( "<nslayoutconstraint:0x17408de30 v:[uiview:0x174186660(50)]>", "<nslayoutconstraint:0x174090fe0 v:[_uilayoutguide:0x1741a8a40]-(0)-[uiview:0x174186660]>", "<_uilayoutsupportconstraint:0x1740a3e40 v:[_uilayoutguide:0x1741a8a40(20)]>", "<_uilayoutsupportconstraint:0x1740a3d80 v:|-(0)-[_uilayoutguide:0x1741a8a40] (names: '|':uiview:0x174186590 )>", "<nslayoutconstraint:0x170089150 v:[uibutton:0x146e49020(53)]>", "<nslayoutconstraint:0x1700891a0 v:[uiview:0x1741868d0]-(10)-[uibutton:0x146e49020]>", "<nslayoutconstraint:0x170088d90 v:[uipickerview:0x146e09ef0(200)]>", "<nslayoutconstraint:0x170088e30 v:|-(-8)-[uipickerview:0x146e09ef0] (names: '|':uiview:0x1741868d0 )>", "<nslayoutconstraint:0x170088e80 uipickerview:0x146e09ef0.bottom == uiview:0x1741868d0.bottom + 8>", "<nslayoutconstraint:0x17008ef60 v:[uiview:0x174186660]-(8)-[uiview:0x1741868d0]>", "<nslayoutconstraint:0x174096620 uibutton:0x146e49020.bottom == uiview:0x174186590.top>" ) attempt recover breaking constraint <nslayoutconstraint:0x170088e80 uipickerview:0x146e09ef0.bottom == uiview:0x1741868d0.bottom + 8> make symbolic breakpoint @ uiviewalertforunsatisfiableconstraints catch in debugger. methods in uiconstraintbasedlayoutdebugging category on uiview listed in <uikit/uiview.h> may helpful. 2015-05-15 20:17:25.377 currencyex[624:42779] unable simultaneously satisfy constraints. @ least 1 of constraints in following list 1 don't want. try this: (1) @ each constraint , try figure out don't expect; (2) find code added unwanted constraint or constraints , fix it. (note: if you're seeing nsautoresizingmasklayoutconstraints don't understand, refer documentation uiview property translatesautoresizingmaskintoconstraints) ( "<nslayoutconstraint:0x17408de30 v:[uiview:0x174186660(50)]>", "<nslayoutconstraint:0x174090fe0 v:[_uilayoutguide:0x1741a8a40]-(0)-[uiview:0x174186660]>", "<_uilayoutsupportconstraint:0x1740a3e40 v:[_uilayoutguide:0x1741a8a40(20)]>", "<_uilayoutsupportconstraint:0x1740a3d80 v:|-(0)-[_uilayoutguide:0x1741a8a40] (names: '|':uiview:0x174186590 )>", "<nslayoutconstraint:0x170089150 v:[uibutton:0x146e49020(53)]>", "<nslayoutconstraint:0x1700891a0 v:[uiview:0x1741868d0]-(10)-[uibutton:0x146e49020]>", "<nslayoutconstraint:0x17008ef60 v:[uiview:0x174186660]-(8)-[uiview:0x1741868d0]>", "<nslayoutconstraint:0x174096620 uibutton:0x146e49020.bottom == uiview:0x174186590.top>" ) attempt recover breaking constraint <nslayoutconstraint:0x17408de30 v:[uiview:0x174186660(50)]> make symbolic breakpoint @ uiviewalertforunsatisfiableconstraints catch in debugger. methods in uiconstraintbasedlayoutdebugging category on uiview listed in <uikit/uiview.h> may helpful. 2015-05-15 20:17:25.378 currencyex[624:42779] unable simultaneously satisfy constraints. @ least 1 of constraints in following list 1 don't want. try this: (1) @ each constraint , try figure out don't expect; (2) find code added unwanted constraint or constraints , fix it. (note: if you're seeing nsautoresizingmasklayoutconstraints don't understand, refer documentation uiview property translatesautoresizingmaskintoconstraints) ( "<nslayoutconstraint:0x174090fe0 v:[_uilayoutguide:0x1741a8a40]-(0)-[uiview:0x174186660]>", "<_uilayoutsupportconstraint:0x1740a3e40 v:[_uilayoutguide:0x1741a8a40(20)]>", "<_uilayoutsupportconstraint:0x1740a3d80 v:|-(0)-[_uilayoutguide:0x1741a8a40] (names: '|':uiview:0x174186590 )>", "<nslayoutconstraint:0x170089150 v:[uibutton:0x146e49020(53)]>", "<nslayoutconstraint:0x1700891a0 v:[uiview:0x1741868d0]-(10)-[uibutton:0x146e49020]>", "<nslayoutconstraint:0x17008ef60 v:[uiview:0x174186660]-(8)-[uiview:0x1741868d0]>", "<nslayoutconstraint:0x174096620 uibutton:0x146e49020.bottom == uiview:0x174186590.top>" ) attempt recover breaking constraint <nslayoutconstraint:0x1700891a0 v:[uiview:0x1741868d0]-(10)-[uibutton:0x146e49020]>
i don't understand why. works @ first constraints. when modify of them works, , when put them back, doesn't work anymore...
any idea?
let's call constraints:
constrainthide
: okbutton
bottom aligned superview top.
constraintshow
: frameview
8 points under topview
.
if inspect colliding constraints in log 1 one, notice both of constraints constrainthide
, constraintshow
present in same time.
this caused removal/addition of constraints.
- initial state
only constrainthide
in view
- state after showing view
constrainthide
correctly removed, constraintshow
added
- state after hiding view
constraintshow
not removed, constrainthide
added
- collision
now question why step 3 hasn't removed constraint? because of bug in step 2. selectioncurrencyconstraintlist
not correctly updated in step 3 attempting remove original constrainthide
constraint instead of constraint constraintshow
added step 2.
this due fact if var constraints = selectioncurrencyconstraintlist
makes copy of array. have save changes in end.
solution
add
selectioncurrencyconstraintlist = constraints
to end of block.
having said that, can drastically simplify code adding of constraints in interface builder, connect constraintshow
, constrainthide
outlets , instead of removing/addding them, change priority on them 0
1000
.
Comments
Post a Comment