Reload UITabBarController on demand - ios

I have the following TabBarController with 2 items. It is showing correctly.
I'm calling the setupItems() function from another controller when something changes its value.
The function is called correctly, the problem is that the navFirstController.tabBarItem.image is not being updated.
class TabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
setupItems()
}
func setupItems() {
let scale: CGFloat = 0.35
let navFirstController = UINavigationController(rootViewController: FirstController())
let navSecondController = UINavigationController(rootViewController: SecondController())
navSecondController.tabBarItem.image = UIImage.scale(image: UIImage(named: "image2")!, by: scale)
navSecondController.tabBarItem.imageInsets = UIEdgeInsets(top: 8, left: 0, bottom: -8, right: 0)
if something == true {
navFirstController.tabBarItem.image = UIImage.scale(image: UIImage(named: "image1")!, by: scale)
} else {
navFirstController.tabBarItem.image = UIImage.scale(image: UIImage(named: "image3")!, by: scale)
}
navFirstController.tabBarItem.imageInsets = UIEdgeInsets(top: 8, left: 0, bottom: -8, right: 0)
viewControllers = [navSecondController, navFirstController]
}
}
I'ved tried with:
1) viewControllers?.remove(at: 1) at the beginning of setupItems()
2) navFirstController.removeFromParent() at the beginning of setupItems()
3) self.viewWillLayoutSubviews() at the end of setupItems()
4) self.view.setNeedsLayout(), self.view.setNeedsDisplay() at the end of setupItems()

I don't feel we need to create viewControllers object again just to change tab bar image.
Just we need to get viewController object from viewControllers array and change image.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func btnClicked(_ sender: Any) {
//change image of tab bar item on button clicked
if let tabVC = self.tabBarController as? TabBarController {
tabVC.changeImage()
}
}
}
class TabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
setupItems()
}
func setupItems() {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let firstVC = storyboard.instantiateViewController(withIdentifier: "First")
let navFirstController = UINavigationController(rootViewController: firstVC)
navFirstController.tabBarItem.image = UIImage(named: "Image1")
let secondVC = storyboard.instantiateViewController(withIdentifier: "Second")
let navSecondController = UINavigationController(rootViewController: secondVC)
navSecondController.tabBarItem.image = UIImage(named: "Image2")
viewControllers = [navSecondController, navFirstController]
}
func changeImage() {
if let second = viewControllers?[1] as? UINavigationController {
second.tabBarItem.selectedImage = UIImage(named: "Image3")
second.tabBarItem.image = UIImage(named: "Image3")
}
}
}
Note if you want to change selected tab bar item image then change "selectedImage" value otherwise change "image" value.

You probably need to set the image's rendering mode to UIImageRenderingModeAlwaysOriginal.
Try changing this:
navFirstController.tabBarItem.image = UIImage.scale(image: UIImage(named: "image1")!, by: scale)
With this:
navFirstController.tabBarItem.image = UIImage.scale(image: UIImage(named: "image1")!, by: scale).withRenderingMode(.alwaysOriginal)
EDIT - Sample Code
Consider this setup:
The initial view controller is a custom class TabBarViewController
The red background view controller is a UIViewController with storyboard ID "First"
The orange background view controller is a custom class SecondViewController with an IBAction and storyboard ID "Second"
The Assets.xcassets file has three images (40x40 png):
TabBarViewController
import UIKit
class TabBarViewController: UITabBarController {
var something: Bool = false
override func viewDidLoad() {
super.viewDidLoad()
setupItems()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
func setupItems() {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let firstVC = storyboard.instantiateViewController(withIdentifier: "First")
let navFirstController = UINavigationController(rootViewController: firstVC)
navFirstController.tabBarItem.image = UIImage(named: "image1")!.withRenderingMode(.alwaysOriginal)
let secondVC = storyboard.instantiateViewController(withIdentifier: "Second")
let navSecondController = UINavigationController(rootViewController: secondVC)
navSecondController.tabBarItem.image = UIImage(named: "image2")!.withRenderingMode(.alwaysOriginal)
navSecondController.tabBarItem.imageInsets = UIEdgeInsets(top: 8, left: 0, bottom: -8, right: 0)
if something == true {
navFirstController.tabBarItem.image = UIImage(named: "image3")!.withRenderingMode(.alwaysOriginal)
} else {
navFirstController.tabBarItem.image = UIImage(named: "image1")!.withRenderingMode(.alwaysOriginal)
}
navFirstController.tabBarItem.imageInsets = UIEdgeInsets(top: 8, left: 0, bottom: -8, right: 0)
viewControllers = [navSecondController, navFirstController]
}
}
SecondViewController
import Foundation
import UIKit
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func btnClicked(_ sender: Any) {
//change image of tab bar item on button clicked
if let tabVC = self.tabBarController as? TabBarViewController {
tabVC.something = !tabVC.something
tabVC.setupItems()
}
}
}
OUTPUT

