How to get rounded corner & dynamic height of popped custom modalPresentationStyle VC - ios

When present a VC, the default style is not cover full screen and with a rounded corner like below gif illustrated.
But I want to control the height of modalPresentation, let's say a 1/4 screen height by default and dynamic changed according to tableView's rows of popped VC. So I implement a custom modalPresentationStyle on the base VC wit below code.
However, I found these issues after:
The popped VC is not rounded corner but with rectangle corner.
I cannot drag to move the popped VC anymore, it is in fixed position.
It would be more better if I could to increment the popped VC's height per its tableView rows count. Not a must item.
#objc func collectButtonTapped(_ sender: Any?) {
let vc = PlayListViewController()
vc.modalPresentationStyle = .custom
vc.transitioningDelegate = self
present(vc, animated: true)
}
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
return HalfSizePresentationController(presentedViewController: presented, presenting: presentingViewController)
}
class HalfSizePresentationController: UIPresentationController {
override var frameOfPresentedViewInContainerView: CGRect {
guard let bounds = containerView?.bounds else { return .zero }
return CGRect(x: 0, y: bounds.height * 0.75, width: bounds.width, height: bounds.height * 0.75)
}
}

Try to assign cornerRadius to your vc:
#objc func collectButtonTapped(_ sender: Any?) {
let vc = PlayListViewController()
vc.modalPresentationStyle = .custom
vc.transitioningDelegate = self
// assign corner radius
vc.view.layer.cornerRadius = 20
vc.view.clipsToBounds = true
vc.view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] // this is for corner radius only for top
present(vc, animated: true)
}
for total control of vc presented position, you can use child vc and auto layout, for present child vc (like a modal presentation style) you can use UIView.animate on child vc top constraint.
this is an example of child vc and auto layout:
import UIKit
class YourController: UIViewController {
private lazy var firstChildVc = AiutiFirst()
let myButton: UIButton = {
let b = UIButton(type: .system)
b.layer.cornerRadius = 10
b.clipsToBounds = true
b.backgroundColor = .black
b.setTitleColor(.white, for: .normal)
b.setTitle("Present", for: .normal)
b.addTarget(self, action: #selector(handlePresent), for: .touchUpInside)
b.translatesAutoresizingMaskIntoConstraints = false
return b
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .blue
addChildVC()
}
var up = false
#objc fileprivate func handlePresent() {
print("present")
if up == false {
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut) {
self.menuDown?.isActive = false
self.menuUp?.isActive = true
self.myButton.setTitle("Dismiss", for: .normal)
self.view.layoutIfNeeded()
} completion: { _ in
print("Animation completed")
self.up = true
}
} else {
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut) {
self.menuUp?.isActive = false
self.menuDown?.isActive = true
self.myButton.setTitle("Present", for: .normal)
self.view.layoutIfNeeded()
} completion: { _ in
print("Animation completed")
self.up = false
}
}
}
var menuUp: NSLayoutConstraint?
var menuDown: NSLayoutConstraint?
fileprivate func addChildVC() {
addChild(firstChildVc)
firstChildVc.view.translatesAutoresizingMaskIntoConstraints = false
firstChildVc.view.layer.cornerRadius = 20
firstChildVc.view.clipsToBounds = true
firstChildVc.view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] // this is for corner radius only for top
view.addSubview(firstChildVc.view)
menuUp = firstChildVc.view.topAnchor.constraint(equalTo: view.centerYAnchor)
menuDown = firstChildVc.view.topAnchor.constraint(equalTo: view.bottomAnchor)
menuDown?.isActive = true
firstChildVc.view.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
firstChildVc.view.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
firstChildVc.view.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
firstChildVc.didMove(toParent: self)
view.addSubview(myButton)
myButton.bottomAnchor.constraint(equalTo: view.centerYAnchor, constant: -40).isActive = true
myButton.widthAnchor.constraint(equalToConstant: 200).isActive = true
myButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
myButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
}
}
And this is the result:
To animate child vc presentation you can use UIView.animate function for top child vc constraint, or Pan gesture do drag it, or whatever you deem necessary and valid to use...
to show it full screen simple set child vc top anchor to top of intere view:
menuUp = firstChildVc.view.topAnchor.constraint(equalTo: view.topAnchor)

Related

Avoid popover adapting to fullscreen in horizontally compact environment

