2013-03-13 127 views
2

我遇到了自動佈局和約束問題,可以使用一些幫助。AutoLayout,約束和旋轉

我運行在iPad這個應用程序。我有一個包含兩個視圖的窗口,一個UIWebView和一個MKMapView。這兩個視圖都在IB中設置,並且Auto Layout打開。 UIWebView位於窗口的頂部,MKMapView位於窗口的底部。每個視圖佔用近一半的窗口。在一個UIWebView在IB設置以下限制:NSLayoutAttributeTop到上海華等於0,前緣上海華等於0,後緣的SuperView等於0,NSLayoutAttributeBottom到上海華等於480的MKMapView有以下限制設置在IB:NSLayoutAttributeTop到Superview等於480,前沿到Superview等於0,後沿到Superview等於0,並且NSLayoutAttributeBottom到Superview等於0.

當窗口加載時,MKMapView實際上被刪除,因爲我想讓UIWebView佔據整個屏幕,因爲在地圖視圖中沒有要顯示的數據。這是我updateDetailViews函數來完成:

- (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]; 
}]; 

} 

的的MKMapView被移除之後,一個UIWebView的NSLayoutAttributeBottom屬性設置爲0,它填補了整個屏幕。一旦有實際數據在地圖上顯示,該的MKMapView,然後加入,和UIWebView的重新定位,必要的限制一起,在我displayMapView功能:

- (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]; 
} 

所有這一切就像我打算。設備旋轉時出現問題。如果我在人像模式與iPad開始,將webViewDistFromBottom和mapViewDistFromTop限制設置爲490,由於updateDetailViews功能上面它有如下的計算:

displayHeight = self.maximumUsableFrame.size.height; 
viewDistance=displayHeight/2+centerMapButton.frame.size.height/2+16; 

如果iPad旋轉爲橫向,則willAnimateRotationToInterfaceOrientation功能被調用,然後調用updateDetailViews,它將viewDistance設置爲367(以及相應的webViewDistFromBottom.constant和mapViewDistFromTop.constant)。上面的UIWebView看起來應該是這樣,但是,底部的MKMapView不會。 mapViewDistFromTop約束設置爲367(如果我將值輸出到日誌),但它似乎仍然設置爲490.我的updateDetailViews函數調用[self.view layoutIfNeeded](我也嘗試過[detailMapView layoutIfNeeded], [detailMapView setNeedsLayout]),但該視圖不能正確顯示。距離頂部的距離太大。如果我將iPad旋轉回肖像,它看起來很好。

我也有同樣的問題,如果iPad在橫向模式下啓動,然後旋轉爲縱向。在橫向模式下,mapViewDistFromTop和webViewDistFromBottom值爲367,並且一旦旋轉爲縱向,則設置爲490。但是,底部的MKMapView看起來與頂部的距離仍然是367,覆蓋了太多的顯示。

任何想法我做錯了什麼?預先感謝您的幫助!

回答

5

如果我理解正確的問題,當人像你想地圖視圖,480點高,在底部,如果在景觀,您希望Web視圖佔據整個屏幕。另一種方法是修改地圖視圖的高度(縱向480,橫向0)。不要移除地圖視圖,只需將其高度設置爲0.並讓現有約束處理所有其他事情。然後,不會添加修改約束,視圖等。您只需要在旋轉時調整一個常量。這是否做這項工作?

爲了說明這一點,在這種情況下,我建議您設置的限制(我將只專注於垂直約束),使它們等同於

V:|[webView][mapView(480)]| 

(我不建議你使用VFL來指定約束條件,但它只是表達我使用的一系列約束條件的最簡潔的方式。)注意,確保沒有任何多餘的約束條件浮動(例如,Web視圖底部約束到超級視圖等)。我在垂直維度中提出了這些約束(Web視圖從頂部到超級視圖,Web視圖從底部到地圖頂部,地圖視圖高度和地圖視圖底部到超級視圖)。

然後,定義併爲mapView的高度約束鏈接的插座:如果我理解

- (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; 
} 

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mapViewHeightConstraint; 

最後,在旋轉,只需更改常量針對約束您要拍攝的用戶界面,我認爲這就是您需要的全部內容,在您的問題中排除了所有其他代碼。我只是測試它,它似乎工作正常。

+1

好吧,我肯定比我應該做的事情困難得多...感謝您的幫助! – user1292943 2013-03-13 19:43:36