为什么有些开发人员会添加这样的约束:
NSLayoutConstraint(item: myView, attribute: .right, relatedBy: .equal, toItem: view, attribute: .right, multiplier: 1.0, constant: 20.0).isActive = true
Run Code Online (Sandbox Code Playgroud)
还有一些像这样:
myView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 20).isActive = true
Run Code Online (Sandbox Code Playgroud)
他们基本上做同样的事情......对吧?那么它们之间有什么区别呢?为什么应该使用其中一种而不是另一种?使用其中一种与另一种相比是否存在性能差异?
在我工作的地方,我们的 iOS 主管专门使用NSLayoutConstraint初始化方式,每个人都被迫这样做,以提高整个代码的一致性和可读性,我喜欢这两种方式,我只是想知道是否有任何初始化方式使用其中一种比另一种有什么好处?或者差异只是基于偏好?
请参阅以下代码:
def viewDidLoad
super
self.view.translatesAutoresizingMaskIntoConstraints = false
self.view.backgroundColor = UIColor.whiteColor
@start = UIButton.buttonWithType(UIButtonTypeRoundedRect).tap do |el|
el.translatesAutoresizingMaskIntoConstraints = false
el.setTitle('Start', forState:UIControlStateNormal)
el.addTarget(self, action:'toStartController', forControlEvents:UIControlEventTouchUpInside)
self.view.addSubview(el)
end
self.layout_subviews
end
def layout_subviews
metrics = { 'space' => 8 }
views_dict = {
'superview' => self.view,
'start' => @start
}
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('H:|-[start(100)]-|',
options: NSLayoutFormatAlignAllCenterX,
metrics: metrics,
views: views_dict))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('V:[start]-|',
options: NSLayoutFormatAlignAllBottom,
metrics: metrics,
views: views_dict))
end
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是H:|-[start(100)]-|行不通的.我想要的是一个宽度为100的按钮,以X轴为中心,并以默认边距连接到屏幕底部.一旦我删除(100)这个工作,但按钮伸展到屏幕的宽度减去默认边距.当我指定自定义宽度时,我认为自动布局系统无法确定左边距和右边距应该是什么.我收到一个Unable to simultaneously satisfy constraints.错误.我想这与破折号有关H:|-[start(100)]-|,它需要有一个流体宽度来将start元素附加到superview,而不是默认边距.
有关如何解决这个问题的任何想法?
更新(感谢ghettopia): …
autolayout rubymotion ios6 nslayoutconstraint visual-format-language
我只是阅读了一些关于如何以编程方式操作约束数的信息,但我认为我需要使用Xcode直观地看到它.所以我决定放一个这样的UIView,看看Constraints发生了什么:

自动它将创建4个约束:

在修改数字后,我得到了所有这些的含义.我们有2个垂直空间和2个水平空间.但是让我们首先关注垂直......
从屏幕顶部测量的垂直空间之一(我认为是superview),我给出了这个数字30.和从底部测量的其他垂直空间,我给了-50.
现在,当它变成代码时,我真的不明白如何给这两个数字.据我所知,这里是如何使用代码设置约束:
NSLayoutConstraint *myConstraint =[NSLayoutConstraint
constraintWithItem:_screenView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:_container
attribute:NSLayoutAttributeHeight
multiplier:20
constant:200];
[_screenView addConstraint: myConstraint];
Run Code Online (Sandbox Code Playgroud)
让我们假设_screenView是一个_container超级视图,并将UIView放在它上面.我有3个问题:
NSLayoutConstraint吗?[_screenView addConstraint: myConstraint];两次吗?multiplier用?因为我在故事板中没有看到这个选项.非常感谢你.
我想创建一个滚动禁用的tableview,它将填充导航栏下面的视图.最后我设法做到了,但这不是正确的方法,因为我给tableview提供了减去64的边距(状态栏+导航栏).
我正在从故事板中分配我的约束.我已经尝试了许多其他约束与表视图,如从4个边给出零约束或等宽+等高+中心水平+中心垂直没有一个工作.
解决这个问题的正确方法是什么.
故事板的屏幕截图如下.