Related

Config Navigation bar only work if viewControllers are created inside viewWillAppear in UITabBarController

I have a UITabBarController with 2 ViewControllers: HomeViewController and ProfileViewController
Inside HomeViewController, I have to change the NavigationBar appearance with the following code:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let nav = self.navigationController {
nav.navigationBar.layer.zPosition = 0
}
let logo = UIImage(named: "plentinaText")?.withRenderingMode(.alwaysTemplate)
let container = UIView(frame: CGRect(x: 0, y: 0, width: 1000, height: 0))
let imageView = UIImageView(image: logo)
imageView.tintColor = .white
imageView.contentMode = .scaleAspectFit
container.addSubview(imageView)
imageView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
imageView.topAnchor.constraint(equalTo: container.topAnchor),
imageView.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -10),
imageView.centerXAnchor.constraint(equalTo: container.centerXAnchor),
imageView.widthAnchor.constraint(equalToConstant: view.frame.width)
])
self.tabBarController?.navigationItem.titleView = container
}
Problem is, this block of code only work if I create HomeViewController ProfileViewController inside viewWillAppear in UITabBarController.
If I put it in ViewDidLoad, it don't even have a NavigationBar. But when I push to another vc and go back to HomeViewController, the Nav bar will work as I wanted.
//
// HomeTabbarController.swift
// Plentina
//
// Created on 10/29/21.
//
import UIKit
class HomeTabbarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
UITabBar.appearance().barTintColor = PlenitaColors.buttonBackGround // your color
if #available(iOS 13.0, *) {
UITabBar.appearance().unselectedItemTintColor = UIColor.systemGray4
} else {
UITabBar.appearance().unselectedItemTintColor = UIColor.lightGray
}
UITabBar.appearance().tintColor = .white
if #available(iOS 15.0, *) {
let appearance = UITabBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = PlenitaColors.buttonBackGround
tabBar.standardAppearance = appearance
tabBar.scrollEdgeAppearance = appearance
}
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// tabbar 1
let storyboard = UIStoryboard(name: "Custom", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "photo") as? HomeViewController
let item1 = viewController
let unselectedIcon1 = UIImage(named: "tabbarHome")?.withRenderingMode(.alwaysTemplate)
let selectedIcon1 = UIImage(named: "tabbarHome")!.withRenderingMode(.alwaysTemplate)
let icon1 = UITabBarItem(title: "Loans", image: unselectedIcon1, selectedImage: selectedIcon1)
item1!.tabBarItem = icon1
// tabbar 2
let unselectedIcon2 = UIImage(named: "tabbarProfile")?.withRenderingMode(.alwaysTemplate)
let selectedIcon2 = UIImage(named: "tabbarProfile")!.withRenderingMode(.alwaysTemplate)
let item2 = ProfileViewController()
let icon2 = UITabBarItem(title: "Profile", image: unselectedIcon2, selectedImage: selectedIcon2)
item2.tabBarItem = icon2
let controllers = [item1!, item2] // array of the root view controllers displayed by the tab bar interface
self.viewControllers = controllers
}
// Delegate methods
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
print("Should select viewController: \(viewController.title ?? "") ?")
return true
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
I found a workaround. I just need to leave self.viewControllers = controllers in viewWillAppear and move the rest to ViewDidLoad, but I still don't know why?
class HomeTabbarController: UITabBarController, UITabBarControllerDelegate {
var controllers: [Any]?
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
UITabBar.appearance().barTintColor = PlenitaColors.buttonBackGround // your color
if #available(iOS 13.0, *) {
UITabBar.appearance().unselectedItemTintColor = UIColor.systemGray4
} else {
UITabBar.appearance().unselectedItemTintColor = UIColor.lightGray
}
UITabBar.appearance().tintColor = .white
if #available(iOS 15.0, *) {
let appearance = UITabBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = PlenitaColors.buttonBackGround
tabBar.standardAppearance = appearance
tabBar.scrollEdgeAppearance = appearance
}
// tabbar 1
let storyboard = UIStoryboard(name: "Custom", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "photo") as? HomeViewController
let item1 = viewController
let unselectedIcon1 = UIImage(named: "tabbarHome")?.withRenderingMode(.alwaysTemplate)
let selectedIcon1 = UIImage(named: "tabbarHome")!.withRenderingMode(.alwaysTemplate)
let icon1 = UITabBarItem(title: "Loans", image: unselectedIcon1, selectedImage: selectedIcon1)
item1!.tabBarItem = icon1
// tabbar 2
let unselectedIcon2 = UIImage(named: "tabbarProfile")?.withRenderingMode(.alwaysTemplate)
let selectedIcon2 = UIImage(named: "tabbarProfile")!.withRenderingMode(.alwaysTemplate)
let item2 = ProfileViewController()
let icon2 = UITabBarItem(title: "Profile", image: unselectedIcon2, selectedImage: selectedIcon2)
item2.tabBarItem = icon2
controllers = [item1!, item2] // array of the root view controllers displayed by the tab bar interface
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.viewControllers = controllers as? [UIViewController]
}
// Delegate methods
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
print("Should select viewController: \(viewController.title ?? "") ?")
return true
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}

