Child view controller's view ignores Auto Layout constraints - ios

I would like to add child view controller to UINavigationController's view. I have hierarchy like this
NavigationController -> View(drawer) -> View(contentContainer) -> child view controller should be pinned to the contentContainer
But for some reason it ignores the constraints and I get weird results. Please see the screenshot, drawer is green, contentContainer is yellow and the child controller is placed almost outside of the screen and has frame with 0 height.
The critical code is inside the drawerContentController didSet and setupView method. Please note that I'm using SnapKit for constraints but the same problem was happening by setting the NSLayoutConstraints traditionally
class NavigationController: UINavigationController {
private var drawerHeightConstraint: Constraint!
fileprivate lazy var drawer = UIView()
private lazy var contentContainer = UIView()
var drawerContentController: UIViewController? {
didSet {
guard let new = drawerContentController else {
oldValue?.removeFromParent(animated: true)
return
}
if let old = oldValue {
old.removeFromParent(animated: true) { _ in
self.add(child: new, superview: self.contentContainer, animated: true, completion: nil)
}
} else {
add(child: new, superview: contentContainer, animated: true, completion: nil)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
setupView()
}
private func setupView() {
view.addSubview(drawer)
drawer.backgroundColor = .green
drawer.snp.makeConstraints { make in
make.leading.bottom.trailing.equalToSuperview()
drawerHeightConstraint = make.height.equalTo(360).constraint
}
let blur = UIBlurEffect(style: .default)
let visualView = UIVisualEffectView(effect: blur)
drawer.addSubview(visualView)
visualView.pinToSuperView()
contentContainer.backgroundColor = .yellow
drawer.addSubview(contentContainer)
contentContainer.snp.makeConstraints { make in
make.edges.equalTo(drawer.safeAreaLayoutGuide)
}
}
func add(child controller: UIViewController, superview: UIView? = nil, animated: Bool, completion: ((Bool) -> Void)? = nil) {
controller.willMove(toParent: self)
addChild(controller)
controller.view.alpha = 0
(superview ?? view).addSubview(controller.view)
controller.view.pinToSuperView()
UIView.animate(withDuration: animated ? 0.3 : 0, animations: {
controller.view.alpha = 1
}) { finished in
controller.didMove(toParent: self)
completion?(finished)
}
}
}
extension UIView {
func pinToSuperView() {
snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}
}
When I add a simple UIView to the contentContainer it works as expected
var drawerContentController: UIViewController? {
didSet {
let v = UIView()
v.backgroundColor = .purple
contentContainer.addSubview(v)
v.pinToSuperView()
}
}

Okay, I "solved" the issue.
It seems that UINavigationController does not like having child view controllers added to it. As seen on the screenshots, when child controller is added the entire view hierarchy of navigation controller is broken. On the second screenshot, the table view controller (white view) is displayed correctly, but in the first case it is not even in the view hierarchy!
So the moral is, try to not add child view controllers directly to UINavigationController, in the end it is not a normal UIViewController and doesn't even have a normal UIView. I have added another UIViewController to act as a container for UINavigationController and added the child controller to it. It now works as expected.

Related

animate subviews inside UINavigationBar when pushing to detailviewController

I've got some subviews in my navigationBar. A black square, some titles and a blue bar. When pushed to a detail viewController, I want my subviews to hide (animated).
I added the subways to the navigation bar inside the main view controller using
self.navigationController?.navigationBar.addsubView(mySubview).
Currently, it looks like his:
What is the right way to hide (animated) those subviews in the detail viewController?
Your question is very interesting. I never thought about the navigation bar.
When UINavigationController is used as the root controller, all UIViewControllers are stored in its stack, meaning that all UIViewControllers share a navigationBar.
You added mySubView to navigationBar in the first UIViewController. If you want to hide it on the details page, you can search for subviews directly.
The first step, you need to give mySubView a tag, which can be a tag, or it can be a custom type, which is convenient for later judgment.
On the first page
import SnapKit
mySubView = UIView()
mySubView?.tag = 999
mySubView?.backgroundColor = .red
mySubView?.translatesAutoresizingMaskIntoConstraints = false
let navBar = navigationController?.navigationBar
navBar!.addSubview(mySubView!)
mySubView!.snp.makeConstraints { (make) in
make.left.equalTo(navBar!).offset(100)
make.centerY.equalTo(navBar!)
make.width.height.equalTo(50)
}
On the details page, I deleted isHidden and saved navigationBar with the attribute because navigationBar = nil during the gesture. If SnapKit is unfamiliar, take a few more minutes to learn.
var mySubView: UIView? = nil
var navBar: UINavigationBar?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
// Do any additional setup after loading the view.
navigationController?.interactivePopGestureRecognizer?.addTarget(self, action: #selector(backGesture))
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
homeNavigationBarStatus()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
homeNavigationBarStatus()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if mySubView == nil {
for view: UIView in (navigationController?.navigationBar.subviews)! {
if view.tag == 999 {
mySubView = view
}
}
}
UIView.animate(withDuration: 1, delay: 0, options: .curveEaseOut, animations: {
self.detailNavigationBarStatus()
}, completion: nil)
}
func detailNavigationBarStatus(){
changingNavigationBarStatus(progress: 0)
}
func homeNavigationBarStatus(){
changingNavigationBarStatus(progress: 1.0)
}
func changingNavigationBarStatus(progress:CGFloat){
mySubView?.alpha = progress
mySubView?.snp.updateConstraints({ (make) in
make.left.equalTo(navBar!).offset(100 * progress)
})
}
#objc func backGesture(sender: UIScreenEdgePanGestureRecognizer) {
switch sender.state {
case .changed:
let x = sender.translation(in: view).x
progress = x / view.frame.width
changingNavigationBarStatus(progress: progress)
default:
break
}
}
However, using tag values is not elegant enough, you can create a specific class for mySubView, which can also be judged by class.

How to fix subview not showing in child view controller when added to a parent view controller

I'm trying to add a child view controller to a parent view controller in a swift ios application, but when I add the child view controller, the activityIndicatorView doesn't appear. What could I be missing?
Here is a snippet that can be tried in a playground:
import PlaygroundSupport
import Alamofire
class LoadingViewController: UIViewController {
private lazy var activityIndicator = UIActivityIndicatorView(style: .gray)
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(activityIndicator)
NSLayoutConstraint.activate([
activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor),
activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// We use a 0.5 second delay to not show an activity indicator
// in case our data loads very quickly.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.0) { [weak self] in
self?.activityIndicator.startAnimating()
}
}
}
// methods for adding and removing child view controllers.
extension UIViewController {
func add(_ child: UIViewController, frame: CGRect? = nil) {
addChild(child)
if let frame = frame {
child.view.frame = frame
}
view.addSubview(child.view)
child.didMove(toParent: self)
}
func remove() {
// Just to be safe, we check that this view controller
// is actually added to a parent before removing it.
guard parent != nil else {
return
}
willMove(toParent: nil)
view.removeFromSuperview()
removeFromParent()
}
}
class MyViewController : UITabBarController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let label = UILabel()
label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
label.text = "Hello World!"
label.textColor = .black
view.addSubview(label)
self.view = view
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let loadingViewController = LoadingViewController()
add(loadingViewController, frame: view.frame)
AF.request("http://www.youtube.com").response { response in
print(String(describing: response.response))
loadingViewController.remove()
}
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
The loadingViewController view fills the parent view, and i've tried to change the background colour at different points and that works. but activityIndicator or any other subview i try to add just doesn't appear.
Try add the line
activityIndicator.startAnimating()
in your viewDidLoad() method from your LoadingViewController class