According to documentation,
In a horizontally compact environment, popovers adapt to the
UIModalPresentationOverFullScreen presentation style by default.
See below image. In compact environment, popover appear from bottom and animate to top until it covers the entire screen.
Is it possible to override this behaviour and have the popover only covering certain height of the screen as shown below?
Following code demonstrate the default behaviour of popover adapting to FullScreen presentation style in compact environment.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .systemBackground
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.setImage(UIImage(systemName: "square.grid.2x2.fill"), for: .normal)
button.addTarget(self, action: #selector(displayPopover), for: .touchUpInside)
self.view.addSubview(button)
NSLayoutConstraint.activate([
button.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100),
button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
button.widthAnchor.constraint(equalToConstant: 40),
button.heightAnchor.constraint(equalToConstant: 40),
])
}
#IBAction func displayPopover(sender: UIButton!) {
let popoverVC = PopoverViewController()
popoverVC.preferredContentSize = CGSize(width: 300, height: 200)
popoverVC.modalPresentationStyle = .popover
popoverVC.popoverPresentationController?.sourceView = sender
popoverVC.popoverPresentationController?.permittedArrowDirections = .up
self.present(popoverVC, animated: true, completion: nil)
}
}
class PopoverViewController: UIViewController {
override func viewDidLoad() {
self.view.backgroundColor = .systemGray
}
}
Output:
Thank you 🙇‍♂️
This feature is now available with iOS 15.
Watch WWDC2021 short video
Download WWDC sample project from here
#IBAction func showImagePicker(_ sender: UIBarButtonItem) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.modalPresentationStyle = .popover
if let popover = imagePicker.popoverPresentationController {
popover.barButtonItem = sender
let sheet = popover.adaptiveSheetPresentationController
sheet.detents = [.medium(), .large()]
sheet.largestUndimmedDetentIdentifier = .medium
sheet.prefersScrollingExpandsWhenScrolledToEdge = false
sheet.prefersEdgeAttachedInCompactHeight = true
sheet.widthFollowsPreferredContentSizeWhenEdgeAttached = true
}
present(imagePicker, animated: true, completion: nil)
}

How to dismiss a stack of UIViewControllers to a certain Root ViewController?

