如何停用我的约束?
Posted
技术标签:
【中文标题】如何停用我的约束?【英文标题】:How to deactivate my constraints? 【发布时间】:2018-02-07 04:52:21 【问题描述】:我在 swift 中以编程方式创建了一个 UITextView,这就是我在 viewDidLoad() 中为我的控制器所拥有的。
let isPortrait = UIInterfaceOrientationIsPortrait(UIApplication.shared.statusBarOrientation)
if isPortrait
searchTextView.widthAnchor.constraint(equalToConstant: view.frame.width * 0.7).isActive = true
else
searchTextView.widthAnchor.constraint(equalToConstant: view.frame.width * 0.1).isActive = true
这就是 searchTextView 的设置方式
func setupView()
self.layer.cornerRadius = 8.0
self.translatesAutoresizingMaskIntoConstraints = false
self.textContainerInset = UIEdgeInsets(top: 12, left: 10, bottom: 0, right: 10)
self.textContainer.maximumNumberOfLines = 1
self.textContainer.lineBreakMode = .byTruncatingHead
self.autocorrectionType = .no
self.text = ""
self.font = Constants.fonts().largeFont
self.backgroundColor = UIColor.white
self.adjustsFontForContentSizeCategory = true
self.textColor = UIColor.black
self.layer.borderColor = UIColor.gray.cgColor
self.layer.borderWidth = 0.25
// Need clipsToBounds = false to show shadow
self.clipsToBounds = false
self.layer.shadowRadius = 20.0
self.layer.shadowColor = UIColor.gray.cgColor
self.layer.shadowOffset = CGSize(width: 2.0, height: 2.0)
self.layer.shadowOpacity = 0.5
self.tintColor = Constants.colors().primaryLightColor
这会根据设备方向为 searchTextView 提供不同的 widthAnchor。这很好用,但是,稍后我会检查设备方向何时会更改并删除并添加相应的 widthAnchors。
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
sideMenuLauncher.dismissSideMenu(duration: 0)
let toPortraitMode = self.view.frame.size.width > size.width
searchTextView.widthAnchor.constraint(equalToConstant: view.frame.width * 0.7).isActive = toPortraitMode
searchTextView.widthAnchor.constraint(equalToConstant: size.width * 0.1).isActive = !toPortraitMode
for constraint in view.constraints
print("\(constraint)\n")
searchTextView.updateConstraints()
searchTextView.layoutIfNeeded()
但这实际上并没有停用任何约束,正如它在此控制台输出中所说:
(
"<NSLayoutConstraint:0x60c000896170 PickupApp.SearchBarView:0x7f7ee1016a00.width == 56.8 (active)>",
"<NSLayoutConstraint:0x604000c9c6b0 PickupApp.SearchBarView:0x7f7ee1016a00.width == 397.6 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x604000c9c6b0 PickupApp.SearchBarView:0x7f7ee1016a00.width == 397.6 (active)>
我不明白为什么即使添加了约束也没有停用这些约束。
【问题讨论】:
When can I activate/deactivate layout constraints?的可能重复 @HarshalValanda 我相信该帖子是使用@IBOutlets
回答的,这需要使用情节提要,但我不使用情节提要。
【参考方案1】:
希望下面的代码对你有帮助,
1) 声明全局变量
var searchTextViewPortraitWidthConstraint: NSLayoutConstraint?
var searchTextViewLandscapeWidthConstraint: NSLayoutConstraint?
let searchTextView = UITextView()
2) viewDidLoad()
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
setupSearchTextView()
let isPortrait = UIInterfaceOrientationIsPortrait(UIApplication.shared.statusBarOrientation)
if isPortrait
searchTextViewPortraitWidthConstraint = searchTextView.widthAnchor.constraint(equalToConstant: view.frame.width * 0.7)
searchTextViewLandscapeWidthConstraint = searchTextView.widthAnchor.constraint(equalToConstant: view.frame.width * 0.1)
searchTextViewPortraitWidthConstraint?.isActive = true
else
searchTextViewLandscapeWidthConstraint = searchTextView.widthAnchor.constraint(equalToConstant: view.frame.width * 0.1)
searchTextViewPortraitWidthConstraint = searchTextView.widthAnchor.constraint(equalToConstant: view.frame.width * 0.7)
searchTextViewLandscapeWidthConstraint?.isActive = true
配置文本视图
func setupSearchTextView()
searchTextView.frame = CGRect(x: <#T##CGFloat#>, y: <#T##CGFloat#>, width: <#T##CGFloat#>, height: <#T##CGFloat#>)
/*
.
.
.
.
.
.*/
3) 要根据设备方向激活或停用宽度约束,请使用以下任一方法(即viewWillLayoutSubviews()
或viewDidLayoutSubviews()
)。
override func viewWillLayoutSubviews()
super.viewWillLayoutSubviews()
let isPortrait = UIInterfaceOrientationIsPortrait(UIApplication.shared.statusBarOrientation)
if isPortrait
searchTextViewPortraitWidthConstraint?.isActive = true
searchTextViewLandscapeWidthConstraint?.isActive = false
else
searchTextViewPortraitWidthConstraint?.isActive = false
searchTextViewLandscapeWidthConstraint?.isActive = true
override func viewDidLayoutSubviews()
super.viewDidLayoutSubviews()
let isPortrait = UIInterfaceOrientationIsPortrait(UIApplication.shared.statusBarOrientation)
if isPortrait
searchTextViewPortraitWidthConstraint?.isActive = true
searchTextViewLandscapeWidthConstraint?.isActive = false
else
searchTextViewPortraitWidthConstraint?.isActive = false
searchTextViewLandscapeWidthConstraint?.isActive = true
【讨论】:
谢谢!您的代码进行了一次更改。在代码块 #2 中,我必须将searchTextViewPortraitWidthConstraint
和 searchTextViewLandscapeWidthConstraint
都设置为 if
和 else
中的约束值。如果没有这个改变,当设备旋转时,searchTextView 似乎根本没有宽度。
@SiddhaTiwari 是的,这是很好的识别,我也更新了我的答案。【参考方案2】:
searchTextView.translatesAutoresizingMaskIntoConstraints = false
【讨论】:
【参考方案3】:您需要存储该约束以便稍后将其停用。
取一个全局变量来存储约束。
var cons:NSLayoutConstraint?
如下更改 viewDidLoad() 以便稍后访问相同的约束:
override func viewDidLoad()
super.viewDidLoad()
let isPortrait = UIInterfaceOrientationIsPortrait(UIApplication.shared.statusBarOrientation)
if isPortrait
self.cons = searchTextView.widthAnchor.constraint(equalToConstant: view.frame.width * 0.7)
else
self.cons = searchTextView.widthAnchor.constraint(equalToConstant: view.frame.width * 0.1)
self.cons?.isActive = true
【讨论】:
以上是关于如何停用我的约束?的主要内容,如果未能解决你的问题,请参考以下文章
如何强制 uitableview 调整单元格的大小(在停用高度约束后)?
UICollectionReusableView 约束未更新