TableViews not working with TabBarController Swift

I have an app with a tableView. I decided to add more screens with other tableViews, so I added a tabBarController programatically. Now I get a found nil error on these lines:
tableView.delegate = self
tableView.dataSource = self
If I remove them, the tableView doesn't load. Do you know what I might be doing wrong?
I added a tabBarController on main storyboard an linked it to the swift file, but it also doesn't work.
class SecondVC: UIViewController,UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var SoundsClasss = [SoundsClass]()
override func viewDidLoad() {
super.viewDidLoad()
let p1 = SoundsClass(imageURL: "sound 01", audioURL: "01", videoTitle: "1", duration: 100)
let p2 = SoundsClass(imageURL: "sound 01", audioURL: "02", videoTitle: "2", duration: 100)
SoundsClasss.append(p1)
SoundsClasss.append(p2)
tableView.delegate = self
tableView.dataSource = self
}
The code for the TabBarController. Do I have to change anything here to specify that the view is a tableView?
class MainTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
tabBar.barTintColor = UIColor.white
setupTabBar()
}
func setupTabBar(){
let FirstController = UINavigationController(rootViewController: MainVC())
let SecondController = UINavigationController(rootViewController: SecondVC())
let ThirdController = UINavigationController(rootViewController: ThirdVC())
viewControllers = [FirstController, SecondController,ThirdController]
guard let items = tabBar.items else { return }
for item in items {
item.imageInsets = UIEdgeInsets(top: 4, left: 0, bottom: -4, right: 0)
}
}
}
in class named SecondVC you have an outlet reference for your UITableView instance this means you create your table view in Stroyboard, so you can not create the view controller using the initializer you should use
UIStoryboard(name: "yourStoryBoardName", bundle: nil).instantiateViewController(withIdentifier: "yourViewcontrollerID")
the setupTabBar function should be as the following
func setupTabBar(){
let vc1 = UIStoryboard(name: "yourStoryBoardName", bundle: nil).instantiateViewController(withIdentifier: "yourFirstViewcontrollerID")
let vc2 = UIStoryboard(name: "yourStoryBoardName", bundle: nil).instantiateViewController(withIdentifier: "yourSecondViewcontrollerID")
let vc3 = UIStoryboard(name: "yourStoryBoardName", bundle: nil).instantiateViewController(withIdentifier: "yourThirdViewcontrollerID")
let FirstController = UINavigationController(rootViewController: vc1)
let SecondController = UINavigationController(rootViewController: vc2)
let ThirdController = UINavigationController(rootViewController: vc3)
viewControllers = [FirstController, SecondController,ThirdController]
guard let items = tabBar.items else { return }
for item in items {
item.imageInsets = UIEdgeInsets(top: 4, left: 0, bottom: -4, right: 0)
}
}
You're using SecondVC() to create your controller. That does not reference the storyboard so it does not set up any outlets.
You need to either build your view controller hierarchy in the storyboard and let it load by default or else get your controllers from the storyboard before adding them to the navigation controllers.
See documentation for:
func instantiateViewController(withIdentifier identifier: String) -> UIViewController

UITabBar Controller Present ViewController of Second tab Without Segue

