在下面的代码中:
我有5个按钮添加到垂直的scrollView中。每个按钮都限于scrollViews的顶部+ 20,前缘,后缘及其高度。我创建了一个b1HeightConstraint
变量。在这里可以保存b1
按钮的heightConstraint。
在单击按钮时,我试图删除此约束。但是我面临一个奇怪的问题:
当我记录约束时,即使我添加了4个约束,我也只看到2个约束。我的视图调试层次结构如下:
import UIKit
import Foundation
class ViewController: UIViewController {
var filterView: UIView!
var scrollView: UIScrollView!
var containerView: UIView!
override func loadView() {
filterView = UIView()
view = filterView
view.backgroundColor = #colorLiteral(red: 0.909803926944733, green: 0.47843137383461, blue: 0.643137276172638, alpha: 1.0)
scrollView = UIScrollView()
scrollView.backgroundColor = #colorLiteral(red: 0.474509805440903, green: 0.839215695858002, blue: 0.976470589637756, alpha: 1.0)
view.addSubview(scrollView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
scrollView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 1).isActive = true
scrollView.isScrollEnabled = true
containerView = UIView()
containerView.backgroundColor = #colorLiteral(red: 0.176470592617989, green: 0.498039215803146, blue: 0.756862759590149, alpha: 1.0)
scrollView.addSubview(containerView)
containerView.translatesAutoresizingMaskIntoConstraints = false
// This is key: connect all four edges of the containerView to
// to the edges of the scrollView
containerView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
containerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
containerView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
// Making containerView and scrollView the same height means the
// content will not scroll vertically
containerView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
}
let b1 = Buttons(titleText: "one")
let b2 = Buttons(titleText: "two")
let b3 = Buttons(titleText: "three")
let b4 = Buttons(titleText: "four")
let b5 = Buttons(titleText: "five")
var b1HeightConstraint : NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
let buttonArray = [b1, b2, b3, b4, b5]
b1.button.addTarget(self, action: #selector(ViewController.shrink(_:)), for: .touchUpInside)
var startPoint = containerView.topAnchor
for btn in buttonArray {
let theBtn = btn.button
containerView.addSubview(theBtn)
theBtn.translatesAutoresizingMaskIntoConstraints = false
theBtn.topAnchor.constraint(equalTo: startPoint, constant: 20).isActive = true
theBtn.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
theBtn.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
theBtn.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true
startPoint = theBtn.bottomAnchor
let btnHeight = theBtn.heightAnchor.constraint(equalTo: scrollView.heightAnchor)
if btn == b1{
b1HeightConstraint = btnHeight
}
}
containerView.bottomAnchor.constraint(equalTo: startPoint, constant: 20).isActive = true
}
@objc func shrink(_ sender: Any){
guard let btn = sender as? UIButton else{
return
}
print("count is: \(btn.constraints.count)")
btn.removeConstraint(b1HeightConstraint!)
containerView.removeConstraint(b1HeightConstraint!)
print("count is: \(btn.constraints.count)")
containerView.updateConstraintsIfNeeded()
containerView.updateConstraints()
scrollView.updateConstraintsIfNeeded()
scrollView.updateConstraints()
}
}
class Buttons : NSObject {
let button = UIButton()
init(titleText: String) {
button.backgroundColor = #colorLiteral(red: 0.976470589637756, green: 0.850980401039124, blue: 0.549019634723663, alpha: 1.0)
button.setTitle(titleText, for: .normal)
}
}
代码已经准备好被转储到ViewController类中。开箱即用。我的代码是here
的代码的一部分答案 0 :(得分:7)
以下是关于您的代码的几点注释:
removeConstraint
时请勿致电addConstraint
)。您对约束的控制是激活和停用。将添加和删除留在iOS上。这些代码行:
let btnHeight = theBtn.heightAnchor.constraint(equalTo: scrollView.heightAnchor)
if btn == b1{
b1HeightConstraint = btnHeight
}
正在创建一个新约束并将其分配给b1HeightConstraint
,但是您从未激活此约束,因此根本没有将其添加到任何视图中。因此,尝试删除它永远不会起作用,因为该约束仅存在于您的b1HeightConstraint
属性中。由于它从未被激活过,因此实际上并没有约束任何东西。
如果要收缩按钮,则需要执行以下操作之一:a)修改其高度约束的constant
属性 OR b)设置其高度约束的将isActive
属性的false
设置为self.height = 34 (content size)
,然后为其赋予新的高度约束 OR c)修改活动约束的优先级,以使 Auto Layout 选择使用不同的约束条件。
在您的视图调试层次结构中,所有显示的约束都是活动约束(这意味着它们可以由 Auto Layout 使用)。灰色的是自动布局不选择使用的,因为优先级较高的约束优先于此。这不会引起冲突。系统添加了UIButton
约束,以解决内容压缩和内容拥抱。 750
抵抗优先级为250
的压缩,并抵抗优先级为self.height = 34 (content size)
的扩展。 250
约束显示为灰色,因为内容拥抱的优先级为1000
,并且使用了另一个更高优先级的约束(将按钮的高度设置为等于scrollView的高度的约束具有优先级b1HeightConstraint
)。
更新的代码:
这是您修改的代码。我改变了两件事:
shrink
是激活的约束。import UIKit
import Foundation
class ViewController: UIViewController {
var filterView: UIView!
var scrollView: UIScrollView!
var containerView: UIView!
override func loadView() {
filterView = UIView()
view = filterView
view.backgroundColor = #colorLiteral(red: 0.909803926944733, green: 0.47843137383461, blue: 0.643137276172638, alpha: 1.0)
scrollView = UIScrollView()
scrollView.backgroundColor = #colorLiteral(red: 0.474509805440903, green: 0.839215695858002, blue: 0.976470589637756, alpha: 1.0)
view.addSubview(scrollView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
scrollView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 1).isActive = true
scrollView.isScrollEnabled = true
containerView = UIView()
containerView.backgroundColor = #colorLiteral(red: 0.176470592617989, green: 0.498039215803146, blue: 0.756862759590149, alpha: 1.0)
scrollView.addSubview(containerView)
containerView.translatesAutoresizingMaskIntoConstraints = false
// This is key: connect all four edges of the containerView to
// to the edges of the scrollView
containerView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
containerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
containerView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
// Making containerView and scrollView the same height means the
// content will not scroll vertically
containerView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
}
let b1 = Buttons(titleText: "one")
let b2 = Buttons(titleText: "two")
let b3 = Buttons(titleText: "three")
let b4 = Buttons(titleText: "four")
let b5 = Buttons(titleText: "five")
var b1HeightConstraint : NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
let buttonArray = [b1, b2, b3, b4, b5]
b1.button.addTarget(self, action: #selector(ViewController.shrink(_:)), for: .touchUpInside)
var startPoint = containerView.topAnchor
for btn in buttonArray {
let theBtn = btn.button
containerView.addSubview(theBtn)
theBtn.translatesAutoresizingMaskIntoConstraints = false
theBtn.topAnchor.constraint(equalTo: startPoint, constant: 20).isActive = true
theBtn.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
theBtn.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
//theBtn.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true
startPoint = theBtn.bottomAnchor
let btnHeight = theBtn.heightAnchor.constraint(equalTo: scrollView.heightAnchor)
btnHeight.isActive = true
if btn == b1{
b1HeightConstraint = btnHeight
}
}
containerView.bottomAnchor.constraint(equalTo: startPoint, constant: 20).isActive = true
}
@objc func shrink(_ sender: UIButton) {
b1HeightConstraint?.isActive = false
b1HeightConstraint = sender.heightAnchor.constraint(equalToConstant: 20)
b1HeightConstraint?.isActive = true
}
}
class Buttons : NSObject {
let button = UIButton()
init(titleText: String) {
button.backgroundColor = #colorLiteral(red: 0.976470589637756, green: 0.850980401039124, blue: 0.549019634723663, alpha: 1.0)
button.setTitle(titleText, for: .normal)
}
}
方法以停用旧的高度限制,然后创建并激活一个新的高度限制。更新的代码
constant
缩小按钮高度的选项
设置高度约束的// shrink button's height by 200 points
b1HeightConstraint?.constant -= 200
属性
// make button height 20 points
b1HeightConstraint?.isActive = false
b1HeightConstraint = sender.heightAnchor.constraint(equalToConstant: 20)
b1HeightConstraint?.isActive = true
停用旧约束并创建并激活新约束
// Set b1HeightConstraint's priority to less than 250, and the
// *content hugging* with priority 250 will take over and resize
// the button to its intrinsic height
b1HeightConstraint?.priority = UILayoutPriority(rawValue: 100)
更改高度限制的优先级
1000
注意:要使此方法起作用,您必须给高度约束一个小于999
的初始优先级(1000
工作得很好),因为 Auto Layout 不会让您如果需要,请更改活动约束的优先级(优先级// Just deactivate the buttonHeight constraint and the *content
// hugging* will take over and it will set the button's height
// to its intrinsic height
b1HeightConstraint?.isActive = false
)。
OR
@IBOutlet fileprivate weak var tblVw: UITableView!
private var gradientLayer = CAGradientLayer()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if gradientLayer.superlayer != nil {
gradientLayer.removeFromSuperlayer()
}
let topColor = UIColor(red: 16.0/255.0, green: 12.0/255.0, blue: 54.0/255.0, alpha: 1.0)
let bottomColor = UIColor(red: 57.0/255.0, green: 33.0/255.0, blue: 61.0/255.0, alpha: 1.0)
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
gradientLayer.colors = [topColor.cgColor, bottomColor.cgColor]
gradientLayer.frame = tblVw.bounds
let backgroundView = UIView(frame: tblVw.bounds)
backgroundView.layer.insertSublayer(gradientLayer, at: 0)
tblVw.backgroundView = backgroundView
}
答案 1 :(得分:1)
这是因为视图和其superView之间的约束已添加到superView中,只有将高度/宽度约束静态添加到let arr = new Array();
object1 = {
"Username" : "Jhon",
"Console" : "xbox",
"Pseudo" : "asd",
}
arr.push(object1)
object2 = {
"Username" : "Doe",
"Console" : "ps4",
"Pseudo" : "efg",
}
arr.push(object2)
console.log(arr);
时,您才能看到高度/宽度约束,请查阅Vandad IOS Book的该图>
查看此Demo