2017-04-10 51 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