I'm eliminating the storyboard from my app completely. How do I present the VC that is linked to the second tab of the TabBarController.
Setup: mainVC --- myTabBar -- tab1 - navCntrl - VC1
tab2 - navCntrl - VC2
When using a segues I used the following code:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == myTabBar) {
let tabVC = segue.destination as? UITabBarController {
tabVC.selectedIndex = myTabBarIndex ==> 1 to reach VC2
}
// other other stuff
}
To eliminating the segues I rewrote the above but although I set the selectedIndex VC2 is not presented. Any suggestions?
func vc2Btn() {
let tabVC = MyTabBar()
tabVC.selectedIndex = 1 // ==>> Index set but can not reach VC2
present(tabVC, animated: true, completion: nil)
}
The full code of my test system:
class MyTabBar: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create Tab 1
let navCtrlTab1 = UINavigationController(rootViewController: VC1())
let tabOne = navCtrlTab1
let tabOneBarItem = UITabBarItem(title: "", image: StyleKit.imageOfIconTabRecent, selectedImage: StyleKit.imageOfIconTabRecentRev)
tabOne.tabBarItem = tabOneBarItem
// Create Tab 2
let navCtrlTab2 = UINavigationController(rootViewController: VC2())
let tabTwo = navCtrlTab2
let tabTwoBarItem = UITabBarItem(title: "", image: StyleKit.imageOfIconTabNote, selectedImage: StyleKit.imageOfIconTabNoteRev)
tabTwo.tabBarItem = tabTwoBarItem
self.viewControllers = [tabOne, tabTwo]
}
}
class mainVC: UIViewController {
let btn0: UIButton = {
let button = UIButton()
button.setBackgroundImage(StyleKit.imageOfBtnBlue(btnText: "VC1"), for: UIControlState.normal)
button.addTarget(self, action:#selector(vc1Btn), for: .touchUpInside)
return button
}()
let btn1: UIButton = {
let button = UIButton()
button.setBackgroundImage(StyleKit.imageOfBtnBlue(btnText: "VC2"), for: UIControlState.normal)
button.addTarget(self, action:#selector(vc2Btn), for: .touchUpInside)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(btn0)
self.view.addSubview(btn1)
addConstraintsWithFormat("H:|-100-[v0]", views: btn0)
addConstraintsWithFormat("H:|-100-[v0]", views: btn1)
addConstraintsWithFormat("V:|-300-[v0]-20-[v1]", views: btn0, btn1)
}
func addConstraintsWithFormat(_ format: String, views: UIView...) {
var viewsDictionary = [String: UIView]()
for (index, view) in views.enumerated() {
let key = "v\(index)"
viewsDictionary[key] = view
view.translatesAutoresizingMaskIntoConstraints = false
}
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
}
func vc1Btn() {
let tabVC = MyTabBar()
tabVC.selectedIndex = 0 // ==>> this is working
present(tabVC, animated: true, completion: nil)
}
func vc2Btn() {
let tabVC = MyTabBar()
tabVC.selectedIndex = 1 // ==>> Index set but can not reach VC2
present(tabVC, animated: true, completion: nil)
}
}
class VC1: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "VC1"
print ("VC1")
}
}
class VC2: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "VC2"
print ("VC2")
}
}
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = mainVC()
return true
}
}

programmatically creating a UITabBarController subViews not loading UITabBarItem images

I am programicaly loading Storyboards into a UITabBarController but for some reason UITabBarItem are not loading the image or selectedImage for all except the first Tab are not loading
But if you tap other tabs icons load
Loading Storyboard Example
import UIKit
class ProfileViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let defaultImag = UIImage(named: "Profile")?.withRenderingMode(.alwaysOriginal)
let selectedImag = UIImage(named: "Profile_selected")?.withRenderingMode(.alwaysOriginal)
self.tabBarItem = UITabBarItem(title: nil, image: defaultImag, selectedImage: selectedImag)
self.tabBarItem.imageInsets = UIEdgeInsets(top: 10, left: 0, bottom: -10, right: 0);
}
}
UITabBarController
import UIKit
class TabBarViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let discoverStoryboard = UIStoryboard(name: "Discover", bundle: nil)
let discoverViewController = discoverStoryboard.instantiateInitialViewController()! as UIViewController
let favouritesStoryboard = UIStoryboard(name: "Favourites", bundle: nil)
let favouritesViewController = favouritesStoryboard.instantiateInitialViewController()! as! FavouritesViewController
let profileStoryboard = UIStoryboard(name: "Profile", bundle: nil)
let profileViewController = profileStoryboard.instantiateInitialViewController()! as UIViewController
self.viewControllers = [discoverViewController, favouritesViewController, profileViewController]
}
}
private func createTabForStoryBoard(storyBoardName: String, title: String, imageName :String, tag: Int) -> (UINavigationController) {
let storyboard = UIStoryboard(name: storyBoardName as String, bundle: nil)
let viewController = storyboard.instantiateInitialViewController() as! UIViewController
let image = UIImage(named: imageName)
let tabBarItem:UITabBarItem = UITabBarItem.init(title: NSLocalizedString(title, comment: "Tab Bar Names") , image: image, tag: 0)
viewController.tabBarItem = tabBarItem
return viewController
}
// MARK: Custom Methods
func setTabBarViewControllers() {
let discoverViewController = self.createTabForStoryBoard("Discover", title: "Discover", imageName: "<image-name>", tag: 1)
let favouritesViewController = self.createTabForStoryBoard("Favourites", title: "Favourites", imageName: "<image-name>", tag: 2)
let profileViewController = self.createTabForStoryBoard("Profile", title: "Profile", imageName: "<image-name>", tag: 3)
let tabBarViewControllers = [discoverViewController, favouritesViewController, profileViewController]
self.viewControllers = tabBarViewControllers
}

