June 2019 - Swift 4 Tutorials W3Schools

Hot

Post Top Ad

20 Jun 2019

Add View below TabBar Controller in swift - iOS

6/20/2019 11:21:00 am 0

In this post we are going to learn how to add a subview under UITabBarController in swift 5.

Add View below TabBar Controller in swift - iOS


First download the starter project from the below link:



Open the project and run, we will  see as  below images in the simulator.



Add View below TabBar Controller in swift - iOS


In this project we have Home View controller to display list of places, Detail view controller for place detail & Account view controller for second tab.

Let’s dive into the goal.

First create new swift file subclass of UIView, name it TabBarSwitchView.swift.

In this view we are going add switch. 


Replace TabBarSwitchView class with the following code:

import UIKit

class TabBarSwitchView: UIView {
    
    let onColor = UIColor(hex: 0xF9CF2D)
    
    let offColor = UIColor.white
    
    let deselectColor = UIColor(hex: 0xBFBFBF)
    
    let bgColor = UIColor(hex: 0x404040)
    
    var travellerLabel: UILabel = {
        let v = UILabel()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()
    
    var hostLabel: UILabel = {
        let v = UILabel()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()
    
    var switchButton: UISwitch = {
        let v = UISwitch()
        v.isUserInteractionEnabled = false
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()
    
    var ison: Bool = false {
        didSet {
            isTraveller = !ison
            switchButton.setOn(ison, animated: true)
            if ison {
                hostLabel.textColor = onColor
                travellerLabel.textColor = deselectColor
            }else {
                hostLabel.textColor = deselectColor
                travellerLabel.textColor = offColor
            }
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }
    
    let scale:CGFloat = 0.6
    
    func setupViews() {
        self.backgroundColor = bgColor
        self.addSubview(switchButton)
        switchButton.centerXAnchor.constraint(equalTo: centerXAnchor, constant: 0).isActive = true
        switchButton.centerYAnchor.constraint(equalTo: centerYAnchor, constant: 0).isActive = true
        switchButton.onTintColor = onColor
        switchButton.tintColor = UIColor.white
        switchButton.thumbTintColor = bgColor
        switchButton.layoutIfNeeded()
        switchButton.backgroundColor = offColor
        switchButton.layer.cornerRadius = 16
        switchButton.transform = CGAffineTransform(scaleX: scale, y: scale)
        
        self.addSubview(travellerLabel)
        travellerLabel.centerYAnchor.constraint(equalTo: centerYAnchor, constant: 0).isActive = true
        travellerLabel.trailingAnchor.constraint(equalTo: switchButton.leadingAnchor, constant: -8).isActive = true
        travellerLabel.text = "TRAVELLER"
        travellerLabel.font = UIFont.systemFont(ofSize: 12)
        travellerLabel.textColor = UIColor.white
        
        self.addSubview(hostLabel)
        hostLabel.centerYAnchor.constraint(equalTo: centerYAnchor, constant: 0).isActive = true
        hostLabel.leadingAnchor.constraint(equalTo: switchButton.trailingAnchor, constant: 8).isActive = true
        hostLabel.text = "HOST"
        hostLabel.font = UIFont.systemFont(ofSize: 12)
        hostLabel.textColor = onColor
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
}


Next create new view controller and name it as TabBarRootVC.swift.

Replace code with following code:

import UIKit

var isTraveller = false
class TabBarRootVC: UIViewController {

    private lazy var tabBarVC: CustomTabBarVC = {
        var viewController = CustomTabBarVC()
        return viewController
    }()
    
    var bottomHeight: CGFloat {
        guard #available(iOS 11.0, *),
            let window = UIApplication.shared.keyWindow else {
                return 0
        }
        return window.safeAreaInsets.bottom
    }
    
    var switchView: TabBarSwitchView = {
        let v = TabBarSwitchView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()
    
    var hideBottomBar: Bool = false {
        didSet {
            if hideBottomBar {
                heightConstraint.constant = 0
            }else {
                heightConstraint.constant = 32 + bottomHeight
            }
            UIView.animate(withDuration: 0.3) {
                self.view.layoutIfNeeded()
            }
        }
    }
    
    var heightConstraint: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
    }
    
    func setupViews() {
        self.view.backgroundColor = UIColor.white
        self.view.addSubview(switchView)
        switchView.edges([.left, .right, .bottom], to: self.view, offset: .zero)
        heightConstraint = switchView.heightAnchor.constraint(equalToConstant: 32 + bottomHeight)
        heightConstraint.isActive = true
        switchView.ison = false
        switchView.isUserInteractionEnabled = true
        switchView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(switchViewTapped(recognizer:))))
        
        addChild(tabBarVC)
        self.view.addSubview(tabBarVC.view)
        tabBarVC.view.translatesAutoresizingMaskIntoConstraints = false
        tabBarVC.view.edges([.left, .right, .top], to: self.view, offset: .zero)
        tabBarVC.view.bottomAnchor.constraint(equalTo: switchView.topAnchor, constant: 0).isActive = true
        tabBarVC.didMove(toParent: self)
        if !hideBottomBar {
            heightConstraint.constant = 32 + bottomHeight
        }else {
            heightConstraint.constant = 0
        }
        
    }
    
    @objc func switchViewTapped(recognizer: UITapGestureRecognizer) {
        switchView.ison = !switchView.ison
        isTraveller = !switchView.ison
        NotificationCenter.default.post(name: Notification.Name(rawValue: "switchChanged"), object: nil)
    }
    

}

Open utilities file and add the following extension :

extension UIViewController {
    func hideBottomSwitch(_ hide: Bool) {
        if let customTab = self.tabBarController as? CustomTabBarVC {
            customTab.hideSwitch = hide
        }
    }
}


Open CustomTabBarVC.swift file and add the following code before viewDidLoad() :

var hideSwitch: Bool = false {
    didSet {
        print("view")
        if let parentVc = self.parent as? TabBarRootVC {
            parentVc.hideBottomBar = hideSwitch
        }
    }
}

Open the HomeViewController.swift file and replace all code with the following:


import UIKit

class HomeViewController: UIViewController {
    
    var tableView: UITableView = {
        let v = UITableView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()
    
    var dataSource = [Place]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.title = "Home"
        dataSource = [Place(name: "Ocean view during daylight", hostName: "Carey", imageName: "Ocean", createdOn: "23th Mar 2019"), Place(name: "Coconut palm trees", hostName: "Stark", imageName: "Trees", createdOn: "13th Mar 2019"), Place(name: "Trees in park", hostName: "Micheal", imageName: "Park", createdOn: "28th Feb 2019"), Place(name: "Water under sunset", hostName: "Shiny", imageName: "Sunset", createdOn: "16th Feb 2019"), Place(name: "Green trees beside roadway", hostName: "Nina", imageName: "Forest", createdOn: "1st Feb 2019")]
        setupViews()
        NotificationCenter.default.addObserver(self, selector: #selector(switchChanged), name:  Notification.Name(rawValue: "switchChanged"), object: nil)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.hideBottomSwitch(false)
    }
    
    func setupViews() {
        self.navigationController?.navigationBar.isTranslucent = false
        view.addSubview(tableView)
        tableView.edges([.all], to: view.safeAreaLayoutGuide, offset: .zero)
        tableView.contentInsetAdjustmentBehavior = .never
        tableView.separatorStyle = .singleLine
        tableView.separatorInset = .zero
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: CellIds.hostCellId)
        tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: CellIds.travellerCellId)
    }
    
    @objc func switchChanged() {
        self.tableView.reloadData()
    }
}

extension HomeViewController: UITableViewDelegate {
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
    
    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 80
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let vc = DetailViewController()
        vc.place = dataSource[indexPath.row]
        vc.hidesBottomBarWhenPushed = true
        self.hideBottomSwitch(true)
        self.navigationController?.pushViewController(vc, animated: true)
    }
    
}

extension HomeViewController: UITableViewDataSource {
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataSource.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if isTraveller {
            // Traveller Cell
            let cell = tableView.dequeueReusableCell(withIdentifier: CellIds.travellerCellId, for: indexPath) as! CustomTableViewCell
            let itemAtIndex = dataSource[indexPath.row]
            cell.imgView.image = UIImage(named: itemAtIndex.imageName)
            cell.txtLabel.text = itemAtIndex.name
            cell.subtitleLabel.text = itemAtIndex.hostName
            cell.selectionStyle = .none
            return cell
        }else {
            // Host Cell
            let cell = tableView.dequeueReusableCell(withIdentifier: CellIds.hostCellId, for: indexPath) as! CustomTableViewCell
            let itemAtIndex = dataSource[indexPath.row]
            cell.imgView.image = UIImage(named: itemAtIndex.imageName)
            cell.txtLabel.text = itemAtIndex.name
            cell.subtitleLabel.text = itemAtIndex.createdOn
            cell.selectionStyle = .none
            return cell
        }
    }
    
}


