Tabbar controller issue - ios

I am using tab bar controller using xib but when I include one vc there is space remaining in that vc at the end. Here is video of my problem
Here is my viewcontroller xib and code
Please help me with it
here is my tabbar controller code
import UIKit
class TabbarControllerVC: UITabBarController, UITabBarControllerDelegate{
let homeVC = HomeVC(nibName: "HomeVC", bundle: nil)
let listVC = HomeVC(nibName: "HomeVC", bundle: nil)
let notificationVC = HomeVC(nibName: "HomeVC", bundle: nil)
let settingVC = MyProfileVC(nibName: "MyProfileVC", bundle: nil)
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
tabBar.tintColor = ColorConstants.ThemeColor
var tabbarControllers = [UIViewController]()
tabbarControllers.append(homeVC)
tabbarControllers.append(listVC)
tabbarControllers.append(notificationVC)
tabbarControllers.append(settingVC)
self.setViewControllers(tabbarControllers, animated: true)
homeVC.tabBarItem = UITabBarItem(title: "", image: UIImage(named : "Home"), selectedImage: UIImage(named : "Home"))
listVC.tabBarItem = UITabBarItem(title: "", image: UIImage(named : "List"), selectedImage: UIImage(named : "List"))
notificationVC.tabBarItem = UITabBarItem(title: "", image: UIImage(named : "Notification"), selectedImage: UIImage(named : "Notification"))
settingVC.tabBarItem = UITabBarItem(title: "", image: UIImage(named : "Setting"), selectedImage: UIImage(named : "Setting"))
UITabBar.appearance().tintColor = ColorConstants.ThemeColor
homeVC.tabBarItem.imageInsets = UIEdgeInsets(top: 4, left: 0, bottom: -4, right: 0)
listVC.tabBarItem.imageInsets = UIEdgeInsets(top: 4, left: 0, bottom: -4, right: 0)
notificationVC.tabBarItem.imageInsets = UIEdgeInsets(top: 4, left: 0, bottom: -4, right: 0)
settingVC.tabBarItem.imageInsets = UIEdgeInsets(top: 4, left: 0, bottom: -4, right: 0)
if #available(iOS 10.0, *) {
UITabBar.appearance().unselectedItemTintColor = ColorConstants.BlackColor
} else {
UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: ColorConstants.BlackColor], for: .normal)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func setupTabBarSeparators() {
let itemWidth = floor(self.tabBar.frame.size.width / CGFloat(self.tabBar.items!.count))
// this is the separator width. 0.5px matches the line at the top of the tab bar
let separatorWidth: CGFloat = 0.5
// iterate through the items in the Tab Bar, except the last one
for i in 0...(self.tabBar.items!.count - 1) {
// make a new separator at the end of each tab bar item
let separator = UIView(frame: CGRect(x: itemWidth * CGFloat(i + 1) - CGFloat(separatorWidth / 2) , y: 15, width: CGFloat(separatorWidth), height: self.tabBar.frame.size.height - 30))
// set the color to light gray (default line color for tab bar)
separator.backgroundColor = UIColor.lightGray
self.tabBar.addSubview(separator)
}
}
override func viewWillAppear(_ animated : Bool){
super.viewWillAppear(true)
setupTabBarSeparators()
}
}

Related

UITabBarController is not fitted to the screen in iOS Swift?

I have been implemented UITabBarController programmatically. Functionality works fine but the UITabBarController is not fitting inside the screen.
here is my code:
class ViewController: UIViewController {
let tabBarCnt = UITabBarController()
override func viewDidLoad() {
super.viewDidLoad()
tabBarCnt.tabBar.tintColor = UIColor.black
createTabBarController()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
addHeightConstraintToTabbar()
}
func addHeightConstraintToTabbar() -> Void {
let heightConstant:CGFloat = self.view.safeAreaInsets.bottom + 49.0
tabBarCnt.tabBar.heightAnchor.constraint(equalToConstant: heightConstant).isActive = true
}
func createTabBarController() {
let firstVc = UIViewController()
firstVc.title = "First"
firstVc.view.backgroundColor = UIColor.red
firstVc.tabBarItem = UITabBarItem.init(title: "Home", image: UIImage(named: "HomeTab"), tag: 0)
let secondVc = UIViewController()
secondVc.title = "Second"
secondVc.view.backgroundColor = UIColor.green
secondVc.tabBarItem = UITabBarItem.init(title: "Location", image: UIImage(named: "Location"), tag: 1)
let controllerArray = [firstVc, secondVc]
tabBarCnt.viewControllers = controllerArray.map{ UINavigationController.init(rootViewController: $0)}
self.view.addSubview(tabBarCnt.view)
}
}
Result screenshot
Add this line:
tabBarCnt.additionalSafeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