Some RootViewController presents a ParentViewController which than presents a ChildViewController.
How can I dissmiss the ChildViewController animated directly to the RootViewController whithout showing the ParentViewController again?
In Detail
Assume some presents the ParentViewController which lets the user enter some credentials to login to some user account.
Once the connection is established the ParentViewController presents the ChildViewController which shows connection / account details to the user
When the user closes the ChildViewController it should be dismissed animated (slide down, etc.). But instead of returning to the ParentViewController the user should get back directly to the RootViewController
Of course it would be possible, that the ParentViewController does not present the ChildViewController itself but (somehow) tells the RootViewController to this. This way it would be no problem to directly return from the ChildViewController to the RootViewController. However, this is NOT what I am looking for, since the RootViewController should not know about the ChildViewController or even care if the ParentViewController presents other VCs.
I am looking for a solution where the ParentViewController controls whether itself is shown after the VC it presented is dismissed or its parent (= the root VC).
Code:
typealias CompletionBlock = () -> Void
class RootViewController: UIViewController {
#IBAction func showParentVC(_ sender: Any) {
let parentVC = ParentViewController()
parentVC.completion = {
self.dismiss(animated: true, completion: nil)
}
present(parentVC, animated: true)
}
}
class ParentViewController: UIViewController {
var completion: CompletionBlock?
#IBAction func showChild(_ sender: Any) {
let childVC = ChildViewController()
childVC.completion = {
self.completion?()
}
present(childVC, animated: true)
}
}
class ChildViewController: UIViewController {
var completion: CompletionBlock?
#IBAction func close(_ sender: Any) {
completion?()
}
}
Using this code does NOT solve the described problem. If close is called on the ChildViewController the RootViewController calls self.dismiss(animated: true, completion: nil). This way the ChildViewController animates away and the ParentViewController becomes visible. Then the ParentViewController animates away and the RootViewControllerbecomes visible.
How to skip the ParentViewController and directly show the RootViewController after animating away the ChildViewController?
My recommendation is embed your RootViewController into a NavigationController (if you don't have it yet) and present both parent a child with
navigationController?.present(viewController, animated: true, completion: nil)
//instead of viewController.present(...)
And then youcan use this method from your childViewController
navigationController?.popToRootViewController(animated: true)
One approach would be to set the view's alpha to Zero when you present another VC onto the "stack" of presented VCs.
So, present the first modal VC from the "root" VC as normal. For each "child" that presents another VC, use:
present(vc, animated: true, completion: {
self.view.alpha = 0.0
})
Now, when you call-back to the "root" VC to dismiss all the VCs, you won't see the partial / flash of the intermediate VC / VCs.
Here is a complete example to test. No #IBOutlets or #IBActions ... just start with a black view controller and assign its Custom Class to MultiPresentDismissViewController:
import UIKit
class MultiPresentDismissViewController: UIViewController {
let theLabel: UILabel = {
let v = UILabel()
v.textAlignment = .center
v.font = UIFont.boldSystemFont(ofSize: 40)
v.backgroundColor = .yellow
v.text = "\"Root\" VC"
return v
}()
let showAnotherButton: UIButton = {
let v = UIButton()
v.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
v.setTitle("Present a VC", for: .normal)
v.setTitleColor(.blue, for: .normal)
v.setTitleColor(.cyan, for: .highlighted)
return v
}()
let theStackView: UIStackView = {
let v = UIStackView()
v.axis = .vertical
v.alignment = .fill
v.distribution = .fill
v.spacing = 32
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
[theLabel, showAnotherButton].forEach {
theStackView.addArrangedSubview($0)
$0.layer.borderWidth = 1.0
}
theStackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(theStackView)
NSLayoutConstraint.activate([
theStackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
theStackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100.0),
theStackView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.8),
])
showAnotherButton.addTarget(self, action: #selector(presentAnotherVC), for: .touchUpInside)
}
#objc func presentAnotherVC() -> Void {
let vc = AnotherViewController()
vc.myID = 1
present(vc, animated: true, completion: nil)
}
}
class AnotherViewController: UIViewController {
let theLabel: UILabel = {
let v = UILabel()
v.textAlignment = .center
v.font = UIFont.boldSystemFont(ofSize: 100)
v.backgroundColor = .yellow
return v
}()
let showAnotherButton: UIButton = {
let v = UIButton()
v.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
v.setTitle("Present Another VC", for: .normal)
v.setTitleColor(.blue, for: .normal)
v.setTitleColor(.cyan, for: .highlighted)
return v
}()
let defaultDismissButton: UIButton = {
let v = UIButton()
v.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
v.setTitle("Default Dismiss All", for: .normal)
v.setTitleColor(.blue, for: .normal)
v.setTitleColor(.cyan, for: .highlighted)
return v
}()
let theStackView: UIStackView = {
let v = UIStackView()
v.axis = .vertical
v.alignment = .fill
v.distribution = .fill
v.spacing = 20
return v
}()
var myID: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .random()
[theLabel, showAnotherButton, defaultDismissButton].forEach {
theStackView.addArrangedSubview($0)
$0.layer.borderWidth = 1.0
}
theStackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(theStackView)
NSLayoutConstraint.activate([
theStackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
theStackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100.0),
theStackView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.8),
])
theLabel.text = "\(myID)"
showAnotherButton.addTarget(self, action: #selector(presentAnotherVC), for: .touchUpInside)
defaultDismissButton.addTarget(self, action: #selector(defaultDismissAll), for: .touchUpInside)
}
#objc func presentAnotherVC() -> Void {
let vc = AnotherViewController()
vc.myID = myID + 1
present(vc, animated: true, completion: {
self.view.alpha = 0.0
})
}
#objc func defaultDismissAll() -> Void {
// walk up the "presenting" hierarchy to find the "root" VC
var vc = self.presentingViewController
while vc?.presentingViewController != nil {
vc = vc?.presentingViewController
}
vc?.dismiss(animated: true, completion: nil)
}
}
extension CGFloat {
static func random() -> CGFloat {
return CGFloat(arc4random()) / CGFloat(UInt32.max)
}
}
extension UIColor {
static func random() -> UIColor {
return UIColor(red: .random(),
green: .random(),
blue: .random(),
alpha: 1.0)
}
}

Cannot Center Popover Swift