How to create a short modal overlay like the iOS Share Sheet menu?

I’m trying to create a custom, short menu that slides up from the bottom of the screen and stays at the bottom (like the iOS share sheet). I’m having a hard time trying to figure out how to do it. I tried presenting a view controller as a modal and setting the preferred content size, but it still presents it as full screen. How can I present a short, modal-like overlay?
You could use a UIPresentationController and a UIViewControllerTransitioningDelegate.
As a starting point here a few lines of code:
UIViewControllerTransitioningDelegate
class OverlayTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
return OverlayPresentationController(presentedViewController:presented, presenting:presenting)
}
}
UIPresentationController
class OverlayPresentationController: UIPresentationController {
private let dimmedBackgroundView = UIView()
private let height: CGFloat = 200.0
override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {
super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(backgroundTapped))
self.dimmedBackgroundView.addGestureRecognizer(tapGestureRecognizer)
}
override var frameOfPresentedViewInContainerView: CGRect {
var frame = CGRect.zero
if let containerBounds = containerView?.bounds {
frame = CGRect(x: 0,
y: containerBounds.height - height,
width: containerBounds.width,
height: height)
}
return frame
}
override func presentationTransitionWillBegin() {
if let containerView = self.containerView, let coordinator = presentingViewController.transitionCoordinator {
containerView.addSubview(self.dimmedBackgroundView)
self.dimmedBackgroundView.backgroundColor = .black
self.dimmedBackgroundView.frame = containerView.bounds
self.dimmedBackgroundView.alpha = 0
coordinator.animate(alongsideTransition: { _ in
self.dimmedBackgroundView.alpha = 0.5
}, completion: nil)
}
}
override func dismissalTransitionDidEnd(_ completed: Bool) {
self.dimmedBackgroundView.removeFromSuperview()
}
#objc private func backgroundTapped() {
self.presentedViewController.dismiss(animated: true, completion: nil)
}
}
How to call it
let overlayTransitioningDelegate = OverlayTransitioningDelegate()
#IBAction func onOpenModalOverlay(_ sender: Any) {
let overlayVC = OverlayViewController()
overlayVC.transitioningDelegate = self.overlayTransitioningDelegate
overlayVC.modalPresentationStyle = .custom
self.present(overlayVC, animated: true, completion: nil)
}
Demo
The OverlayViewController is a normal ViewController. Here I used an ugly green background color to make it easier to recognize the overlay.