iOS 10 Swift 3 UIViewController present doesn't work

I'm currently developing an application using iOS 10 and Swift 3
I think that I may have destroy the navigation between my controllers.
Indeed, when I try to present a new view controller, I have this warning on Xcode debugger.
Warning: Attempt to present FirstViewController on Project.StoryBoardManager whose view is not in the window hierarchy!
I have made some research but I'm not able to fix my bug.
I have this on my AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let storyboard = UIStoryboard(name:"Authentication", bundle: nil)
let vc = storyboard.instantiateInitialViewController() as UIViewController!
self.window?.rootViewController = vc
self.window?.makeKeyAndVisible()
return true
}
And this on my class to present news views
class StoryBoardManager: UIViewController{
fileprivate var appD = UIApplication.shared.delegate as! AppDelegate
func changeView(storyboardName: String){
let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
if let vc = storyboard.instantiateInitialViewController() {
vc.modalTransitionStyle = UIModalTransitionStyle.flipHorizontal
vc.modalPresentationStyle = UIModalPresentationStyle.fullScreen
//appD.window?.rootViewController = vc
present(vc, animated: true, completion: nil)
} else {
print("Unable to instantiate VC from \(storyboardName) storyboard")
}
}
override func viewDidLoad(){
super.viewDidLoad()
}
If I comment the update of rootViewController the new controller is not presented.
EDIT for #Zac Kwan
import Foundation
import UIKit
class CustomNavBar: UIView {
fileprivate let _storyBoardManager : StoryBoardManager = StoryBoardManager()
fileprivate var _currentUIViewController : UIViewController = UIViewController()
init() {
super.init(frame: CGRect(x: 0, y: 0, width:0, height:0))
}
func changeViewStoryboard(sender: UIButton!){
if (sender.tag == 0){
self._storyBoardManager.changeView(storyboardName: "View1")
} else if (sender.tag == 1) {
self._storyBoardManager.changeView(storyboardName: "View2")
} else if (sender.tag == 2) {
self._storyBoardManager.changeView(storyboardName: "View3")
} else {
self._storyBoardManager.changeView(storyboardName: "View4")
}
}
override init(frame: CGRect) {
super.init(frame: frame)
}
func createButton(title: String, posX: Double, witdh: Double, tag: Int, font: UIFont) -> UIButton {
let buttonCreated = UIButton(frame: CGRect(x: posX, y: 0, width: witdh, height: 60))
buttonCreated.setTitle(title, for: UIControlState())
buttonCreated.setTitleColor(CommonVariable.darkGrey, for: UIControlState())
buttonCreated.titleLabel!.font = font
buttonCreated.tag = tag
buttonCreated.addTarget(self, action:#selector(self.changeViewStoryboard(sender:)), for: UIControlEvents.touchUpInside)
buttonCreated.backgroundColor = UIColor.white
return buttonCreated
}
required init?(coder aDecoder: NSCoder) {
Super. Inuit (coder: decoder)
addSubview(self.createButton(title: « ChangeView », posX: 256.0, witdh: Double(self._sizeButton) - 1, tag: 1, font: UIFont(name: « Arial », size: 15)!))
addSubview(self.createButton(title: « ChangeView 2 », posX: 512.0, witdh: Double(self._sizeButton) - 1, tag: 2, font: UIFont(name: « Arial », size: 15)!))
}
}
Please try changing the code like below :
class StoryBoardManager: UIViewController{
fileprivate var appD = UIApplication.shared.delegate as! AppDelegate
func changeView(storyboardName: String){
let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
if let vc = storyboard.instantiateInitialViewController() {
vc.modalTransitionStyle = UIModalTransitionStyle.flipHorizontal
vc.modalPresentationStyle = UIModalPresentationStyle.fullScreen
//appD.window?.rootViewController = vc
appD.present(vc, animated: true, completion: nil)
} else {
print("Unable to instantiate VC from \(storyboardName) storyboard")
}
}
override func viewDidLoad(){
super.viewDidLoad()
}

Resources