我在日志中收到错误,告诉我在 Swift 中以编程方式向 View 添加约束时存在无法同时满足的冲突约束,但 UI 看起来就像我在运行模拟器时预期的那样你可以在屏幕截图中看到。左按钮的前缘与分段控件的前缘对齐,右按钮的后缘与分段控件的后缘对齐。
我认为是这些限制导致了问题,因为注释掉这 2 个是阻止错误被抛出的原因,但 UI 看起来并不像我预期的那样。
有人可以帮我理解我做错了什么吗?
Conversion View Controller loaded
2016-07-29 22:51:34.555 WorldTrotter[800:41503] 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:0x7fd836313550 UIButton:0x7fd836312e60'Current Location'.left == UILayoutGuide:0x7fd83630fc20'UIViewLayoutMarginsGuide'.left>",
"<NSLayoutConstraint:0x7fd836313660 UIButton:0x7fd836312e60'Current Location'.trailing == UILayoutGuide:0x7fd83630fc20'UIViewLayoutMarginsGuide'.centerX - 8>",
"<NSLayoutConstraint:0x7fd836318800 'UIView-Encapsulated-Layout-Width' H:[MKMapView:0x7fd83351d900(0)]>",
"<NSLayoutConstraint:0x7fd836312e00 'UIView-leftMargin-guide-constraint' H:|-(0)-[UILayoutGuide:0x7fd83630fc20'UIViewLayoutMarginsGuide'](LTR) (Names: '|':MKMapView:0x7fd83351d900 )>",
"<NSLayoutConstraint:0x7fd833794d30 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x7fd83630fc20'UIViewLayoutMarginsGuide']-(0)-|(LTR) (Names: '|':MKMapView:0x7fd83351d900 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fd836313660 UIButton:0x7fd836312e60'Current Location'.trailing == UILayoutGuide:0x7fd83630fc20'UIViewLayoutMarginsGuide'.centerX - 8>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2016-07-29 22:51:34.556 WorldTrotter[800:41503] 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:0x7fd836313ee0 UIButton:0x7fd8363136b0'Next Pin'.leading == UILayoutGuide:0x7fd83630fc20'UIViewLayoutMarginsGuide'.centerX + 8>",
"<NSLayoutConstraint:0x7fd836313fb0 UIButton:0x7fd8363136b0'Next Pin'.trailing == UILayoutGuide:0x7fd83630fc20'UIViewLayoutMarginsGuide'.trailing>",
"<NSLayoutConstraint:0x7fd836318800 'UIView-Encapsulated-Layout-Width' H:[MKMapView:0x7fd83351d900(0)]>",
"<NSLayoutConstraint:0x7fd836312e00 'UIView-leftMargin-guide-constraint' H:|-(0)-[UILayoutGuide:0x7fd83630fc20'UIViewLayoutMarginsGuide'](LTR) (Names: '|':MKMapView:0x7fd83351d900 )>",
"<NSLayoutConstraint:0x7fd833794d30 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x7fd83630fc20'UIViewLayoutMarginsGuide']-(0)-|(LTR) (Names: '|':MKMapView:0x7fd83351d900 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fd836313fb0 UIButton:0x7fd8363136b0'Next Pin'.trailing == UILayoutGuide:0x7fd83630fc20'UIViewLayoutMarginsGuide'.trailing>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
import UIKit
import MapKit
class MapViewController: UIViewController, MKMapViewDelegate {
var mapView: MKMapView!
let locationManager = CLLocationManager()
var coordinates: [CLLocationCoordinate2D] = []
var counter: Int = 0
override func loadView() {
mapView = MKMapView()
mapView.delegate = self
view = mapView
//Adding pins to map
let firstLocation = CLLocationCoordinate2DMake(5.000000, -5.000000)
let secondLocation = CLLocationCoordinate2DMake(-5.000000, 5.000000)
coordinates.append(firstLocation)
coordinates.append(secondLocation)
let segmentedControl = UISegmentedControl(items: ["Standard", "Hybrid", "Satellite"])
segmentedControl.backgroundColor = UIColor.whiteColor().colorWithAlphaComponent(0.5)
segmentedControl.selectedSegmentIndex = 0
segmentedControl.translatesAutoresizingMaskIntoConstraints = false
segmentedControl.addTarget(self, action: #selector(MapViewController.mapTypeChanged(_:)), forControlEvents: .ValueChanged)
view.addSubview(segmentedControl)
let margins = view.layoutMarginsGuide
let topConstraint = segmentedControl.topAnchor.constraintEqualToAnchor(topLayoutGuide.bottomAnchor, constant: 8)
let leadingConstraint = segmentedControl.leadingAnchor.constraintEqualToAnchor(margins.leadingAnchor)
let trailingConstraint = segmentedControl.trailingAnchor.constraintEqualToAnchor(margins.trailingAnchor)
topConstraint.active = true
leadingConstraint.active = true
trailingConstraint.active = true
let userButton = UIButton()
view.addSubview(userButton)
userButton.translatesAutoresizingMaskIntoConstraints = false
userButton.addTarget(self, action: #selector(MapViewController.userButtonSelected(_:)), forControlEvents: UIControlEvents.TouchUpInside)
userButton.setTitle("Current Location", forState: .Normal)
userButton.backgroundColor = UIColor.blueColor().colorWithAlphaComponent(0.7)
let bTopConstraint = userButton.topAnchor.constraintEqualToAnchor(segmentedControl.bottomAnchor, constant: 8)
//Problematic constraint I think
let bLConstraint = userButton.leftAnchor.constraintEqualToAnchor(margins.leftAnchor)
let bTConstraint = userButton.trailingAnchor.constraintEqualToAnchor(margins.centerXAnchor, constant: -8)
bTopConstraint.active = true
bLConstraint.active = true
bTConstraint.active = true
let pinsButton = UIButton()
view.addSubview(pinsButton)
pinsButton.translatesAutoresizingMaskIntoConstraints = false
pinsButton.addTarget(self, action: #selector(MapViewController.pinsButtonSelected(_:)), forControlEvents: UIControlEvents.TouchUpInside)
pinsButton.setTitle("Next Pin", forState: .Normal)
pinsButton.backgroundColor = UIColor.blueColor().colorWithAlphaComponent(0.7)
let pTopConstraint = pinsButton.topAnchor.constraintEqualToAnchor(segmentedControl.bottomAnchor, constant: 8)
//Problematic constraint I think
let pLConstraint = pinsButton.leadingAnchor.constraintEqualToAnchor(margins.centerXAnchor, constant: 8)
let pTConstraint = pinsButton.trailingAnchor.constraintEqualToAnchor(margins.trailingAnchor)
pTopConstraint.active = true
pLConstraint.active = true
pTConstraint.active = true
}
func mapTypeChanged(segControl: UISegmentedControl) {
switch segControl.selectedSegmentIndex {
case 0:
mapView.mapType = .Standard
case 1:
mapView.mapType = .Hybrid
case 2:
mapView.mapType = .Satellite
default:
break
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
func userButtonSelected(button: UIButton) {
if mapView.showsUserLocation == false {
mapView.showsUserLocation = true
} else {
mapView.showsUserLocation = false
}
}
func pinsButtonSelected(button: UIButton) {
if counter >= coordinates.count {
counter = 0
}
let dropPin = MKPointAnnotation()
dropPin.coordinate = coordinates[counter]
counter += 1
mapView.addAnnotation(dropPin)
mapView.setCenterCoordinate(dropPin.coordinate, animated: false)
}
func mapViewWillStartLocatingUser(mapView: MKMapView) {
// Ask for Authorisation from the User.
self.locationManager.requestAlwaysAuthorization()
// For use in foreground
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
mapView.setUserTrackingMode(MKUserTrackingMode.Follow, animated: true)
print("Tracking user")
}
最佳答案
您的问题是因为您没有提供 MKMapView
适当的frame
.当你这样创建它时:
mapView = MKMapView()
您正在将框架设置为 0
宽度和 0
高度。自动布局然后将该框架转换为 View 宽度和高度的约束。
列出的冲突约束之一是:
<NSLayoutConstraint:0x7fd836318800 'UIView-Encapsulated-Layout-Width' H:[MKMapView:0x7fd83351d900(0)]>
0
在 [MKMapView:0x7fd83351d900(0)]
表示有一个约束使MKMapView
的宽度成为0
,这当然不是您想要的。
您可以通过在创建 map View 时为其提供适当的框架来解决此问题:
替换:
mapView = MKMapView()
与:
mapView = MKMapView(frame: UIScreen.mainScreen().bounds)
我在下面的回答通过让 iOS 正确设置 View 来解决这个问题。
上一个答案
最初我无法重现您的问题,但是当我将您的 viewController 放在 UITabBarController
中时,我也看到了自动布局错误消息。
为了让它工作,我使用了一个标准 UIViewController
在Storyboard 中移动了你的loadView
编码为 viewDidLoad
.我添加了 MKMapView
作为 self.view
的 subview 加上适当的约束,使其大小与 self.view
相同:
override func viewDidLoad() {
super.viewDidLoad()
mapView = MKMapView()
mapView.delegate = self
mapView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(mapView)
NSLayoutConstraint.activateConstraints([
mapView.topAnchor.constraintEqualToAnchor(view.topAnchor),
mapView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor),
mapView.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor),
mapView.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor)
])
//Adding pins to map
let firstLocation = CLLocationCoordinate2DMake(5.000000, -5.000000)
let secondLocation = CLLocationCoordinate2DMake(-5.000000, 5.000000)
coordinates.append(firstLocation)
coordinates.append(secondLocation)
let segmentedControl = UISegmentedControl(items: ["Standard", "Hybrid", "Satellite"])
segmentedControl.backgroundColor = UIColor.whiteColor().colorWithAlphaComponent(0.5)
segmentedControl.selectedSegmentIndex = 0
segmentedControl.translatesAutoresizingMaskIntoConstraints = false
segmentedControl.addTarget(self, action: #selector(MapViewController.mapTypeChanged(_:)), forControlEvents: .ValueChanged)
view.addSubview(segmentedControl)
let margins = view.layoutMarginsGuide
let topConstraint = segmentedControl.topAnchor.constraintEqualToAnchor(topLayoutGuide.bottomAnchor, constant: 8)
let leadingConstraint = segmentedControl.leadingAnchor.constraintEqualToAnchor(margins.leadingAnchor)
let trailingConstraint = segmentedControl.trailingAnchor.constraintEqualToAnchor(margins.trailingAnchor)
topConstraint.active = true
leadingConstraint.active = true
trailingConstraint.active = true
let userButton = UIButton()
view.addSubview(userButton)
userButton.translatesAutoresizingMaskIntoConstraints = false
userButton.addTarget(self, action: #selector(MapViewController.userButtonSelected(_:)), forControlEvents: UIControlEvents.TouchUpInside)
userButton.setTitle("Current Location", forState: .Normal)
userButton.backgroundColor = UIColor.blueColor().colorWithAlphaComponent(0.7)
let bTopConstraint = userButton.topAnchor.constraintEqualToAnchor(segmentedControl.bottomAnchor, constant: 8)
//Problematic constraint I think
let bLConstraint = userButton.leftAnchor.constraintEqualToAnchor(margins.leftAnchor)
let bTConstraint = userButton.trailingAnchor.constraintEqualToAnchor(margins.centerXAnchor, constant: -8)
bTopConstraint.active = true
bLConstraint.active = true
bTConstraint.active = true
let pinsButton = UIButton()
view.addSubview(pinsButton)
pinsButton.translatesAutoresizingMaskIntoConstraints = false
pinsButton.addTarget(self, action: #selector(MapViewController.pinsButtonSelected(_:)), forControlEvents: UIControlEvents.TouchUpInside)
pinsButton.setTitle("Next Pin", forState: .Normal)
pinsButton.backgroundColor = UIColor.blueColor().colorWithAlphaComponent(0.7)
let pTopConstraint = pinsButton.topAnchor.constraintEqualToAnchor(segmentedControl.bottomAnchor, constant: 8)
//Problematic constraint I think
let pLConstraint = pinsButton.leadingAnchor.constraintEqualToAnchor(margins.centerXAnchor, constant: 8)
let pTConstraint = pinsButton.trailingAnchor.constraintEqualToAnchor(margins.trailingAnchor)
pTopConstraint.active = true
pLConstraint.active = true
pTConstraint.active = true
}
备选方案:
移动您的
loadView
代码为viewDidLoad
并摆脱这些行:mapView = MKMapView() view = mapView
在 Storyboard中,更改
view
的类在ViewController
至MKMapView
.制作
mapView
一个@IBOutlet
:@IBOutlet var mapView: MKMapView!
在 Storyboard中连接 socket 。
设置
MKMapView
代表。 Control-从mapView
拖动在 Storyboard 到viewController
顶部的 ViewController 图标并从弹出窗口中选择委托(delegate)。您还可以通过调用以下方式连接委托(delegate):mapView.delegate = self
在
viewDidLoad
.
关于ios - 以编程方式向 Swift 中的 View 添加约束时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38659695/