Display overlay view between ViewControllers

I am trying to display an overlay view on top of every ViewController after successfully logging in to show loading status of the app and load some data while this view is being displayed.
This view comes from a custom NIB file.
I display the OverlayLoadingView after a successful login request to the server, then I want to present a new ViewController on another Storyboard using:
self.present(vc, animated: true, completion: nil)
And finally hide the OverlayLoadingView in the next ViewController (This is why I handle it as a Singleton).
But when I present the next ViewController, the OverlayLoadingView disappears. Is there a way to display this loading view on top of everything while presenting a new view controller on the back at the same time?
Something like this:
LoginViewController -> Successfully logged in -> display OverlayView -> present MainViewController -> MainViewController presented below OverlayView -> Load initial data -> Hide OverlayView after initial data has been loaded.
#IBDesignable
public class OverlayLoadingView: UIView {
#IBOutlet weak var headerImageView: UIImageView!
#IBOutlet weak var detailTextLabel: UILabel!
class var sharedInstance: OverlayLoadingView {
struct Static {
static let instance: OverlayLoadingView = OverlayLoadingView(frame: UIScreen.main.bounds)
}
return Static.instance
}
// Custom view from the XIB file
fileprivate var view: UIView!
// Set header image directly by giving a value to headerImageURL variable from server response
/**
Initialiser method
*/
override init(frame: CGRect) {
super.init(frame: frame)
setupNib()
}
/**
Initialiser method
*/
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupNib()
}
fileprivate func loadNib() -> UIView? {
return Bundle.main.loadNibNamed("OverlayLoadingView", owner: self, options: nil)?.first as? UIView
}
func setupNib() {
if let overlayLoadingView = loadNib() {
self.view = overlayLoadingView
let screenWidth = Util.screenSize().width
let screenHeight = Util.screenSize().height
self.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
view.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
self.addSubview(view)
}
}
public func showOverlay() {
if let appDelegate = UIApplication.shared.delegate as? AppDelegate,
let window = appDelegate.window {
self.alpha = 1.0
window.addSubview(self)
activityIndicator.startAnimating()
}
}
public func hideOverlayView() {
activityIndicator.stopAnimating()
self.removeFromSuperview()
}
}
EDIT:
To display the overlay view I am using:
DispatchQueue.main.async {
let storyboard = UIStoryboard(name: "TabMenu", bundle: nil)
let vc = storyboard.instantiateInitialViewController()!
OverlayLoadingView.sharedInstance.showOverlay()
self.present(vc, animated: true, completion: {
// Dismiss current VC?
})
}
The views hierarchy is shown like the following image. The overlay view should be over everything.
If your requirement is to display the loading view above all controllers you can add the view to the window.
if let window = UIApplication.shared.keyWindow {
let overlay = OverlayLoadingView(frame:UIScreen.main.bounds)
overlay.tag = 1001
window.addSubView(overlay)
// remove it like this
window.viewWithTag(overlay.tag)?.removeFromSuperView()
}
By the way this is not a Singleton as I'm able to use init and create another instance mark the init as private. Make the class final to avoid reflection and replace class with static As class can be overided but static can't.

