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.
A View's visibility status is of Integer type and can have one of three options: VISIBLE (0) - The View is visible to the user. INVISIBLE (4) - The View is invisible to the user, but still takes up space in the layout. GONE (8) - The View is invisible, and it does not take up space in the layout.
When a View is gone, it means it doesn't take any space in the layout. When it is invisible, it will take the necessary room in a layout but you just don't see it.
The view's window property is non-nil if a view is currently visible, so check the main view in the view controller: Invoking the view method causes the view to load (if it is not loaded) which is unnecessary and may be undesirable. It would be better to check first to see if it is already loaded.
From Android official documentation, View. GONE This view is invisible, and it doesn't take any space for layout purposes. View. INVISIBLE This view is invisible, but it still takes up space for layout purposes.
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()
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:
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()
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With