2017-04-10 52 views
2

我有一個MKMapView約300高,它摺疊在兩個其他視圖之間,只是像摺疊視圖時通常那樣上下動畫高度。MKMapView與零高度約束掙扎 - edgeInsets的地圖視圖?

enter image description here

@IBOutlet var heightMap: NSLayoutConstraint! 
@IBOutlet var theMap: MKMapView! 

當視圖啓動它是高度爲零..

override func viewDidLoad() { 
    super.viewDidLoad() 
    .. 
    heightMap.constant = 0 
} 

有一股真氣警告...

[LayoutConstraints] Unable to simultaneously satisfy constraints. 
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
     (1) look at each constraint and try to figure out which you don't expect; 
     (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x6080000904f0 MKMapView:0x7fe6b3000600.height == 0 (active)>", 
    "<NSLayoutConstraint:0x608000093a60 UILayoutGuide:0x60800018fd80'Edge Insets'.top == MKMapView:0x7fe6b3000600.top + 8 (active)>", 
    "<NSLayoutConstraint:0x608000093b50 UILayoutGuide:0x60800018fd80'Edge Insets'.bottom == MKMapView:0x7fe6b3000600.bottom (active)>" 
) 

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x608000093b50 UILayoutGuide:0x60800018fd80'Edge Insets'.bottom == MKMapView:0x7fe6b3000600.bottom (active)> 

注意,這似乎是掙扎帶有「edgeInsets」或可能的「Edge Insets」(帶空格!)頂部和底部,

'Edge Insets'.top == MKMapView:0x7fe6b3000600.top + 8 
'Edge Insets'.bottom == MKMapView:0x7fe6b3000600.bottom 

地圖視圖有一個只讀屬性.alignmentRectInsets

(其實當我打印了這一點,不管它是什麼,它是零反正..

let ari = theMap.alignmentRectInsets 
print("wth \(ari)") 
> wth UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0) 

我甚至無法在MKMapView上找到任何關於「邊緣插入」的信息,這裏的交易是什麼?

我仔細檢查了未安裝的約束和常見問題。

+0

如果你給高度constriant,無需底部和頂部的佈局約束。嘗試刪除其中的一個。 – MBN

+0

hi @MBN - 不,我沒有添加奇怪的'Edge Insets'.top和'Edge Insets'.bottom約束。這些似乎是由MKMapKit本身添加的。 (所有「我的」約束都是完美的)。 – Fattie

+0

這是令人難以置信的沒有人知道這一點! – Fattie

回答

2

有趣的是,如果初始高度爲零,我只會得到這個錯誤,所以它似乎是mapview初始設置的問題。他們似乎解決方案是要

  1. 給的MapView一個hieght在故事板(我做100)
  2. 讓 在界面生成器檢查隱框隱藏的MapView

當其時間顯示的MapView:

  1. 顯示它
  2. 最小化它(我設置爲.ulpOfOne我不斷零nstead因爲從技術上幀不應該是會退化)
  3. 動畫到最終位置

    class ViewController: UIViewController{ 
        @IBOutlet weak var m: MKMapView! 
        @IBOutlet weak var h: NSLayoutConstraint! 
        @IBAction func t(_ sender: Any) { 
         m.isHidden = false 
         h.constant = .ulpOfOne 
         view.layoutIfNeeded() 
         h.constant = 100 
         UIView.animate(withDuration: 3) { 
          self.view.layoutIfNeeded() 
         } 
        } 
    } 
    

僅供參考我真的使用UIStackView對於這一點,只是動畫是否隱藏代替,然後你甚至不必處理代碼中的約束。

+0

嘿喬希謝謝。它似乎只是一個錯誤,或什麼的。 **「邊緣插入」**仍然神祕!關於**。ulpOfOne **的提示很好,謝謝。爲.isHidden使用堆棧視圖的想法也很好! – Fattie

1

我一直在努力解決同樣的問題,每次想要隱藏MKMapView(手動使用高度約束或在UIStackView中)時都會收到此警告。我注意到,我可以通過在激活零高度約束之前將地圖視圖的邊界高度設置爲0來防止警告。所以我寫了一個小類來封裝的bug:

import MapKit 

class HideableMapView: MKMapView { 

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 

     if self.containsZeroHeightConstraint() { 
      // Set the bounds manually before the constraint gets processed to prevent an auto layout warning 
      self.bounds.size.height = 0 
     } 

     super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) 
    } 

    private func containsZeroHeightConstraint() -> Bool { 
     return (self.constraints.filter { $0.firstAttribute == .height && $0.constant == 0 }).isEmpty == false 
    } 
} 

此類工作爲我的項目,其中的MKMapView嵌入在UIStackView。根據您的設置,您可能需要重寫另一種方法。爲UIViewAlertForUnsatisfiableConstraints設置一個符號斷點以查看調用堆棧。

我又提出了雷達,你可以在這裏找到:https://openradar.appspot.com/radar?id=6109127172423680

+0

感謝Felix的報道! – Fattie

+1

此問題已在iOS 11 beta 7中解決。 – Felix

+0

**宏偉**謝謝@Felix! – Fattie