Perform Segue is not working when i am using programmatic UI

I am creating an app for my personal project using programmaticUI and storyboard for the UI part, but i found an issue when i tried to performSegue from my "SecondViewController" to my "ThirdViewController" , i added the "identifier" in my segue like usual:
And then i called the "performSegue" from my SecondViewController:
import UIKit
class SecondViewController: UIViewController {
private var myItem = [SecondItem]()
lazy var myTableView : UITableView = {
let myTable = UITableView()
myTable.translatesAutoresizingMaskIntoConstraints = false
return myTable
}()
private let myContentView : UIView = {
let view = UIView()
view.backgroundColor = .gray
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
lazy var label : UILabel = {
let myLabel = UILabel()
myLabel.text = "Hello"
return myLabel
}()
private let unameTextField : UITextField = {
let txtField = UITextField()
txtField.backgroundColor = .white
txtField.placeholder = "Username"
txtField.borderStyle = .roundedRect
txtField.translatesAutoresizingMaskIntoConstraints = false
return txtField
}()
private let pwordTxtField : UITextField = {
let txtField = UITextField()
txtField.placeholder = "Password"
txtField.borderStyle = .roundedRect
txtField.translatesAutoresizingMaskIntoConstraints = false
return txtField
}()
private let loginBtn : UIButton = {
let btn = UIButton(type: .system)
btn.backgroundColor = .blue
btn.setTitle("Login", for: .normal)
btn.tintColor = .white
btn.layer.cornerRadius = 5
btn.clipsToBounds = true
btn.translatesAutoresizingMaskIntoConstraints = false
btn.addTarget(self, action: #selector(btnPressed), for: .touchUpInside)
return btn
}()
//I called the "performSegue" here
#objc func btnPressed() {
performSegue(withIdentifier: "gotoBla", sender: self)
print("button pressed")
}
lazy var imageView : UIImageView = {
let image = UIImage(named: "image_4")
let imageView = UIImageView(image: image)
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
func setAutoLayout(){
let guide = view.safeAreaLayoutGuide
myContentView.anchor(top: guide.topAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: view.frame.height / 3, enableInsets: true)
imageView.anchor(top: myContentView.topAnchor, left: nil , bottom: nil , right: nil , paddingTop: 10, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 80, height: 80, enableInsets: true)
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
unameTextField.anchor(top: imageView.bottomAnchor, left: myContentView.leftAnchor, bottom: nil, right: myContentView.rightAnchor, paddingTop: 10, paddingLeft: 20, paddingBottom: 5, paddingRight: 20, width: 0, height: 40, enableInsets: true)
pwordTxtField.anchor(top: unameTextField.bottomAnchor, left: myContentView.leftAnchor, bottom: nil, right: myContentView.rightAnchor, paddingTop: 30, paddingLeft: 20, paddingBottom: 0, paddingRight: 20, width: 0, height: 40, enableInsets: true)
loginBtn.anchor(top: pwordTxtField.bottomAnchor, left: myContentView.leftAnchor, bottom: nil, right: myContentView.rightAnchor , paddingTop: 20, paddingLeft: 20, paddingBottom: 0, paddingRight: 20, width: 0, height: 40, enableInsets: true)
//TableView
myTableView.topAnchor.constraint(equalTo: myContentView.bottomAnchor).isActive = true
myTableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
myTableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
myTableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
override func viewDidLoad() {
super.viewDidLoad()
myItem.append(SecondItem(text: "first"))
myItem.append(SecondItem(text: "Second"))
myItem.append(SecondItem(text: "Third"))
view.backgroundColor = .white
view.addSubview(myContentView)
myContentView.addSubview(unameTextField)
myContentView.addSubview(pwordTxtField)
myContentView.addSubview(loginBtn)
myContentView.addSubview(imageView)
myTableView.register(SecondTableViewCell.self, forCellReuseIdentifier: K.SecondTableViewCell.identifier)
myTableView.delegate = self
myTableView.dataSource = self
view.addSubview(myTableView)
setAutoLayout()
}
}
extension SecondViewController : UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(indexPath.row)
}
}
extension SecondViewController : UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
myItem.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: K.SecondTableViewCell.identifier, for: indexPath) as! SecondTableViewCell
cell.second = myItem[indexPath.row]
cell.selectionStyle = .none
return cell
}
}
And for the Third View Controller, i am not yet adding some code in there
import UIKit
class ThirdViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
But everytime i run the app and click the login button,it always gave me this error:
This is what my app looks like:
Do i miss something here? I am a beginner by the way, i hope you guys can help me. Thank you
When posting questions here, it would be good for you to take a few minutes to review How to Ask
However, based on the little bit of info you've provided...
Almost certainly the problem is that you are adding View Controllers in Storyboard and then improperly trying to use them via code.
For example, I'm guessing that you have code in your "first" view controller to load and display SecondViewController like this:
#objc func showSecondTapped(_ sender: Any) {
let vc = SecondViewController()
navigationController?.pushViewController(vc, animated: true)
}
and then in SecondViewController you're trying to use the Storyboard associated segue with this:
#objc func btnPressed(_ sender: Any) {
performSegue(withIdentifier: "gotoBla", sender: self)
print("button pressed")
}
However, that segue doesn't exist as part of SecondViewController code ... it is part of the Storyboard object.
Back in your first view controller, if you load and push to SecondViewController like this:
#objc func showSecondTapped(_ sender: Any) {
if let vc = storyboard?.instantiateViewController(withIdentifier: "secondVC") as? SecondViewController {
navigationController?.pushViewController(vc, animated: true)
}
}
you will then be able to call performSegue because you loaded it from the Storyboard.
if let vc = storyboard?.instantiateViewController(withIdentifier: "secondVC") as? SecondViewController {
navigationController?.pushViewController(vc, animated: true)
// if navigationController?.pushViewController doesn't work you can try this
present(vc, animated: true) {
// anything you want to perform after presenting new screen
}
// and try this to show in full screen with different transition effect
vc.modalTransitionStyle = .crossDissolve
vc.modalPresentationStyle = .fullScreen
present(vc, animated: true) {
// anything you want to perform after presenting new screen
}
}

