ios - AutoLayout, constraints, and rotation -
i'm having issue auto layout , constraints , use help.
i running application on ipad. have window contains 2 views, uiwebview , mkmapview. both of views set in ib, , auto layout turned on. uiwebview positioned @ top of window , mkmapview @ bottom. each view takes half of window. uiwebview has following constraints set in ib: nslayoutattributetop superview equal 0, leading edge superview equal 0, trailing edge superview equal 0, , nslayoutattributebottom superview equal 480. mkmapview has following constraints set in ib: nslayoutattributetop superview equal 480, leading edge superview equal 0, trailing edge superview equal 0, , nslayoutattributebottom superview equal 0.
when window loaded, mkmapview removed, since want uiwebview take entire screen, because there no data display in map view. done in updatedetailviews function:
- (void)updatedetailviews { displayheight = self.maximumusableframe.size.height; viewdistance=displayheight/2+centermapbutton.frame.size.height/2+16; [detailmapview settranslatesautoresizingmaskintoconstraints:no]; [directorywebview settranslatesautoresizingmaskintoconstraints:no]; if (mapviewvisible==true) { webviewdistfrombottomdefault=viewdistance; webviewdistfrombottom.constant=viewdistance; mapviewdistfromtopdefault=viewdistance; mapviewdistfromtop.constant=viewdistance; } else { [detailmapview removefromsuperview]; webviewdistfrombottomdefault=0; webviewdistfrombottom.constant=0; mapviewdistfromtopdefault=viewdistance; mapviewdistfromtop.constant=viewdistance; } [detailmapview setneedsupdateconstraints]; [uiview animatewithduration:0.25f animations:^{ [self.detailmapview layoutifneeded]; }]; } after mkmapview removed, nslayoutattributebottom attribute of uiwebview set 0, , fills entire screen. once there actual data show in map, mkmapview added, , uiwebview repositioned, along necessary constraints, in displaymapview function:
- (void)displaymapview { double dbllatitude; double dbllongitude; [detailmapview settranslatesautoresizingmaskintoconstraints:no]; if ([self ismapviewdisplayed]==false) { [detailview addsubview:detailmapview]; nslayoutconstraint *myconstraint =[nslayoutconstraint constraintwithitem:detailmapview attribute:nslayoutattributetop relatedby:nslayoutrelationequal toitem:detailview attribute:nslayoutattributetop multiplier:1.0 constant:mapviewdistfromtopdefault]; [detailview addconstraint:myconstraint]; //mapviewdistfromtop.constant = mapviewdistfromtopdefault; myconstraint =[nslayoutconstraint constraintwithitem:detailmapview attribute:nslayoutattributebottom relatedby:nslayoutrelationequal toitem:detailview attribute:nslayoutattributebottom multiplier:1.0 constant:0]; [detailview addconstraint:myconstraint]; myconstraint =[nslayoutconstraint constraintwithitem:detailmapview attribute:nslayoutattributeleading relatedby:nslayoutrelationequal toitem:detailview attribute:nslayoutattributeleading multiplier:1.0 constant:0]; [detailview addconstraint:myconstraint]; myconstraint =[nslayoutconstraint constraintwithitem:detailmapview attribute:nslayoutattributetrailing relatedby:nslayoutrelationequal toitem:detailview attribute:nslayoutattributetrailing multiplier:1.0 constant:0]; [detailview addconstraint:myconstraint]; [detailmapview setneedsupdateconstraints]; } [uiview animatewithduration:.5 animations:^{ webviewdistfrombottom.constant=webviewdistfrombottomdefault; mapviewdistfromtop.constant=mapviewdistfromtopdefault; [self.directorywebview layoutifneeded]; [self.detailmapview layoutifneeded]; }]; [self updatedetailviews]; ... if ((dbllatitude != 0) && (dbllongitude != 0)) { zoomlocation.latitude = dbllatitude; zoomlocation.longitude = dbllongitude; mkcoordinateregion viewregion = mkcoordinateregionmakewithdistance(zoomlocation, meters_per_mile, meters_per_mile); mkcoordinateregion adjustedregion = [detailmapview regionthatfits:viewregion]; [detailmapview setregion:adjustedregion animated:yes]; } cllocationcoordinate2d coordinate; coordinate.latitude = dbllatitude; coordinate.longitude = dbllongitude; ... [detailmapview addannotation:annotation]; } all of works intend. problem occurs when device rotated. if start ipad in portrait mode, webviewdistfrombottom , mapviewdistfromtop constraints set 490, due updatedetailviews function above has following calculations:
displayheight = self.maximumusableframe.size.height; viewdistance=displayheight/2+centermapbutton.frame.size.height/2+16; if ipad rotated landscape, willanimaterotationtointerfaceorientation function called, calls updatedetailviews, sets viewdistance 367 (and correspondingly webviewdistfrombottom.constant , mapviewdistfromtop.constant). uiwebview on top looks should, however, mkmapview on bottom not. mapviewdistfromtop constraint set 367 (if output value log), appears still set 490. updatedetailviews function calls [self.view layoutifneeded] (and have tried [detailmapview layoutifneeded], [detailmapview setneedslayout]), view not show correctly. distance top large. if rotate ipad portrait, looks fine.
i have same problem if ipad started in landscape mode, rotated portrait. in landscape mode, mapviewdistfromtop , webviewdistfrombottom values 367, , set 490 once rotated portrait. however, mkmapview on bottom looks distance top still 367, covering of display.
any idea i'm doing wrong? in advance assistance!!!
if understand question correctly, when in portrait want map view, 480 points tall, @ bottom, , if in landscape, want web view take whole screen. alternative approach modify height of map view (480 in portrait, 0 in landscape). don't remove map view, set height 0. , let existing constraints take care of else. there no adding of modifying of constraints, views, etc. need adjust 1 constant on rotation. job?
to illustrate this, in scenario i'm suggesting set constraints (i'll focus on vertical constraints) equivalent
v:|[webview][mapview(480)]| (i'm not suggesting use vfl specify constraints, it's concise way articulate series of constraints used.) note, make sure don't have extraneous constraints floating around (e.g. web view bottom constraint super view, etc.). i'm proposing, in vertical dimension, these constraints (web view top super view, web view bottom map view top, map view height, , map view bottom super view).
then, define , link outlet height constraint of mapview:
@property (weak, nonatomic) iboutlet nslayoutconstraint *mapviewheightconstraint; finally, on rotation, change constant constraint:
- (void)willrotatetointerfaceorientation:(uiinterfaceorientation)tointerfaceorientation duration:(nstimeinterval)duration { [super willrotatetointerfaceorientation:tointerfaceorientation duration:duration]; if (uiinterfaceorientationisportrait(tointerfaceorientation)) self.mapviewheightconstraint.constant = 480.0; else self.mapviewheightconstraint.constant = 0.0; } if understand ui you're shooting for, think that's need, eliminating of other code in question. tested , seems work fine.
Comments
Post a Comment