我正在使用Swift 5,Xcode 11.3.1创建应用。最初,我是使用Swift中的情节提要创建应用的,但现在我正在通过应用以编程方式实现标签,文本字段,选择器,开关,按钮等。但是,当我尝试使用我最初使用情节提要创建的MKMapView进行编程编码时,遇到了一个障碍。
[当我使用情节提要创建时,我的屏幕/场景分为3个部分/区域,其中前100pts(CGFloat pts)用于显示一些文本。然后我有高度为ptpts的pt 106的MKMapView。 MKMapView延伸到边缘,因此几乎是一个正方形(ish)...屏幕/场景的下部用于显示一些文本,几个UISwitches和一个自定义按钮。在MKMapView中,我还具有一个显示中心点和用户位置的标记,以便用户可以将地图滚动到地图上的另一个点,该点由地图中间的标记表示。
所以,这里是出问题的地方...我试图以编程方式为MKMapView定义相同类型的外观,但是它一直在全屏显示地图,因此覆盖了我用于显示的上部和下部区域文字和按钮。我无法弄清楚为什么MKMapView不坚持我设置的框架或约束。我的第一个尝试是定义框架,但是随后我做了一些阅读,发现自己也需要对约束进行编码。但是,现在,当应用程序运行约束时(第一个约束),导致该应用程序炸毁并出现错误....
2020-03-14 21:43:57.509878 + 1100 MyGarageApp [17060:95627] *由于未捕获的异常'NSGenericException'而终止应用程序,原因:'无法激活锚点约束,因为它们没有共同祖先。约束或其锚点是否引用了不同视图层次结构中的项目?那是非法的。*第一个引发调用堆栈:
这是我显示地图的代码:
[这段代码在我的viewDidLoad之前]
// Early IBOutlets required to define the scene
var theMapView: MKMapView!
@IBOutlet weak var addressLabelOutlet: UILabel!
let centerMapButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(UIImage(named: "MapPointer.png"), for: .normal)
button.addTarget(self, action: #selector(handleCenterOnUserLocation), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
下一段代码是我的viewDidLoad部分之后的方法(即,在我的身体方法之内)...
func configureMapView() {
theMapView = MKMapView(frame: CGRect(x: 0, y: 106, width: self.view.frame.width, height:413))
theMapView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true
theMapView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 106).isActive = true
theMapView.heightAnchor.constraint(equalToConstant: 413).isActive = true
theMapView.widthAnchor.constraint(equalToConstant: 355).isActive = true
theMapView.showsUserLocation = true
theMapView.userTrackingMode = .follow
theMapView.frame = view.frame
view.addSubview(theMapView)
}
由于我渴望摆脱情节提要的局限,并能够控制我的代码以正确地适应设备,因此任何人都能以编程方式解决该问题的指导将不胜感激。
谢谢大家。
首先,使用约束要求将translatesAutoresizingMaskIntoConstraints
设置为false
。其次,将地图的框架设置为从x = 0开始,然后将前导约束设置为x = 10,这意味着这两个将相互冲突。
此外,仅在将视图添加到视图层次结构后,才能添加约束,因此将约束移到view.addSubview()
行下方。
一旦添加了约束,请尝试调用theMapView.layoutIfNeeded()
以实际触发对地图视图的重新布局。
我的最后一条评论是,您可以在相对范围内更好地定义您在此处定义的约束,因为现在移至更大的屏幕会完全破坏您的布局。