View doesn't appear after changing the view property 'isHidden = false' - ios

I'm developing an iOS application and then the issue that I have faced now is showing a view using the view property isHidden.
I initialized a custom view including a CAAnimation and then set the default isHidden property true to hide. After a certain condition meets I changed the isHidden property to false to show it. But in this case the view doesn't appear.
private func setupButtonEffectView() {
self.buttonEffectView = ButtonEffectView()
self.buttonEffectView!.translatesAutoresizingMaskIntoConstraints = false
// self.view.addSubview(self.buttonEffectView!)
self.view.insertSubview(self.buttonEffectView!, belowSubview: self.button!)
NSLayoutConstraint.activate([
self.buttonEffectView!.centerXAnchor.constraint(equalTo: self.button!.centerXAnchor),
self.buttonEffectView!.centerYAnchor.constraint(equalTo: self.button!.centerYAnchor),
self.buttonEffectView!.widthAnchor.constraint(equalToConstant: 100),
self.buttonEffectView!.heightAnchor.constraint(equalToConstant: 100)
])
self.buttonEffectView!.isHidden = true
}
I created the button effect using the method above.

Try instead of hiding the view, setting the alpha to 0.0. self.buttonEffectView.alpha = 0.0. Then when you want to show it set the alpha to 1.0.

Related

UISplitViewController - Expand & Collapse Master View in iPad Portrait

My universal app displays both master and detail views in iPad with preferredDisplayMode = .allVisible. I need to expand the master view into full screen and hide the detail view on a button click. I know there is functionality to expand detail into full screen hiding master. But couldn't find how to expand and collapse master view.
I tried in expand function as below.
self.splitViewController.preferredPrimaryColumnWidthFraction = 1.0
self.splitViewController.maximumPrimaryColumnWidth = self.splitViewController.view.bounds.size.width as! CGFloat
And collapse function as below.
self.splitViewController.preferredDisplayMode = .allVisible
self.splitViewController.preferredPrimaryColumnWidthFraction = 0.6
self.splitViewController.maximumPrimaryColumnWidth = self.splitViewController.view.bounds.size.width as! CGFloat
But they don't work. Any ideas on how to achieve this?
My setup uses a navigation bar, but the show/hide functionality would probably work without it. What I wanted to achieve is to have the user decide whether to show the "primary" view and have it shown no matter the orientation - something a UISplitViewController doesn't natively do.
I achieved this through activating/deactivating two arrays of constraints, pinning the secondary" view's leading anchor to the "primary's" trailing anchor. From there, all the constraint changes are with the "primary" view.
(I'm using quotation marks because these view's actually have much more logic that a UIView should have, so they are each UIViewControllers with one being a child of the other, but the constraints are view-related.)
Let's start with the static constraints:
primary.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
primary.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
primary.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
secondary.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
secondary.leadingAnchor.constraint(equalTo: toolBar.trailingAnchor).isActive = true
secondaary.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
secondary.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
Next, define/populate the two arrays that will show/hide the primary:
var isShowingPrimary = false
var showPrimary = [NSLayoutConstraint]()
var hidePrimary = [NSLayoutConstraint]()
showPrimary.append(primary.widthAnchor.constraint(equalToConstant: 300))
hidePrimary.append(primary.widthAnchor.constraint(equalToConstant: 0))
NSLayoutConstraint.activate(hidePrimary)
Notice that isActive is true for the static constraints, and I activated the hidePrimary constraints only.
Now all you need to do is wire up a UIBarButtonItem or UIButton to execute a toggle function that will show/hide the primary view, along with animating it:
func togglePrimary() {
if isShowingPrimary {
// hide primary view
NSLayoutConstraint.deactivate(showPrimary)
NSLayoutConstraint.activate(hidePrimary)
} else {
// show primary view
NSLayoutConstraint.deactivate(hidePrimary)
NSLayoutConstraint.activate(showPrimary)
}
// toggle flag and animate changes
isShowingPrimary.toggle()
UIView.animate(withDuration: 0.3) { self.view.layoutIfNeeded() }
}

Make View visible outside TableViewCell