Now run the project we will see output as following:

Add View below TabBar Controller in swift - iOS


Download the finished project from the following link:


Read More

11 Jun 2019

Swift UISwitch color in On state & Off state, Change Switch height in swift - iOS

6/11/2019 10:48:00 am 0

UISwitch in swift has two states either On or Off. This switches mostly see in native  settings app.

Switch colors change in swift ios


First add switch to view as below, add following code in viewDidLoad() method:

let switchButton = UISwitch()
switchButton.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(switchButton)
switchButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: 0).isActive = true
switchButton.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: 0).isActive = true
switchButton.isOn = true

Run the code, you will see switch in On state with green color.

Tap on switch to turn off, color changes to white.

Green is for On, White is for Off these are default colors for switch in swift.

Now we will change default colors,

On - Blue 
Off - Red 

Add the following to the end of viewDidLoad() method:


// Colors
switchButton.onTintColor = UIColor.blue
switchButton.tintColor = UIColor.red
switchButton.thumbTintColor = UIColor.white
switchButton.backgroundColor = UIColor.red
switchButton.layer.cornerRadius = 16

Run the code you will see different colors unlike default color for switch in ios.

Change Switch Height:  

For changing the height of switch in swift we need to do following,  Add below code to the end of viewDidLoad():

// change height
switchButton.transform = CGAffineTransform(scaleX: 0.6, y: 0.6)

Run code, we will switch button size with small size.






Read More

9 Jun 2019

Cannot preview in this file - active schema cannot build this file Xcode 11 beta.

6/09/2019 12:37:00 am 0
This is happening most of times, no need to worry we can fix with one of the following solutions.


Solution 1:

Go to Xcode preferences -> Locations -> Command line tools

Here, most of them are set to Xcode 10, change to Xcode 11.

Restart Xcode 11 beta, the try it should be ok.

Solution 2:

1. Delete the ContentView.swift file.

2. Create new 'SwiftUI View'

3. Name it same as ContentView.swift.

4. Now click resume in the canvas, we can see preview loading.

Sometimes restarting system may also help.
Read More

Post Top Ad