I am trying to make a popover that will allow users to swipe between images (is there a better approach to this than using a popover?).
Right now to make the popover, I have spend hours googling on simply how to make a rectangle center in the screen. From the internet my code is:
// get a reference to the view controller for the popover
let popController = UIStoryboard(name: "Event", bundle: nil).instantiateViewController(withIdentifier: "carouselPopover")
// set the presentation style
popController.modalPresentationStyle = UIModalPresentationStyle.popover
let width = view.frame.width
popController.preferredContentSize = CGSize(width: width, height: 300)
// set up the popover presentation controller
popController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.up
popController.popoverPresentationController?.delegate = self
popController.popoverPresentationController?.sourceView = self.view
popController.popoverPresentationController?.sourceRect = CGRect(x: view.bounds.midX, y: view.bounds.midY, width: 0, height: 0)
popController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
// present the popover
self.present(popController, animated: true, completion: nil)
However, for the life of me I cannot understand why the popover is not centered
It only loses its center when I set the popController's preferred content size. Any thoughts?
TL:DR
I want to 1) center the popover on the screen, 2) Make the popover 1:1 ratio, and 3) make the width of the popover proportional to the width of the parent screen. How can I do that without 1000's lines of code.
You can create a custom popover class. Then you establish delegate patterns to determine if user swipes.
protocol PopoverDelegate: class {
func imageviewDidSwipe(_ popover: Popover)
}
class Popover: UIView {
weak var delegate: PopoverDelegate?
init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.white
}
func setupImage(_ image: UIImage) {
let imageView = UIView(frame: CGRect.zero)
imageView.image = image
self.addSubview(imageView)
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
imageView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 50).isActive = true // However big you want
imageView.widthAnchor.constraint(equalToConstant: 50).isActive = true // However big you want
}
func showPopover(over view: UIView) {
view.addSubview(self)
translatesAutoResizingMaskIntoConstraints = false
centerXAnchor.contraint(equalTo: view.centerXAnchor).isActive = true
centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
heightAnchor.constraint(equalToConstant: frame.height).isActive = true
widthAnchor.constraint(equalToConstant: frame.width).isActive = true
}
}
To use...
class vC: UIViewController {
func ImageOnClick() {
// change view to where you want popover to show on top of
let popover = Popover(frame: view.frame)
popover.setupImage(image.png)
popover.delegate = self
showPopover(over: view)
}
}
extension vC: PopoverDelegate {
func imageviewDidSwipe(_ popover: Popover) {
// image swiped
}
}

Show back button without navigation view controller

