sin*_*eil 5 ios autolayout swift
我在日志中收到错误,告诉我在以编程方式向 Swift 中的视图添加约束时,存在无法同时满足的冲突约束,但正如您所见,在运行模拟器时,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.
Run Code Online (Sandbox Code Playgroud)
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")
}
Run Code Online (Sandbox Code Playgroud)
}
你的问题是因为你没有给你MKMapView一个适当的frame。当你像这样创建它时:
mapView = MKMapView()
Run Code Online (Sandbox Code Playgroud)
您正在设置框架的0宽度和0高度。然后,自动布局将该框架转换为视图宽度和高度的约束。
列出的冲突约束之一是:
<NSLayoutConstraint:0x7fd836318800 'UIView-Encapsulated-Layout-Width' H:[MKMapView:0x7fd83351d900(0)]>
Run Code Online (Sandbox Code Playgroud)
in表示有一个约束使 to 的宽度为0,这当然不是你想要的。[MKMapView:0x7fd83351d900(0)]MKMapView0
您可以通过在创建地图视图时为其提供适当的框架来解决此问题:
代替:
mapView = MKMapView()
Run Code Online (Sandbox Code Playgroud)
和:
mapView = MKMapView(frame: UIScreen.mainScreen().bounds)
Run Code Online (Sandbox Code Playgroud)
我下面的答案通过让 iOS 设置视图解决了这个问题,它做得正确。
我最初无法重现您的问题,但是当我将 viewController 放入 a 中时UITabBarController,我也看到了自动布局错误消息。
为了使其正常工作,我UIViewController在Storyboard中使用了一个标准,并将您的loadView代码移至viewDidLoad. 我添加了MKMapView作为 的子视图self.view以及适当的约束,以使其大小与 相同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
}
Run Code Online (Sandbox Code Playgroud)
将您的loadView代码移至viewDidLoad并删除这些行:
mapView = MKMapView()
view = mapView
Run Code Online (Sandbox Code Playgroud)
在Storyboard中,将的类更改view为。ViewControllerMKMapView
制作mapView一个@IBOutlet:
@IBOutlet var mapView: MKMapView!
Run Code Online (Sandbox Code Playgroud)
连接情节提要中的插座。
设置MKMapView代表。- 从Storyboard中Control拖动到顶部的ViewController图标,然后从弹出窗口中选择委托。您还可以通过调用以下方式连接委托:mapViewviewController
mapView.delegate = self
Run Code Online (Sandbox Code Playgroud)
在viewDidLoad。
| 归档时间: |
|
| 查看次数: |
1669 次 |
| 最近记录: |