Is it possible to have a view inside a tableViewCell and make it visible even outside the tableView-frame?
I would need this for an animation. I tried setting clipsToBounde = false but that didn't solve the issue. The view is still cut outside the tableViewFrame.
My view inside tableViewCell:
func setupLoadingAnimation(){
successAnimation.translatesAutoresizingMaskIntoConstraints = false
successAnimation.clipsToBounds = false
self.contentView.addSubview(successAnimation)
successAnimation.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: -60).isActive = true
successAnimation.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
successAnimation.widthAnchor.constraint(equalToConstant: 160).isActive = true
successAnimation.heightAnchor.constraint(equalToConstant: 160).isActive = true
successAnimation.isHidden = true
successAnimation.loopMode = .playOnce
}
You'll need to make sure all views in the hierarchy have their clipping set to false. Start with the superview of successAnimation and go up through the hierarchy, this will include the cell's contentView and the table view itself.
Another thing you'll have to look for is that views that are added to the hierarchy later will show on top of others if they are at the same level, and since a table view manages its cells it's hard to know which cells are going to overlap your animation.
To fix this you could call bringSubviewToFront() on your table view and pass the cell, I would do this right before executing the success animation.
Another alternative would be to place the table and success views in a shared parent, that way you only have to make sure that the success view is above the table view once, when you add the views.

Can layoutIfNeeded be called only once per loading the view - e.g. viewDidLoad?

A view's height in my view controller needs to change as the user interacts with the application. Sometimes the view needs to be larger in height and other times it needs to be shorter depending on the number of options a user has.
I have implemented a method to change the height depending on the state of the view, and I call this method in viewDidLoad to set the initial state, and I recall the method whenever the state changes.
However, the only time the view actually updates the layout is from the call in viewDidLoad. All other calls of my method do not update the view.
func updateContainerViewHeight(constant: CGFloat) {
print("lets update")
baseView.heightAnchor.constraint(equalToConstant: constant).isActive = true
containerView.heightAnchor.constraint(equalToConstant: constant).isActive = true
self.view.setNeedsLayout()
UIView.animate(withDuration: 0.25) {
self.view.layoutIfNeeded()
}
}
FYI print("let's update") is printing in the console.
As here
baseView.heightAnchor.constraint(equalToConstant: constant).isActive = true
containerView.heightAnchor.constraint(equalToConstant: constant).isActive = true
every call adds new constraints which will cause conflicts , so create
1-
var baseCon,containCon:NSLayoutConstraint!
2-
baseCon = baseView.heightAnchor.constraint(equalToConstant: constant)
baseCon.isActive = true
containCon = containerView.heightAnchor.constraint(equalToConstant: constant)
containCo.isActive = true
3- Then play with constant
baseCon.constant = ////

How to show MapKit compass?

Currently the compass only get's shown if a User applies a rotate-gesture. Otherwise the compass is hidden.
But it would be nice if my two wishes below were fulfilled!
Is it possible to display the compass always?
How to show / hide the compass-view using Swift?
You can do this quite easily in iOS 11 by using the new MKCompassButton class.
You need to create an instance of MKCompassButton and add it to your map view. You can then set its compassVisibility property to one of:
.visible - always visible
.never - never visible
.adaptive - the compasss is only visible if the map is rotated away from a North/up orientation.
If you keep a reference to the compass in a property you can change its visibility as you need:
mapview.showsCompass = false // Hide built-in compass
compassButton = MKCompassButton(mapView: mapview) // Make a new compass
compassButton.compassVisibility = .visible // Make it visible
mapview.addSubview(compassButton) // Add it to the view
// Position it as required
compassButton.translatesAutoresizingMaskIntoConstraints = false
compassButton.trailingAnchor.constraint(equalTo: mapview.trailingAnchor, constant: -12).isActive = true
compassButton.topAnchor.constraint(equalTo: mapview.topAnchor, constant: 12).isActive = true
Unfortunately, for prior versions of iOS there is no simple solution. I have seen suggestions that involve looking through the map view's subviews to try and find the compass view but there seems to be mixed results.

How to lock the scroll view in place?

I want to lock the scrollView when my segmented Control comes to top of the screen. How can I do this in swift? What's the code of this? How to compute the distance between the top of the segmented control and top of the view controller? It means how can I find the true place for locking scrollView?
After Swift 4.0 it has changed to
scrollView.isScrollEnabled = false
and
scrollView?.isScrollEnabled = true
Just flip the scrollEnabled boolean:
yourScrollView.scrollEnabled = false
To make it scroll again:
yourScrollView.scrollEnabled = true

Resources