I have the scheme: UITabBarViewController (with 3 tabs).
In all that tabs I don't want to show navigation menu on top.
And from the first tab, I want to push another view controller from button click that will have "back" button (and top toolbar with "cancel")
I tried some ways - in storyboard with push segue - no back button.
Probably because i don't have navigation view controller, so my navigation stack is empty.
Programmatically:
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "AddCoinTableViewController") as! AddCoinTableViewController
self.present(nextViewController, animated:true, completion:nil)
If I embed tabs in navigation controller, then I have top toolbar (which I don't want).
Any ideas how to make it?
You can't achieve navigation functionality without using UINavigationController. I mean you have to do all animation kind of stuff on your own, and I think that's not a good idea. Rather than that, you can use UINavigationController, and if you don't want to show navigationBar at some viewController, than do as follows for those view controllers.
override func viewWillApear() {
super.viewDidLoad()
self.navigationController?.isNavigationBarHidden = true
}
override func viewWillDisappear(animated: Bool) {
self.navigationController?.isNavigationBarHidden = false
}
You can embed the navigation controller at your first tab controller (or any you want), and hide it at the controllers you don't want on their viewDidLoad like this:
self.navigationController?.isNavigationBarHidden = true
Doing this, you will be able to see the back Button at the controllers you pushed and didn't hide the navigationBar.
Make sure you push the controller using the navigation controller like this:
self.navigationController?.pushViewController(YOUR VIEW CONTROLLER, animated: true)
The below code will allow you to create your own Navigation handling class and have the "push" "pop" animation that UINavigationController has.. You can create a new project, copy paste the below into ViewController.swift and see for yourself..
Now you can give any UIViewController navigation controller abilities..
import UIKit
class NavigationHandler : NSObject, UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning, UINavigationBarDelegate {
private var isPresenting: Bool = false
private weak var controller: UIViewController?
init(controller: UIViewController) {
super.init()
self.controller = controller
controller.transitioningDelegate = self
let navigationBar = UINavigationBar()
controller.view.addSubview(navigationBar)
NSLayoutConstraint.activate([
navigationBar.leftAnchor.constraint(equalTo: controller.view.leftAnchor),
navigationBar.rightAnchor.constraint(equalTo: controller.view.rightAnchor),
navigationBar.topAnchor.constraint(equalTo: controller.view.safeAreaLayoutGuide.topAnchor)
])
navigationBar.translatesAutoresizingMaskIntoConstraints = false
navigationBar.delegate = self
let item = UINavigationItem(title: controller.title ?? "")
let barButton = UIBarButtonItem(title: "Back", style: .done, target: self, action: #selector(onBackButton(button:)))
item.leftBarButtonItems = [barButton]
navigationBar.setItems([item], animated: true)
}
func position(for bar: UIBarPositioning) -> UIBarPosition {
return .topAttached
}
#objc
private func onBackButton(button: UIBarButtonItem) {
self.controller?.dismiss(animated: true, completion: nil)
}
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
self.isPresenting = true;
return self;
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
self.isPresenting = false;
return self;
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.25;
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let duration = self.transitionDuration(using: transitionContext)
let fromController = transitionContext.viewController(forKey: .from)
let toController = transitionContext.viewController(forKey: .to)
let containerView = transitionContext.containerView
if self.isPresenting {
let frame = fromController!.view.frame
containerView.addSubview(toController!.view)
toController?.view.frame = CGRect(x: frame.origin.x + frame.width, y: frame.origin.y, width: frame.width, height: frame.height)
UIView.animate(withDuration: duration, animations: {
fromController?.view.frame = CGRect(x: frame.origin.x - frame.size.width, y: frame.origin.y, width: frame.size.width, height: frame.size.height)
toController?.view.frame = frame
}, completion: { (completed) in
transitionContext.completeTransition(true)
})
}
else {
let frame = fromController!.view.frame
containerView.insertSubview(toController!.view, at: 0)
toController?.view.frame = CGRect(x: frame.origin.x - frame.size.width, y: frame.origin.y, width: frame.size.width, height: frame.size.height)
UIView.animate(withDuration: duration, animations: {
fromController?.view.frame = CGRect(x: frame.origin.x + frame.width, y: frame.origin.y, width: frame.width, height: frame.height)
toController?.view.frame = frame
}, completion: { (completed) in
transitionContext.completeTransition(true)
})
}
}
}
View Controllers for testing:
class ViewController : UIViewController {
private var navigationHandler: NavigationHandler?
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(type: .custom)
button.setTitle("Push Controller", for: .normal)
button.setTitleColor(UIColor.red, for: .normal)
button.layer.borderColor = UIColor.black.cgColor
button.layer.borderWidth = 1.0
button.layer.cornerRadius = 5.0
button.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(button)
NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
button.heightAnchor.constraint(equalToConstant: 45.0),
button.widthAnchor.constraint(equalToConstant: 150.0)
])
button.addTarget(self, action: #selector(onPush(button:)), for: .touchUpInside)
}
#objc
private func onPush(button: UIButton) {
let child = ChildViewController()
self.navigationHandler = NavigationHandler(controller: child)
self.present(child, animated: true, completion: nil)
}
}
class ChildViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.blue
}
}

How to mask a ViewController when presenting a view over it

I am trying to mask a ViewController when i present a view like in The way i present my view is by anchoring it outside of the screen like this:
addContactTopAnchor = addContact.bottomAnchor.constraint(equalTo:
view.topAnchor)
addContactTopAnchor.isActive = true
addContact.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
addContact.heightAnchor.constraint(equalToConstant: 182).isActive = true
and when i press a button i move it onto the display like this:
func addTapped(){
self.addContactTopAnchor.isActive = false
self.addContactTopAnchor = addContact.bottomAnchor.constraint(equalTo: view.topAnchor, constant: 182)
self.addContactTopAnchor.isActive = true
UIView.animate(withDuration: 0.3, animations: { () -> Void in
self.view.layoutIfNeeded()
})
}
I want to mask everything except for the view just like its show in my screenshot.
I created a view
let mask: UIView = {
let view = UIView()
view.backgroundColor = .black
view.alpha = 0
return view
}()
and in my button press, I set the alpha and brought my view to the front
func addTapped() {
self.addContactTopAnchor.isActive = false
self.addContactTopAnchor = addContact.topAnchor.constraint(equalTo: view.bottomAnchor, constant: -182)
self.addContactTopAnchor.isActive = true
UIView.animate(withDuration: 0.3, animations: { () -> Void in
self.view.layoutIfNeeded()
self.mask.alpha = 0.5
self.navigationController?.navigationBar.alpha = 0.5
self.navigationController?.navigationBar.shadowImage = UIImage()
self.view.bringSubview(toFront: self.addContact)
})
}
EDIT: Also i added this to mask the navigation bar:
self.navigationController?.navigationBar.alpha = 0.5
self.navigationController?.navigationBar.shadowImage = UIImage()
thanks #desdenova for the help

Resources