Custom Alert (UIAlertView) with swift

How can i create a custom alert with Swift? I try translating a guide from Objective c but loads a full screen layout
for do it easy i can load a new layout with the transparent background i try this:
listaalertviewcontroller.view.backgroundColor = UIColor.clearColor()
let purple = UIColor.purpleColor() // 1.0 alpha
let semi = purple.colorWithAlphaComponent(0.5)
listaalertviewcontroller.view.backgroundColor = semi
presentingViewController.modalPresentationStyle = UIModalPresentationStyle.CurrentContext
self.presentViewController(listaalertviewcontroller, animated: true, completion: nil)
in the animation it's transparent but when the animation ends it's opaque... and i turn off opaque option in the view... what i'm doing wrong?
Code tested in Swift 5 and Xcode 10
How to make your own custom Alert
I was wanting to do something similar. First of all, UIAlertView is deprecated in favor of UIAlertController. See this answer for the standard way to display an alert:
How would I create a UIAlertView in Swift?
And both UIAlertView and UIAlertController do not really allow much customization. One option is to use some third party code. However, I discovered that it isn't that difficult to create your own Alert by displaying another view controller modaly.
The example here is just a proof-of-concept. You can design your alert any way you want.
Storyboard
You should have two View Controllers. Your second view controller will be your alert. Set the class name to AlertViewContoller and the Storyboard ID to alert. (Both of these are names that we defined ourselves in the code below, nothing special about them. You can add the code first if you want. It might actually be easier if you add the code first.)
Set the background color for the root view (in your Alert View Controller) to clear (or translucent black is nice for an alert). Add another UIView and center it with constraints. Use that as your alert background and put whatever you want inside. For my example, I added a UIButton.
Code
ViewController.swift
import UIKit
class ViewController: UIViewController {
#IBAction func showAlertButtonTapped(_ sender: UIButton) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let myAlert = storyboard.instantiateViewController(withIdentifier: "alert")
myAlert.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
myAlert.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
self.present(myAlert, animated: true, completion: nil)
}
}
AlertViewController.swift
import UIKit
class AlertViewController: UIViewController {
#IBAction func dismissButtonTapped(_ sender: UIButton) {
self.dismiss(animated: true, completion: nil)
}
}
Don't forget to hook up the outlets.
You can add an onTouchUp event listener to the background view to dismiss the popup when the user clicks outside of it.
That's it. You should be able to make any sort of alert that you can imagine now. No need for third party code.
Here is another custom alert I made. Still ugly, but it shows more things you can do.
Other options
Sometimes there is no need to reinvent the wheel, though. I'm impressed with the third party project SDCAlertView (MIT license). It is written in Swift but you can use it with Objective-C projects as well. It offers a wide range of customability.
Here is the Swift 3 code. Thanks a lot #Suragch for the awesome approach to create a custom AlertView.
ViewController.swift
import UIKit
class ViewController: UIViewController {
#IBAction func showAlertButtonTapped(sender: UIButton) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let myAlert = storyboard.instantiateViewController(withIdentifier: "storyboardID")
myAlert.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
myAlert.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
self.present(myAlert, animated: true, completion: nil)
}
AlertViewController.swift
import UIKit
class AlertViewController: UIViewController {
#IBAction func dismissButtonTapped(sender: UIButton) {
self.dismiss(animated: true, completion: nil)
}
}
To make it a little more interesting or to make the default effect in iOS, you could add either a VisualEffectView or change the color of the main UIView to a dark color and set its alpha to 70%. I prefer the second approach since the blur effect is not as smooth as the one with the view with 70 alpha.
Effect with VisualEffectView:
Effect using a UIView with 70 Alpha:
Nowadays, an alert is merely a simple presented view controller. You can write a presented view controller that behaves similarly to an alert — that is, it pops onto the screen and dims whatever is behind it — but it's your view controller and you are free to give it any interface you like.
To get you started, I've written a github project that you can download and run, and modify to suit your actual needs.
I'll show the key part of the code. The "alert" view controller, in its initializers, sets its own modal presentation style as custom and sets a transitioning delegate:
class CustomAlertViewController : UIViewController {
let transitioner = CAVTransitioner()
override init(nibName: String?, bundle: Bundle?) {
super.init(nibName: nibName, bundle: bundle)
self.modalPresentationStyle = .custom
self.transitioningDelegate = self.transitioner
}
convenience init() {
self.init(nibName:nil, bundle:nil)
}
required init?(coder: NSCoder) {
fatalError("NSCoding not supported")
}
}
All the work is done by the transitioning delegate:
class CAVTransitioner : NSObject, UIViewControllerTransitioningDelegate {
func presentationController(
forPresented presented: UIViewController,
presenting: UIViewController?,
source: UIViewController)
-> UIPresentationController? {
return MyPresentationController(
presentedViewController: presented, presenting: presenting)
}
}
class MyPresentationController : UIPresentationController {
func decorateView(_ v:UIView) {
// iOS 8 doesn't have this
// v.layer.borderColor = UIColor.blue.cgColor
// v.layer.borderWidth = 2
v.layer.cornerRadius = 8
let m1 = UIInterpolatingMotionEffect(
keyPath:"center.x", type:.tiltAlongHorizontalAxis)
m1.maximumRelativeValue = 10.0
m1.minimumRelativeValue = -10.0
let m2 = UIInterpolatingMotionEffect(
keyPath:"center.y", type:.tiltAlongVerticalAxis)
m2.maximumRelativeValue = 10.0
m2.minimumRelativeValue = -10.0
let g = UIMotionEffectGroup()
g.motionEffects = [m1,m2]
v.addMotionEffect(g)
}
override func presentationTransitionWillBegin() {
self.decorateView(self.presentedView!)
let vc = self.presentingViewController
let v = vc.view!
let con = self.containerView!
let shadow = UIView(frame:con.bounds)
shadow.backgroundColor = UIColor(white:0, alpha:0.4)
shadow.alpha = 0
con.insertSubview(shadow, at: 0)
shadow.autoresizingMask = [.flexibleWidth, .flexibleHeight]
let tc = vc.transitionCoordinator!
tc.animate(alongsideTransition: { _ in
shadow.alpha = 1
}) { _ in
v.tintAdjustmentMode = .dimmed
}
}
override func dismissalTransitionWillBegin() {
let vc = self.presentingViewController
let v = vc.view!
let con = self.containerView!
let shadow = con.subviews[0]
let tc = vc.transitionCoordinator!
tc.animate(alongsideTransition: { _ in
shadow.alpha = 0
}) { _ in
v.tintAdjustmentMode = .automatic
}
}
override var frameOfPresentedViewInContainerView : CGRect {
// we want to center the presented view at its "native" size
// I can think of a lot of ways to do this,
// but here we just assume that it *is* its native size
let v = self.presentedView!
let con = self.containerView!
v.center = CGPoint(x: con.bounds.midX, y: con.bounds.midY)
return v.frame.integral
}
override func containerViewWillLayoutSubviews() {
// deal with future rotation
// again, I can think of more than one approach
let v = self.presentedView!
v.autoresizingMask = [
.flexibleTopMargin, .flexibleBottomMargin,
.flexibleLeftMargin, .flexibleRightMargin
]
v.translatesAutoresizingMaskIntoConstraints = true
}
}
extension CAVTransitioner { // UIViewControllerTransitioningDelegate
func animationController(
forPresented presented:UIViewController,
presenting: UIViewController,
source: UIViewController)
-> UIViewControllerAnimatedTransitioning? {
return self
}
func animationController(
forDismissed dismissed: UIViewController)
-> UIViewControllerAnimatedTransitioning? {
return self
}
}
extension CAVTransitioner : UIViewControllerAnimatedTransitioning {
func transitionDuration(
using transitionContext: UIViewControllerContextTransitioning?)
-> TimeInterval {
return 0.25
}
func animateTransition(
using transitionContext: UIViewControllerContextTransitioning) {
let con = transitionContext.containerView
let v1 = transitionContext.view(forKey: .from)
let v2 = transitionContext.view(forKey: .to)
// we are using the same object (self) as animation controller
// for both presentation and dismissal
// so we have to distinguish the two cases
if let v2 = v2 { // presenting
con.addSubview(v2)
let scale = CGAffineTransform(scaleX: 1.6, y: 1.6)
v2.transform = scale
v2.alpha = 0
UIView.animate(withDuration: 0.25, animations: {
v2.alpha = 1
v2.transform = .identity
}) { _ in
transitionContext.completeTransition(true)
}
} else if let v1 = v1 { // dismissing
UIView.animate(withDuration: 0.25, animations: {
v1.alpha = 0
}) { _ in
transitionContext.completeTransition(true)
}
}
}
}
It looks like a lot of code, and I suppose it is, but it's almost entire confined to a single class, which is entirely boilerplate; just copy and paste. All you have to do is write the internal interface and behavior of your "alert" view controller, giving it buttons and text and whatever else you want, just as you would do for any other view controller.
Custom Alert UIView Class in swift 4. And Usage ##
import UIKit
class Dialouge: UIView {
#IBOutlet weak var lblTitle: UILabel!
#IBOutlet weak var lblDescription: UILabel!
#IBOutlet weak var btnLeft: UIButton!
#IBOutlet weak var btnRight: UIButton!
#IBOutlet weak var viewBg: UIButton!
var leftAction = {}
var rightAction = {}
override func draw(_ rect: CGRect)
{
self.btnRight.layer.cornerRadius = self.btnRight.frame.height/2
self.btnLeft.layer.cornerRadius = self.btnLeft.frame.height/2
self.btnLeft.layer.borderWidth = 1.0
self.btnLeft.layer.borderColor = #colorLiteral(red: 0.267678082, green: 0.2990377247, blue: 0.7881471515, alpha: 1)
}
#IBAction func leftAction(_ sender: Any) {
leftAction()
}
#IBAction func rightAction(_ sender: Any) {
rightAction()
}
#IBAction func bgTapped(_ sender: Any) {
self.removeFromSuperview()
}
}
strong text
## Usage Of Custom Alert with Tabbar.
let custView = Bundle.main.loadNibNamed("Dialouge", owner: self, options:
nil)![0] as? Dialouge
custView?.lblDescription.text = "Are you sure you want to delete post?"
custView?.lblTitle.text = "Delete Post"
custView?.btnLeft.setTitle("Yes", for: .normal)
custView?.btnRight.setTitle("No", for: .normal)
custView?.leftAction = {
self.deletePost(postId: self.curr_post.id,completion: {
custView?.removeFromSuperview()
})
}
custView?.rightAction = {
custView?.removeFromSuperview()
}
if let tbc = self.parentt?.tabBarController {
custView?.frame = tbc.view.frame
DispatchQueue.main.async {
tbc.view.addSubview(custView!)
}
}else if let tbc = self.parView?.parenttprof {
custView?.frame = tbc.view.frame
DispatchQueue.main.async {
tbc.view.addSubview(custView!)
}
}
else
{
custView?.frame = self.parView?.view.frame ?? CGRect.zero
DispatchQueue.main.async {
self.parView?.view.addSubview(custView!)
}
}
Use https://github.com/shantaramk/Custom-Alert-View
It is effortless to implement this. Follow the steps below:
Drag down the AlertView folder in project directory
Show AlertView Popup
func showUpdateProfilePopup(_ message: String) {
let alertView = AlertView(title: AlertMessage.success, message: message, okButtonText: LocalizedStrings.okay, cancelButtonText: "") { (_, button) in
if button == .other {
self.navigationController?.popViewController(animated: true)
}
}
alertView.show(animated: true)
}

Resources