iOS view visibility gone
Solution 1
As I have worked on both iOS & Android, You need to play with constraint outlet in ios to achieve Android functioning. iOS Does not support automatically like Android native support on visibility GONE
& VISIBLE
You need to hook the outlet
of particular constraint
(it may vertical/horizontal/height) you need to set it to 0
& need to manage your UI.
To Hide:
self.viewYourConstraint.constant = 0
self.yourView.hidden = true
self.view.layoutIfNeeded()
To Show:
self.viewYourConstraint.constant = 100//your constant value
self.yourView.hidden = false
self.view.layoutIfNeeded()
Note: If other constraints will be affected because of the update to the constraint above, the following must also need to be called:
self.yourView.setNeedsUpdateConstraints()
Cheers
Solution 2
Try this extension:
extension UIView {
func visiblity(gone: Bool, dimension: CGFloat = 0.0, attribute: NSLayoutAttribute = .height) -> Void {
if let constraint = (self.constraints.filter{$0.firstAttribute == attribute}.first) {
constraint.constant = gone ? 0.0 : dimension
self.layoutIfNeeded()
self.isHidden = gone
}
}
}
// How you can use this....
@IBOutlet weak var testView: UIView?
@IBAction func testVisibilty(switchbutton: UISwitch) -> Void {
let viewHeight:CGFloat = switchbutton.isOn ? 100 : 0.0
self.testView?.visiblity(gone: !switchbutton.isOn, dimension: viewHeight)
// set visibility for width constraint
//let viewWidth:CGFloat = switchbutton.isOn ? 300 : 0.0
//self.testView?.visiblity(gone: !switchbutton.isOn, dimension: viewWidth, attribute: .width)
}
Here is result:
Solution 3
Maybe you'd prefer this solution
extension UIView {
enum Visibility {
case visible
case invisible
case gone
}
var visibility: Visibility {
get {
let constraint = (self.constraints.filter{$0.firstAttribute == .height && $0.constant == 0}.first)
if let constraint = constraint, constraint.isActive {
return .gone
} else {
return self.isHidden ? .invisible : .visible
}
}
set {
if self.visibility != newValue {
self.setVisibility(newValue)
}
}
}
private func setVisibility(_ visibility: Visibility) {
let constraint = (self.constraints.filter{$0.firstAttribute == .height && $0.constant == 0}.first)
switch visibility {
case .visible:
constraint?.isActive = false
self.isHidden = false
break
case .invisible:
constraint?.isActive = false
self.isHidden = true
break
case .gone:
if let constraint = constraint {
constraint.isActive = true
} else {
let constraint = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: 0)
self.addConstraint(constraint)
constraint.isActive = true
}
}
}
}
then the usage is:
someView.visibility = .visible
someView.visibility = .invisible
someView.visibility = .gone
edit:
improving capabilities: will work from storyboard (just write: 'visible', 'invisible', 'gone') in the "Visibility State"
all constraints inside view should be less then a 1000
extension UIView {
enum Visibility: String {
case visible = "visible"
case invisible = "invisible"
case gone = "gone"
}
var visibility: Visibility {
get {
let constraint = (self.constraints.filter{$0.firstAttribute == .height && $0.constant == 0}.first)
if let constraint = constraint, constraint.isActive {
return .gone
} else {
return self.isHidden ? .invisible : .visible
}
}
set {
if self.visibility != newValue {
self.setVisibility(newValue)
}
}
}
@IBInspectable
var visibilityState: String {
get {
return self.visibility.rawValue
}
set {
let _visibility = Visibility(rawValue: newValue)!
self.visibility = _visibility
}
}
private func setVisibility(_ visibility: Visibility) {
let constraints = self.constraints.filter({$0.firstAttribute == .height && $0.constant == 0 && $0.secondItem == nil && ($0.firstItem as? UIView) == self})
let constraint = (constraints.first)
switch visibility {
case .visible:
constraint?.isActive = false
self.isHidden = false
break
case .invisible:
constraint?.isActive = false
self.isHidden = true
break
case .gone:
self.isHidden = true
if let constraint = constraint {
constraint.isActive = true
} else {
let constraint = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: 0)
// constraint.priority = UILayoutPriority(rawValue: 999)
self.addConstraint(constraint)
constraint.isActive = true
}
self.setNeedsLayout()
self.setNeedsUpdateConstraints()
}
}
}
Solution 4
You say you want to hide your subview and remove the space it occupies. If you want to avoid messing with constraints, you can try using stack views:
- Create a
UIStackView
and setup appropriate constraints between the stack view and its parent view; - Add views to the stack view;
- Now you can toggle the visibility of these views inside the stack view by setting
view.isHidden
to true or false, and the layout will adjust automatically.
Solution 5
I believe you are looking for view.isHidden = true
. This simply hides the view in place without altering the view hierarchy or constraint mapping. You can subsequently re-show your view . with view.isHidden = false
.
John
Updated on February 18, 2020Comments
-
John about 4 years
I am new to iOS development.I want to toggle (hide/visible) a subview from parent view.In android there is a way to hide the visibility to gone.
In android
subView.setVisibility(View.GONE);
In iOS
subView.removeFromSuperview()
when i use above function it remove subViewConstraints and mess up my scroll view constraints.
topsubView.bottomAnchor.constraint(equalTo: bottomSubView.topAnchor, constant: 8).isActive = true
when i use the above code it works fine and hide subView.but when i want to make subView visible,it is not showing the subView.
topsubView.bottomAnchor.constraint(equalTo: bottomSubView.topAnchor, constant: 8).isActive = false self.view.layoutIfNeeded()
Hope you understand my problem.Thanks in Advance.
-
John about 6 yearsThanks but i want to remove the space of the subView also
-
Naveed Ahmad over 5 yearswhy properties are reset by this exension
-
sandpat over 5 yearsWhat If the views don't have constant spacing?
-
C. Kontos over 4 yearsIs the hidden part necessary when you are setting the height constraint to 0?
-
Mukesh Lokare over 4 yearsThats how it work in iOS, gone feature is not available on IOS. Somehow even you remove view from superview then you will have to create that view again then..
-
C. Kontos over 4 yearsWell I have similar code without using
self.yourView.hidden = true
and everything works fine since I am making the view's height constraint equal to 0 when I want it hidden. -
Mukesh Lokare over 4 yearsYes, thats true, But the best practices in the iOS is we should have to make view hidden as well.
-
Pelanes over 3 yearsThis is the quickest and easiest solution, but maybe is not the best for all cases! @sandpat you just need to set the view inside stack with no fixed size, and two constraints for the top and bottom (or lead and trail) of the views inside this view.
-
Ashraf Amin about 2 yearsBravo tqvm. Worked for iOS newbie like me. Thumbs up !