iOS Swift Code - Just working when i have a breakpoint on it

I have a tab coordinator that extends from a parent coordinator; i want to assign a delegate to the UITabViewController; but when i do it, it doesn't trigger anything; but if i have a breakpoint in the init function of my coordinator; it will work as expected. My brain is going to explode because i don't know where to search the bug, as it is working as expected when XCODE does have a breakpoint.
import RxSwift
enum HomeRoutes: Route{
case explore
case swaps
case post
case notifications
case profile
}
class HomeCoordinator: ViewCoordinator<HomeRoutes> {
typealias Dependencies = HasUserManager & HasItemService
// MARK: - Stored properties
private let viewDelegate = CrowdswapTabDelegate()
private let disposeBag = DisposeBag()
convenience init(dependencies: Dependencies) {
//Create Tabs
let exploreTab = ExploreCoordinator(dependencies: dependencies)
exploreTab.rootViewController.navigationBar.isHidden = true
exploreTab.rootViewController.tabBarItem = UITabBarItem(title: nil, image: #imageLiteral(resourceName: "explore"), selectedImage: nil)
exploreTab.rootViewController.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
let swapsTab = SwapsCoordinator(dependencies:dependencies)
swapsTab.rootViewController.navigationBar.isHidden = true
swapsTab.rootViewController.tabBarItem = UITabBarItem(title: nil, image: #imageLiteral(resourceName: "swaps"), selectedImage: nil)
swapsTab.rootViewController.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
let postTab = PostCoordinator(dependencies: dependencies)
postTab.rootViewController.navigationBar.isHidden = true
postTab.rootViewController.tabBarItem = UITabBarItem(title: nil, image: #imageLiteral(resourceName: "upload"), selectedImage: nil)
postTab.rootViewController.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
let notificationTab = NotificationCoordinator()
notificationTab.rootViewController.navigationBar.isHidden = true
notificationTab.rootViewController.tabBarItem = UITabBarItem(title: nil, image: #imageLiteral(resourceName: "notifications"), selectedImage: nil)
notificationTab.rootViewController.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
let profileTab = ProfileCoordinator(dependencies: dependencies)
profileTab.rootViewController.navigationBar.isHidden = true
profileTab.rootViewController.tabBarItem = UITabBarItem(title: nil, image: #imageLiteral(resourceName: "profile"), selectedImage: nil)
profileTab.rootViewController.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
let tabBarController = UITabBarController()
tabBarController.tabBar.tintColor = UIColor(red:0.21, green:0.17, blue:0.46, alpha:1.0)
tabBarController.tabBar.backgroundColor = UIColor.white
tabBarController.tabBar.isTranslucent = false
tabBarController.tabBar.backgroundImage = UIImage()
tabBarController.tabBar.layer.borderWidth = 0.0
tabBarController.tabBar.clipsToBounds = true
tabBarController.viewControllers = [exploreTab.rootViewController, swapsTab.rootViewController, postTab.rootViewController, notificationTab.rootViewController, profileTab.rootViewController]
self.init(controller: tabBarController)
}
// MARK: - Init
init(controller: UITabBarController) {
controller.delegate = viewDelegate
super.init(root: controller)
}
}
And here is my viewDelegate:
class CrowdswapTabDelegate: NSObject, UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
/// Prevent selection of the same tab twice (which would reset its navigation controller)
if viewController.tabBarItem.image == #imageLiteral(resourceName: "upload") {
return false
}
if let viewController = viewController.children[0] as? ExploreViewController{
if tabBarController.selectedIndex == 0 {
viewController.collectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
}
return true
}
return true
}
}
OK. I solved it; first thought was that it was a problem about threads or a race-condition; but it seemed it was that as the delegate is a weak reference; it wasnt retained BUT when i have a breakpoint, the IDE retained the delegate, so it worked.
solution was to have the delegate parent as a stored property, to have the delegate retained by the parent.

Having an issue in Menu Tabs. And I am using carbonKit Framework

I want both tabs(Hello World, Tab) equal width of controller width . I put the complete code of my tabs. if anyone have suggestion for it. plz give suggestion.i am waiting. Comment & Answer Fast.
import UIKit
import CarbonKit
class ViewController: UIViewController, CarbonTabSwipeNavigationDelegate {
func generateImage(for view: UIView) -> UIImage? {
defer {
UIGraphicsEndImageContext()
}
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale)
if let context = UIGraphicsGetCurrentContext() {
view.layer.render(in: context)
return UIGraphicsGetImageFromCurrentImageContext()
}
return nil
}
var iconWithTextImage: UIImage {
let button = UIButton()
let icon = UIImage(named: "home")
button.setImage(icon, for: .normal)
button.setTitle("Home", for: .normal)
button.setTitleColor(UIColor.blue, for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 15)
button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 10)
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -10, bottom: 0, right: 10)
button.sizeToFit()
return generateImage(for: button) ?? UIImage()
}
override func viewDidLoad() {
super.viewDidLoad()
let tabSwipe = CarbonTabSwipeNavigation(items: ["HELLO WORLD", "Tab"], delegate: self)
tabSwipe.setTabExtraWidth(40)
tabSwipe.insert(intoRootViewController: self)
}
func carbonTabSwipeNavigation(_ carbonTabSwipeNavigation: CarbonTabSwipeNavigation, viewControllerAt index: UInt) -> UIViewController {
guard let storyboard = storyboard else { return UIViewController() }
if index == 0 {
return storyboard.instantiateViewController(withIdentifier: "FirstViewController")
}
return storyboard.instantiateViewController(withIdentifier: "SecondTableViewController")
}
}
This helps you.
First of all set carbonSegmentControl frame to Screen equal Width like this.
var frameRect: CGRect = (carbonTabSwipeNavigation.carbonSegmentedControl?.frame)!
frameRect.size.width = UIScreen.main.bounds.size.width
carbonTabSwipeNavigation.carbonSegmentedControl?.frame = frameRect
After that write this line for equal width.
carbonTabSwipeNavigation.carbonSegmentedControl?.apportionsSegmentWidthsByContent = false
1. Before Equal Width
2. After Equal Width