我有一个子类UIView,我有,UITextField并希望移动占位符文本一点点.我NSLayoutConstraint用于设置子视图的位置和大小.我已创建UIView并添加它leftView,UITextField但它崩溃说明"视图层次结构没有为约束做好准备".以下是我的代码:
class MasterView: UIView {
let searchTextField = UITextField()
let paddingView = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
searchTextField.placeholder = "Search videos"
searchTextField.translatesAutoresizingMaskIntoConstraints = false
paddingView.translatesAutoresizingMaskIntoConstraints = false
searchTextField.leftView = paddingView
searchTextField.leftViewMode = UITextFieldViewMode.Always
self.addSubview(searchTextField)
}
// Gets called when using storyboard
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
self.addConstraint(NSLayoutConstraint(item: searchTextField, attribute: NSLayoutAttribute.TopMargin, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.TopMargin, …Run Code Online (Sandbox Code Playgroud) 所以,我已经完成了使用IBin Xcode并希望UI在Swift中编写所有内容.
所以我做的是:
UIView的包含我想写的元素 - 让我们称之为"TestView"TestView到a VC作为子视图.在TestView课堂上我添加了这样的元素:
class TestView: UIView {
var someLabel:UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
self.someLabel = UILabel(frame: CGRect(x: self.frame.midX, y: oneSixthHeight, width: 100, height: 22))
self.someLabel.text = "test"
var constraints:[NSLayoutConstraint] = []
self.someLabel.translatesAutoresizingMaskIntoConstraints = false
let rightsideAnchor:NSLayoutConstraint = NSLayoutConstraint(item: self.someLabel, attribute: .Trailing, relatedBy: .Equal, toItem: self, attribute: .Trailing, multiplier: 1, constant: 1)
constraints.append(rightsideAnchor)
NSLayoutConstraint.activateConstraints(constraints)
}
}
Run Code Online (Sandbox Code Playgroud)有了这个,我希望将UILabel它固定在视图的右侧.
但是,我确实收到此错误:
由于未捕获的异常'NSGenericException'而终止应用程序,原因:'无法激活带有项的约束>和>因为它们没有共同的祖先. …
这是一种将子视图固定到UIView实例的方法。请原谅凌乱的代码,我一直在尝试让它工作。
open static func withEmbeddedView(_ view: UIView, andFixedHeight height: CGFloat) -> PMGAlertControllerEmbedComponent {
let base = PMGAlertControllerEmbedComponent(frame: CGRect.zero)
base.addSubview(view)
view.translatesAutoresizingMaskIntoConstraints = false
base.translatesAutoresizingMaskIntoConstraints = false
let left = NSLayoutConstraint(item: view, attribute: .left, relatedBy: .equal, toItem: base, attribute: .left, multiplier: 1, constant: 0)
let right = NSLayoutConstraint(item: view, attribute: .right, relatedBy: .equal, toItem: base, attribute: .right, multiplier: 1, constant: 0)
let top = NSLayoutConstraint(item: view, attribute: .top, relatedBy: .equal, toItem: base, attribute: .top, multiplier: 1, constant: 0)
let bottom …Run Code Online (Sandbox Code Playgroud) 我有三个UIButton,我以编程方式创建了约束,在某些情况下,我删除其中一个UIButton按钮button.removeFromSuperview(),其余两个按钮将根据优先级设置约束。问题是当我删除一个UIButton(buttonWink)时,从 viewLifeCycle 开始viewWillLayoutSubviews,应用程序将在下面一行崩溃
buttonWink.translatesAutoresizingMaskIntoConstraints = false
Run Code Online (Sandbox Code Playgroud)
当然,因为 ButtonWink 已从超级视图中删除,但是我们可以在设置约束之前进行检查:
if buttonWink != nil {
buttonWink.translatesAutoresizingMaskIntoConstraints = false
}
Run Code Online (Sandbox Code Playgroud)
但是通过对每个按钮检查 nil 会使代码变得冗长,有什么方法可以做到这一点吗?我会非常感谢朋友们。
输出 -
我在这里附上我尝试过的完整代码。
import UIKit
class MasterViewController: UIViewController {
@IBOutlet weak var buttonMessage : UIButton!
@IBOutlet weak var buttonLike : UIButton!
@IBOutlet weak var buttonWink : UIButton!
@IBAction func tapsOnLike(_ sender: UIButton) {
sender.removeFromSuperview()
}
@IBAction func tapsOnWink(_ sender: UIButton) {
sender.removeFromSuperview()
}
@IBAction func tapsOnNextButton(){
let vc = …Run Code Online (Sandbox Code Playgroud) 如果我想要一个与iOS 11之前的设备兼容的应用程序,是否需要每个将视图的某些属性链接到self.view的约束的代码,以便遵守safeAreaLayoutGuide?
if #available(iOS 11.0, *) {
NSLayoutConstraint.activate([
theImage.heightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.heightAnchor, multiplier: 0.5)
theImage.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20),
theImage.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -view.frame.width/8)
])
} else {
NSLayoutConstraint.activate([
theImage.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5)
theImage.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20),
theImage.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -view.frame.width/8),
])
}
Run Code Online (Sandbox Code Playgroud) 我uitextview subview在 inputContainerView 中有一个,因为它可能出现在消息传递应用程序中。
以编程方式,在加载uitextview时,初始化 inputContainerView 时设置的高度锚点。当输入更多行文本时,此约束在增加容器高度方面非常有效。
我的目标是uitextview在达到 X 行之后限制其高度,此后键入的任何行都可以滚动。同样,当行数低于最大值时,它会返回到其原始形式 - 不可滚动并根据内容自动调整高度。
经过多次试验和研究,一旦达到最大行数,我就设法获得了注视的高度,但是一旦行数低于最大值,我似乎无法弄清楚如何将其恢复到原始形式。看起来uitextview高度停留在行数达到最大值的高度。
下面是相关代码:
//Container View Initialization, onLoad Frame Height is set to 60
override init(frame: CGRect) {
super.init(frame: frame)
autoresizingMask = .flexibleHeight
addSubview(chatTextView)
textView.heightAnchor.constraint(greaterThanOrEqualToConstant: frame.height - 20).isActive = true
}
//TextView Delegate
var isTextViewOverMaxHeight = false
var textViewMaxHeight: CGFloat = 0.0
func textViewDidChange(_ textView: UITextView) {
let numberOfLines = textView.contentSize.height/(textView.font?.lineHeight)!
if Int(numberOfLines) > 5 {
if !isTextViewOverMaxHeight {
containerView.textView.heightAnchor.constraint(greaterThanOrEqualToConstant: 40).isActive = …Run Code Online (Sandbox Code Playgroud) 如何在Objective C中使用从iOS 9创建的约束?在Swift中,这应该是这样的:
button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
button.heightAnchor.constraint(equalToConstant: 100).isActive = true
Run Code Online (Sandbox Code Playgroud) 我希望将基于Objective-c的通用应用程序转换为Swift项目.到目前为止,我已经能够交换大部分代码,但是我在翻译以下内容时遇到了问题:
NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:self.contentView
attribute:NSLayoutAttributeLeading
relatedBy:0
toItem:self.view
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:0];
[self.view addConstraint:leftConstraint];
NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:self.contentView
attribute:NSLayoutAttributeTrailing
relatedBy:0
toItem:self.view
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:0];
[self.view addConstraint:rightConstraint];
Run Code Online (Sandbox Code Playgroud)
我还必须更改此代码:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
return NO;
}
Run Code Online (Sandbox Code Playgroud)
Swift中有类似的方法吗?
任何帮助将不胜感激.在此先感谢所有回复的人.:)
swift ×9
ios ×8
autolayout ×3
objective-c ×3
constraints ×2
anchor ×1
ios10 ×1
ios11 ×1
ios6 ×1
rubymotion ×1
uitableview ×1
uitextfield ×1
uitextview ×1
uiview ×1
xcode ×1
xcode6 ×1