Unable to occupy hidden view space in swift - swift

I have 3 view View A , View B and Table view where View A is optional.
i.e. Only authenticated person can interact with View A.
So i have hided the View A for unauthenticated user by
viewA.isHidden = true
But this view is still taking space. What i want is if View A is hidden, Allow View B and table view take view A Space.
what I want is show in below pic.

Well, you should have to add two constraint
vertical space from view B to View A with constant = 10 and priority = 999 (high)
top space from view B to safe area with constant = 10 and priority = 750 (low)
the constraint which has higher priority is considered first. Add outlet connection to the ViewController.
when you want to hide view A then change the priority of second constraint to 999(high) and first constraint to 750(low) programatically.
constaraint.priority = UILayoutPriority(rawValue: 750)

Related

UIKitCore layoutGuides deadlock

I am creating a popup menu. It has a UIPresentationController that calculates frameOfPresentedViewInContainerView based on presented view controller's view size before showing it.
Presented view controllers consist of the fixed height outer (navigation) view controller embedding some dynamic height inner (content) view controller;
Inner view controllers, under the hood, have UIStackView wrapped in a UIScrollView;
Before calculating size of inner view controller I am calling layoutIfNeeded() on it.
The problem occurred only on devices with the notch (I blame safeAreaLayout) and only with a UIStackView-based inner view controllers. When layoutIfNeeded() called on presented controller (e.x. when display orientation change, content size change, or presented second time) UIKitCore goes into an infinite loop calling -[UIView layoutGuides]. It doesn't crash the app, but use 100% of the main thread and freezes the UI(sometimes whole phone to the point you need make a hard reset), consuming about 10Mb of memory every second.
I was able to fix it by adding 1 extra point to a calculated height of the frameOfPresentedViewInContainerView. This sounds like an awful fix, so I am trying to better understand the problem.
I would be glad if someone with a deep understanding of UIKit could point me to a better strategy on how to debug/investigate the issue.
UPDATE
Seems like UIScrollView having hard time positioning content due to a safeArea. UIKitCore keeps repeating those 5 lines:
- [UIScrollView _layoutGuideOfType:createIfNecessary:]
- [NSISEngine(_UILayoutEngineStatistics)_UIKitPerformPendingChangeNotifications]
- [UIView layoutGuides]
- [_UIScrollViewScrollIndicator _layoutFillViewAnimated:]
- [UIView(AdditionalLayoutSupport) nsli_lowerAttribute:intoExpression:withCoefficient:forConstraint:onBehalfOfLayoutGuide:]
I also have
runtime: Layout Issues: Scrollable content size is ambiguous for UIScrollView.
I was able to fix my issue by specifically attaching UIScrollView to the bottom of safeAreaLayoutGuide.
var bottomConstraint = formView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
if #available(iOS 11.0, *) {
bottomConstraint = formView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
}

Change height of one of multiple fields in stack view

In my code I have a stack view that initially has 1 element PhoneNumberField. Another PhoneNumberFieldscan be added dynamically in the runtime:
#IBAction func addAlternatePhoneNumberAction(_ sender: UIButton) {
let alternateNumberView = PhoneNumberField()
...
phoneNumberStackView.addArrangedSubview(alternateNumberView)
}
This is what xib for PhoneNumberFieldlooks like:
The problem is that I would like to be able to dynamically hide the 'Name for other phone' field based on the content of 'Mobile combobox'. When I set the 'isHidden' parameter everything works as expected, the only problem is that the PhoneNumberField height stays the same. I would like it to shrink when the 'Name for other phone' field is hidden.
I tried doing it using the outlet for height constant for otherNumberNameField in the PhoneNumberField.swift file but the problem is that in that case all of the PhoneNumberFields in the stack view have the size of the first field.
What would be the correct solution for this?
edit: In addition to the answer below: I had to set the distribution for the phoneNumberStackView to equal spacing. Worked like a charm.
First, create StackView.
Don't set its height constraint, just set top, leading, trailing and bottom constraints.
Bottom constraint set equal to Error label top constraint.
Then set its distribution to Fill Equally.
Now put first two Views into one view and put this view together with OtherNumberField view to this StackView.
So now your hierarchy should look like this:
Now when you hide one view from StackView, StackView will be smaller because you didn't set its height.

how to remove a view from stackview and distribute the other fillequally

i have a stackview desing in storyboard with 5 view inside composed of 1 buttom, a small view with a label and a button. like this.
what i want is to remove one of the the view let say the one with orange background.
i tried this on viewdidload
stackview.view2.isHiden = true
stackview.view2.removeFromSuperview()
this remove the view and all elements but the remaing does not distribute as expected any idea how to achive this
// Appears to remove the first arranged view from the stack.
// The view is still inside the stack, it's just no longer visible, and no longer contributes to the layout.
let firstView = stackView.arrangedSubviews[0]
firstView.isHidden = true

Table View don't bounce

My question is :
Why when I build and run the Table View created with different rows don't bounce, although I selected the checkbox Bounces and Bounce Vertically in Xcode 6 ?
By default UIScrollView, which is a superclass of UITableView won't bounce if the content fits within its bounds i.e. if the rows fit within table's bounds.
To alter this behaviour you can set alwaysBounceVertical property to true.
var alwaysBounceVertical: Bool { get set }
If this property is set to true and bounces is true, vertical dragging
is allowed even if the content is smaller than the bounds of the
scroll view. The default value is false.
Try this code:
[eventTable setBounces:NO];
(OR)In Storyboard untick the Bounces.

UICollectionView section index

If while scrolling header section in UICollectionview rose above navigationitem how can I know the index of the header section which is not visible?
You can use view.window property if its nil it means its not visible.
Since Collection view re-uses views you would like to check which last header view is visible
instead and subtract one .
1) For the UIViews which are visible get the min index.
2) All the view above it are not visible.