How to set image in a tab bar item in Swift?

I have taken a view controller & embedded it in a navigation Controller and again this has been embedded in a tab bar controller. when I am trying to set a image via story board, the image does not appear on a tab bar icon. Here image name is 25.
What can I do? How can I do it programmatically? what should I take proper image size for this purpose?
In your MainTabbarViewController
Bind the outlet of your tabbar:
#IBOutlet weak var myTabBar: UITabBar?
override func viewDidLoad() {
super.viewDidLoad()
myTabBar?.tintColor = UIColor.white
tabBarItem.title = ""
setTabBarItems()
}
set the tabbar items here defined method below:
func setTabBarItems(){
let myTabBarItem1 = (self.tabBar.items?[0])! as UITabBarItem
myTabBarItem1.image = UIImage(named: "Unselected")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
myTabBarItem1.selectedImage = UIImage(named: "Selected ")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
myTabBarItem1.title = ""
myTabBarItem1.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
let myTabBarItem2 = (self.tabBar.items?[1])! as UITabBarItem
myTabBarItem2.image = UIImage(named: "Unselected")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
myTabBarItem2.selectedImage = UIImage(named: "Selected")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
myTabBarItem2.title = ""
myTabBarItem2.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
let myTabBarItem3 = (self.tabBar.items?[2])! as UITabBarItem
myTabBarItem3.image = UIImage(named: "Unselected")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
myTabBarItem3.selectedImage = UIImage(named: "Selected")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
myTabBarItem3.title = ""
myTabBarItem3.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
let myTabBarItem4 = (self.tabBar.items?[3])! as UITabBarItem
myTabBarItem4.image = UIImage(named: "Unselected")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
myTabBarItem4.selectedImage = UIImage(named: "Selected")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
myTabBarItem4.title = ""
myTabBarItem4.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
}
add AppDelegate class :
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
window=UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = setTabbar()
self.window?.makeKeyAndVisible()
window?.backgroundColor=UIColor.white
return true
}
func setTabbar() -> UITabBarController
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let tabbarcntrl = UITabBarController()
let Home = storyboard.instantiateViewController(withIdentifier: "HomeView") // 1st tab bar viewcontroller
let Followed = storyboard.instantiateViewController(withIdentifier: "FollowedView") // 2nd tab bar viewcontroller
let Message = storyboard.instantiateViewController(withIdentifier: "MessageView") // 3rd tab bar viewcontroller
// all viewcontroller embedded navigationbar
let nvHome = UINavigationController(rootViewController: Home)
let nvFollowed = UINavigationController(rootViewController: Followed)
let nvMessage = UINavigationController(rootViewController: Message)
// all viewcontroller navigationbar hidden
nvHome.setNavigationBarHidden(true, animated: false)
nvFollowed.setNavigationBarHidden(true, animated: false)
nvMessage.setNavigationBarHidden(true, animated: false)
tabbarcntrl.viewControllers = [nvHome,nvFollowed,nvMessage]
let tabbar = tabbarcntrl.tabBar
tabbar.barTintColor = UIColor.black
tabbar.backgroundColor = UIColor.black
tabbar.tintColor = UIColor(red: 43/255, green: 180/255, blue: 0/255, alpha: 1)
//UITabBar.appearance().tintColor = UIColor.white
let attributes = [NSFontAttributeName:UIFont(name: "Montserrat-Light", size: 10)!,NSForegroundColorAttributeName:UIColor.white]
let attributes1 = [NSFontAttributeName:UIFont(name: "Montserrat-Light", size: 10)!,NSForegroundColorAttributeName:UIColor(red: 43/255, green: 180/255, blue: 0/255, alpha: 1)]
UITabBarItem.appearance().setTitleTextAttributes(attributes, for: .normal)
UITabBarItem.appearance().setTitleTextAttributes(attributes1, for: .selected)
let tabHome = tabbar.items![0]
tabHome.title = "Home" // tabbar titlee
tabHome.image=UIImage(named: "icon_home.png")?.withRenderingMode(.alwaysOriginal) // deselect image
tabHome.selectedImage = UIImage(named: "icon_home.png")?.withRenderingMode(.alwaysOriginal) // select image
tabHome.titlePositionAdjustment.vertical = tabHome.titlePositionAdjustment.vertical-4 // title position change
let tabFoll = tabbar.items![1]
tabFoll.title = "Followed"
tabFoll.image=UIImage(named: "icon_fold.png")?.withRenderingMode(.alwaysOriginal)
tabFoll.selectedImage=UIImage(named: "icon_fold.png")?.withRenderingMode(.alwaysOriginal)
tabFoll.titlePositionAdjustment.vertical = tabFoll.titlePositionAdjustment.vertical-4
let tabMsg = tabbar.items![3]
tabMsg.title = "Message"
tabMsg.image=UIImage(named: "icon_mail.png")?.withRenderingMode(.alwaysOriginal)
tabMsg.selectedImage=UIImage(named: "icon_mail.png")?.withRenderingMode(.alwaysOriginal)
tabMsg.titlePositionAdjustment.vertical = tabMsg.titlePositionAdjustment.vertical-4
return tabbarcntrl
}
Set both images- for select/selected state
You are doing all the things in right way But the only problem is your tabbaritem image is not in correct size .Just look this table for actual size of tabbaritem images.
In swift 4 and 5 you can use the below extension. Remember one thing always pass the same number of images , selected images and title but if you do not want to set title then pass nil in title.
extension UITabBarController{
func setUpImagaOntabbar(_ selectedImage : [UIImage], _ image : [UIImage], _ title : [String]?){
for (index,vals) in image.enumerated(){
if let tab = self.tabBar.items?[index]{
tab.image = image[index]
tab.image = selectedImage[index]
if let tile = title[index]{
tab.title = title[index]
}
}
}
}
}

Resources