How to deactivate my constraints?
I hope the following code will help you,
1) declare the global variables
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
}
}
configure textview
func setupSearchTextView(){
searchTextView.frame = CGRect(x: <#T##CGFloat#>, y: <#T##CGFloat#>, width: <#T##CGFloat#>, height: <#T##CGFloat#>)
/*
.
.
.
.
.
.*/
}
3) to activate or deactivate the width constraint based on device orientation use the any one of the below approach (i.e, viewWillLayoutSubviews()
or 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
}
}
Activate/deactivate autolayout NSLayoutConstraints
The solution was that I had to change the priority of both constraints.
Set the constraint you want to use by default to a priority of anything lower then 1000. For instance, 750.
Set the priority of the other constraint to 250. (In Storyboard).
Once you want the second constraint to replace the first one, simply change the priority of the second constraint from 250 to anything higher than 750, and it will magically work.
Activating and Deactivating Constraints Not Updating View Frame
change this
self.view.removeConstraint(constraint1)
to
parentView.removeConstraint(constraint1)
self.view.layoutIfNeeded()
This constraint need to be removed from the parent view of both the label and the button which contains that constraint
Constraint doesn't get deactivated
Couple issues...
1 - many iPhone models only have wC hR
(portrait) and wC hC
(landscape) size classes. So, if you're checking for the .horizontalSizeClass
on those devices it will always be .compact
. You likely want to be checking the .verticalSizeClass
2 - the way you have your code, you are creating NEW constraints every time you call addConstrainsToCenterView()
. You're not activating / deactivating existing constraints.
Take a look at this:
class MyViewController: UIViewController {
var heightSizeClass = UIUserInterfaceSizeClass.unspecified
var centeredView : UIView = {
let view = UIView()
view.backgroundColor = UIColor.systemGreen
return view
}()
// constraints to activate/deactivate
var compactAnchor: NSLayoutConstraint!
var regularAnchor: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(centeredView)
centeredView.translatesAutoresizingMaskIntoConstraints = false
// centeredView is Always centerX and centerY
centeredView.centerXAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.centerXAnchor).isActive = true
centeredView.centerYAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.centerYAnchor).isActive = true
// for a square (1:1 ratio) view, it doesn't matter whether we set
// height == width
// or
// width == height
// so we can set this Active all the time
centeredView.heightAnchor.constraint(equalTo: centeredView.widthAnchor).isActive = true
// create constraints to activate / deactivate
// for regular height, set the width to 4/5ths the width of the view
regularAnchor = centeredView.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 4/5)
// for compact height, set the height to 4/5ths the height of the view
compactAnchor = centeredView.heightAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.heightAnchor, multiplier: 4/5)
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
// use .verticalSizeClass
heightSizeClass = self.traitCollection.verticalSizeClass
updateCenterViewConstraints()
}
func updateCenterViewConstraints() {
if heightSizeClass == .compact {
// if height is compact
regularAnchor.isActive = false
compactAnchor.isActive = true
}
else{
// height is regular
compactAnchor.isActive = false
regularAnchor.isActive = true
}
}
}
With that approach, we create two vars for the constraints we want to activate/deactivate:
// constraints to activate/deactivate
var compactAnchor: NSLayoutConstraint!
var regularAnchor: NSLayoutConstraint!
Then, in viewDidLoad()
, we add centeredView
to the view, set its "non-changing" constraints - centerX, centerY, aspect-ratio - and create the two activate/deactivate constraints.
When we change the size class, we only have to deal with the two var
constraints.
NSLayoutConstraint activate/deactivate
You can try to change the priority of constraint.
For example:
constraint.priority = 0; // it's turn off
constraint.priority = 1000; // it's turn on
Enable + Disable Auto-Layout Constraints
Aha!
Constraints become nil (and thus can't be reactivated), once their active
property is set to false. Making them strong references (thanks, Caleb, for clearing up the nomenclature) preserves them so they can be activated and deactivated as desired.
Programmatically disable auto-layout constraint
When developing for iOS 8.0 or later, just use isActive
property of NSLayoutConstraint
after creating your IBOutlet.
UPDATED
- to have strong reference to the outlet per below suggestion, thank you @rob mayoff.
- to use .isActive instead of .active with Swift 4 per below suggestion, thank you @Mohit Singh.
your cell would have the following outlet:
@IBOutlet var photoBottomConstraint: NSLayoutConstraint!
and you would access the constraint in willDisplayCell
like:
myCell.photoBottomConstraint.isActive = false
and when you need it again:
myCell.photoBottomConstraint.isActive = true
Related Topics
Storyboard View Elements Greyed Out
Synchronous Url Request on Swift 2
Clear Background for Form Sections in Swiftui
Programmatically Scroll a Uiscrollview
Adjust Uibutton Font Size to Width
Autolayout: Add Constraint to Superview and Not Top Layout Guide
iOS 11 - Keyboard Height Is Returning 0 in Keyboard Notification
How to Use Addtarget Method in Swift 3
What Describes the Application Delegate Best? How Does It Fit into the Whole Concept
Uicollectionview - Diddeselectitematindexpath Not Called If Cell Is Selected
iOS - How to Play a Video with Transparency
How to Use Core Location/Gps Without Any Internet Connection/Disabled Cellular Network
Can Not Save File Inside Tmp Directory
How to Create a New Swift Project Without Using Storyboards
Objective-C 101 (Retain VS Assign) Nsstring
How to Apply Multiple Transforms in Swift
Uiapplication.Registerforremotenotifications() Must Be Called from Main Thread Only