Change label text on right bar item swift 4 - ios

I have created a common nevigation method in view controller extension to show back, close and cart item on navigation bar through out my application. It shows the items on nav bar properly. But the cart item which is at the right side of the nav bar, has a button icon and a round badge icon with label. I need to update the label and increase the count on label every time an item is added in the cart. But somehow the label is not changing. Below is my code -
UIViewController Extension -
func setCartBarButtonItem() {
let cartBarButton = UIBarButtonItem.init(customView: getCartButton())
self.navigationItem.rightBarButtonItem = cartBarButton
}
func getCartButton() -> UIButton{
let frame = CGRect.init(x: UIScreen.main.bounds.width - 40, y: 14, width: 44, height:44)
let cartButton = UIButton.init(frame: frame)
cartButton.setImage(UIImage(named: "cart"), for: .normal)
cartButton.addTarget(self, action: #selector(self.cartButtonTapped), for: .touchUpInside)
let cartLabelView = UIView(frame: CGRect(x: cartButton.layer.bounds.width/2, y: 10, width: 16, height: 16))
cartLabelView.backgroundColor = UIColor(red: 255.0/255.0, green: 234.0/255.0, blue: 41.0/255.0, alpha: 1.0)
cartLabelView.layer.cornerRadius = 8
cartLabelView.layer.borderWidth = 0.5
cartLabelView.layer.borderColor = UIColor(red: 54.0/255.0, green: 54.0/255.0, blue: 54.0/255.0, alpha: 1.0).cgColor
cartButton.addSubview(cartLabelView)
let cartLabel = UILabel(frame: CGRect(x: cartLabelView.layer.bounds.width/3, y: 0, width: cartLabelView.layer.bounds.width, height: cartLabelView.layer.bounds.height))
cartLabel.textColor = UIColor.black
cartLabel.font = UIFont(name: "Arial", size: 9)
cartLabelView.addSubview(cartLabel)
cartLabelView.isHidden = true
var count = 0
count = getNumberOfItemInCart()
if count > 0 {
cartLabelView.isHidden = false
cartLabel.text = String(count)
}
return cartButton
}
In one delegate function which is called when item is added in cart, I call the this setCartBarButtonItem() to update the label. But label does not update. It shows the last value only.

Related

Why are fonts in UI segment control reverting to system fonts automatically?

I have several UI Segment Controls across an iOS app written in swift.
Whilst simulating on an iOS device, on the initial load they use the correct custom font set in the code but certain instances where I go to other views and come back, the fonts in the segment control tabs seem to revert to system fonts automatically.
What is causing this issue?
I am creating all of my segmented controls using this function in each view controller. This is where the custom fonts are set.
override func viewDidLoad() {
super.viewDidLoad()
isHirer = AppSettings.boolValue(.isHirer)
setupUI()
setupSegmentControl()
downloadData()
configureLocationManager()
}
func setupSegmentControl() {
var items = [String]()
items = AppSettings.boolValue(.isHirer) ? ["Posts", "Manage"] : ["Search", "Manage"]
let segmentedControl = UISegmentedControl(items: items)
segmentedControl.selectedSegmentIndex = 0
UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor:UIColor.init(displayP3Red: 0/255, green: 0/255, blue: 0/255, alpha: 1), NSAttributedString.Key.font : UIFont.init(name: "Cabin-SemiBold", size: 16)!], for: .selected)
UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor:UIColor.init(displayP3Red: 138/255, green: 145/255, blue: 172/255, alpha: 0.7), NSAttributedString.Key.font : UIFont.init(name: "Cabin-SemiBold", size: 16)!], for: .normal)
segmentedControl.frame = CGRect.init(x: 0, y: 42, width: tableView.frame.width/2-20, height: 48)
if AppSettings.boolValue(.isHirer) {
segmentedControl.setContentOffset(CGSize(width: 0, height: -5), forSegmentAt: 0)
segmentedControl.setContentOffset(CGSize(width: 0, height: -5), forSegmentAt: 1)
} else {
segmentedControl.setContentOffset(CGSize(width: 5, height: -5), forSegmentAt: 0)
segmentedControl.setContentOffset(CGSize(width: 0, height: -5), forSegmentAt: 1)
}
segmentedControl.setBackgroundImage(backgroundWithColor(color: .backgroundGray, frame: CGRect(x: 0, y: 0, width: segmentedControl.frame.width, height: segmentedControl.frame.height)), for: .normal, barMetrics: .default)
segmentedControl.setDividerImage(imageWithColor(color: UIColor.white), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
segmentedControl.addTarget(self, action: #selector(showSection), for: .valueChanged)
seg = segmentedControl
}
#objc func showSection(sender: UISegmentedControl) {
switch sender.selectedSegmentIndex {
case 0:
isSegment0 = true
tableView.reloadData()
case 1:
isSegment0 = false
tableView.reloadData()
default:
break
}
}
Then in ViewForHeaderInSection function of table view added seg to the header view.
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 0 && AppSettings.boolValue(.isHirer) || section == 0 && !AppSettings.boolValue(.isHirer) {
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 90))
headerView.backgroundColor = .backgroundGray
let segmentControl = seg
segmentControl.tag = section
headerView.addSubview(segmentControl)
return headerView
Please try modifying your code as follows:
Before:
UISegmentedControl.appearance().setTitleTextAttributes(...)
After:
segmentedControl.setTitleTextAttributes(...)
i.e. do not use appearance proxy on the UISegmentedControl class
The appearance proxy would typically be done once in an app early in its lifecycle before any controls of that class are instantiated. For example, you might instead use the appearance proxy in your AppDelegates didFinishLaunching() API, this would replace the need to call setTitleTextAttributes() elsewhere in your code.
Please report back if this helps.

iOS Swift 3 - Remove Overlay UIView after Panel Tap

I am very new to swift and I am stuck with the task described in the title.
My Problem:
I am building a product page programmatically, consisting of a few simple details and an offer button. Tapping offer button brings up an overlay on the view with some other details. You click "Ok" and the overlay disappears.
All good except the overlay does not disappear!
What I have tried:
func hideOverlay(_ sender: UIButton) {
containerView.backgroundColor = UIColor.white
buttonView.backgroundColor = UIColor.white
for subview in overlayView.subviews {
subview.removeFromSuperview()
}
}
Function is called on tapping the button within the overlayView. I will include the showOverlay function(working).
func showOverlay(_ sender: UIButton) {
//Load overlay view
let overlayHeight : CGFloat = 500
let overlayWidth : CGFloat = 290
let overlayView = UIView(frame: CGRect(x: centreView(masterView: view.frame.width, subView: overlayWidth), y: 64 + centreView(masterView: (view.frame.height - 64), subView: overlayHeight), width: overlayWidth, height: overlayHeight))
overlayView.backgroundColor = UIColor.white
let overlayTitle = UILabel(frame: CGRect(x: 0, y: 0, width: overlayWidth, height: overlayHeight*1/5))
overlayTitle.text = "Offer Taken"
overlayTitle.font = UIFont.boldSystemFont(ofSize: 35)
overlayTitle.textAlignment = .center
overlayView.addSubview(overlayTitle)
let overlayButtonView = UIView(frame: CGRect(x: 0, y: 0 + (overlayHeight * 4/5), width: overlayWidth, height: overlayHeight * 1/5))
overlayButtonView.backgroundColor = UIColor.red
let buttonWidth : CGFloat = 100
let buttonHeight : CGFloat = 35
let overlayButton = UIButton(type: UIButtonType.system)
overlayButton.frame = CGRect(x: centreView(masterView: overlayWidth, subView: buttonWidth), y: overlayButtonView.frame.origin.y + centreView(masterView: overlayButtonView.frame.height, subView: buttonHeight), width: buttonWidth, height: buttonHeight)
overlayButton.backgroundColor = UIColor.blue
overlayButton.setTitle("OK",for: .normal)
overlayButton.setTitleColor(UIColor.white, for: .normal)
overlayButton.setTitle("Offer Taken", for: .highlighted)
overlayButton.setTitleColor(UIColor.white, for: .highlighted)
overlayButton.addTarget(self, action: #selector(self.hideOverlay(_:)), for: .touchUpInside)
overlayView.addSubview(overlayButtonView)
overlayView.addSubview(overlayButton)
containerView.backgroundColor = UIColor(colorLiteralRed: 0, green: 0, blue: 0, alpha: 0.5)
buttonView.backgroundColor = UIColor(colorLiteralRed: 0, green: 0, blue: 0, alpha: 0.5)
view.addSubview(overlayView)
}
I have tried
overlayView.removeFromSuperview()
after the for loop, but I fear that overlayView.subviews is not correctly filled with the views I expect.
I appreciate anyone taking the time to help me, even if a little closer to a solution.
In func showOverlay(_ sender: UIButton) {...} you are creating a local variable "overlayView":
let overlayView = UIView(frame: ...)
You then add that as a subview to view. All that is fine, except you do not keep a reference to "overlayView" .. the view remains but you have no reference to it.
Add a class-level variable, outside of any function blocks:
var overlayView: UIView!
Then, inside func showOverlay(_ sender: UIButton) {...}, instead of let overlayView = just assign it to the existing variable:
overlayView = UIView(frame: ...)
When you're ready to remove it:
func hideOverlay(_ sender: UIButton) {
overlayView.removeFromSuperview()
}
and you're done :)
Try the viewWithTag method described in a similar thread here:
Swift addsubview and remove it

Swift : Programatically Create a UIButton with Some Specific Font And Size

I want to create a basic UIButton programmatically. For example, in my view controller five UIButtons will be created dynamically in the same row and its layout or properties are set for some color, font, and size.
And I also need to add action method for a specific button.
If you wanted to do it programmatically, you might think along the following lines:
Create your buttons in a for... loop in viewDidLoad() (or elsewhere, depending on your requirements):
let buttonWidth : CGFloat = self.view.frame.width / 10
let buttonHeight : CGFloat = 50
for count in 0..<10 {
let newButton = UIButton(frame: CGRect(origin: CGPoint(x: CGFloat(count) * buttonWidth, y: 50), size: CGSize(width: buttonWidth, height: buttonHeight)))
newButton.backgroundColor = UIColor.red
newButton.setTitle("Button #\(count)", for: UIControlState.normal)
newButton.setTitleColor(UIColor.white, for: UIControlState.normal)
newButton.addTarget(self, action: #selector(self.buttonTapped(sender:)), for: UIControlEvents.touchUpInside)
newButton.titleLabel?.font = UIFont(name: "Arial", size: 10)
newButton.tag = count
self.view.addSubview(newButton)
}
Then you can implement the selector buttonTapped(sender: UIButton) as follows, retrieving the button's tag so you can tailor the action (via a switch statement, for example):
func buttonTapped(sender: UIButton) -> Void {
print("\(sender.tag) was tapped!")
// Do something more interesting based on the tag here...
}
This allows you to set up a lot of button actions without a lot of different selectors. Hope that helps.
Create uibuttons and add them inside main view see example below.
class yourClassName: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// here method CGRectMake defines x, y, width, height
var btnOne = UIButton(frame: CGRectMake(0, 0, 50, 50))
var btnOne = UIButton(frame: CGRectMake(0, 0, 50, 50))
self.view.addSubview(btnOne) // add button inside view
self.view.addSubview(btnOne) // add button inside view
// using selector you must specify a method for each button
btnOne.addTarget(self, action: #selector(self.actionOne), forControlEvents: .TouchUpInside)
btnTwo.addTarget(self, action: #selector(self.actionTwo), forControlEvents: .TouchUpInside)
}
Actions methods:
func actionOne(sender : UIButton) {
print("button one tapped")
}
func actionTwo(sender : UIButton) {
print("button second tapped")
}
let bacViewOne=UIButton(frame: CGRectMake(20, 60 , 130, 130))
bacViewOne.backgroundColor=UIColor.whiteColor()
bacViewOne.layer.cornerRadius=5.0
btn1 = UIButton(type: UIButtonType.Custom) as UIButton
btn1.setImage(UIImage(named: "new.png"), forState: UIControlState.Normal)
btn1.frame = CGRectMake((bacViewOne.frame.size.width-90)/2, 5 , 90, 90)
//btn1.backgroundColor = UIColor.whiteColor()
btn1.tag = 1
btn1.addTarget(self, action: #selector(ViewController.dashboard(_:)), forControlEvents: UIControlEvents.TouchUpInside)
bacViewOne.addSubview(btn1)
self.view.addSubview(bacViewOne)
let l1 = UILabel(frame: CGRectMake((bacViewOne.frame.size.width-90)/2, 100, 90, 21))
l1.textAlignment = NSTextAlignment.Center
l1.textColor = UIColor(red: 41/255.0, green: 43/255.0, blue: 64/255.0, alpha: 1)
l1.text = "Dashboard"
//l1.font = UIFont (name: "BakerSignetBT-Roman", size: 15)
bacViewOne.addSubview(l1)
l1.font = UIFont.systemFontOfSize(11)
var bacViewT=UIButton(type: UIButtonType.Custom) as UIButton
bacViewT .frame = CGRectMake(20, 240, 130, 130)
bacViewT.backgroundColor=UIColor.whiteColor()
bacViewT.layer.cornerRadius=5.0
btn3 = UIButton(type: UIButtonType.Custom) as UIButton
btn3.setImage(UIImage(named: "Usernew.png"), forState: UIControlState.Normal)
btn3.frame = CGRectMake((bacViewT.frame.size.width-90)/2, 5, 90, 90)
// btn3.backgroundColor = UIColor(red: 41/255.0, green: 43/255.0, blue: 64/255.0, alpha: 1)
btn3.tag = 2
btn3.addTarget(self, action: #selector(ViewController.userExpenses(_:)), forControlEvents: UIControlEvents.TouchUpInside)
bacViewT.addSubview(btn3)
self.view.addSubview(bacViewT)
let l2 = UILabel(frame: CGRectMake((bacViewT.frame.size.width-100)/2, 100, 100, 21))
l2.textAlignment = NSTextAlignment.Center
l2.textColor = UIColor(red: 41/255.0, green: 43/255.0, blue: 64/255.0, alpha: 1)
l2.text = "User Expense"
//l2.font = UIFont (name: "BakerSignetBT-Roman", size: 15)
bacViewT.addSubview(l2)
l2.font = UIFont.systemFontOfSize(11)
//7
let bacViewTh=UIButton(frame: CGRectMake(170, 60, 130, 130))
bacViewTh.backgroundColor=UIColor.whiteColor()
bacViewTh.layer.cornerRadius=5.0
btn7 = UIButton(type: UIButtonType.Custom) as UIButton
btn7.setImage(UIImage(named: "events.png"), forState: UIControlState.Normal)
btn7.frame = CGRectMake((bacViewTh.frame.size.width-90)/2, 5, 90, 90)
btn7.tag = 3
btn7.addTarget(self, action: #selector(ViewController.upcomingEvents(_:)), forControlEvents: UIControlEvents.TouchUpInside)
bacViewTh.addSubview(btn7)
let l3 = UILabel(frame: CGRectMake((bacViewTh.frame.size.width-100)/2, 100, 100, 21))
l3.textAlignment = NSTextAlignment.Center
l3.textColor = UIColor(red: 41/255.0, green: 43/255.0, blue: 64/255.0, alpha: 1)
l3.text = "Upcoming Events"
//l3.font = UIFont (name: "BakerSignetBT-Roman", size: 15)
bacViewTh.addSubview(l3)
l3.font = UIFont.systemFontOfSize(11)
self.view.addSubview(bacViewTh)
//8
let bacViewF=UIButton(frame: CGRectMake(170, 240, 130, 130))
bacViewF.backgroundColor=UIColor.whiteColor()
bacViewF.layer.cornerRadius=5.0
btn9 = UIButton(type: UIButtonType.Custom) as UIButton
btn9.setImage(UIImage(named: "Location.png"), forState: UIControlState.Normal)
btn9.frame = CGRectMake((bacViewF.frame.size.width-90)/2, 5, 90, 90)
btn9.tag = 4
btn9.addTarget(self, action: #selector(ViewController.userLocations(_:)), forControlEvents: UIControlEvents.TouchUpInside)
bacViewF.addSubview(btn9)
self.view.addSubview(bacViewF)
let l4 = UILabel(frame: CGRectMake((bacViewF.frame.size.width-100)/2, 100, 100, 21))
l4.textAlignment = NSTextAlignment.Center
l4.textColor = UIColor(red: 41/255.0, green: 43/255.0, blue: 64/255.0, alpha: 1)
l4.text = "User Locations"
bacViewF.addSubview(l4)
l4.font = UIFont.systemFontOfSize(11)

Unable to change the x and y position of Label inside navigation bar

I am building an app that uses a custom navigation bar as shown in this pic
I am unable to change the the position of the label such as "My Xyz business". I want to push the label a little top of the screen ( right now its hugging towards the bottom of the bar)
i have tried with code but only the height and width changes. There is no change in the x and y position.
Why is that happening
following is the code:
func customNavigationBar() {
var ver: [AnyObject] = UIDevice.currentDevice().systemVersion.componentsSeparatedByString(".")
if CInt(ver[0] as! String)! >= 7 {
// iOS 7.0 or later
self.navigationController!.navigationBar.barTintColor = UIColor.whiteColor()
self.navigationController!.navigationBar.translucent = false
}
else {
// iOS 6.1 or earlier
self.navigationController!.navigationBar.tintColor = UIColor.whiteColor()
}
self.navigationController!.navigationBar.frame = CGRectMake(0, 0,400 , 174)
let lbl: UILabel = UILabel(frame: CGRectMake(0, 0, 200, 30))
lbl.font = UIFont(name: "Vodafone Rg", size: 20.0)
lbl.text = "My Xyz Inc Business"
lbl.textColor = UIColor(red: 230.0 / 255, green: 0, blue: 0, alpha: 1.0)
let vodafoneLabel: UIBarButtonItem = UIBarButtonItem(customView: lbl)

UIStackView not appearing in Container View

Can someone please explain to me why I cannot see this StackView show up in its container?
This is what it looks like now:
This is what I want it to look like, ignore the cells, I just need to figure out why the Edit button, search bar and Sort button are not showing.
Here is the code I used to setup the views and their contents:
// Container
let barViewFrame = CGRectMake(0, 0, view.frame.width, 44)
let barViewContainer = UIView(frame: barViewFrame)
barViewContainer.backgroundColor = UIColor(red: 231/255, green: 231/255, blue: 231/255, alpha: 1.0)
tableView.tableHeaderView = barViewContainer
// Edit Button
let editButton = UIButton(type: .System)
editButton.bounds = CGRectMake(0, 0, 44, 44)
editButton.setTitle("Edit", forState: .Normal)
// Search Bar
let searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: 50, height: 44))
searchBar.placeholder = "Search"
searchBar.searchBarStyle = .Prominent
searchBar.barTintColor = UIColor(red: 231/255, green: 231/255, blue: 231/255, alpha: 1.0)
// Sort Button
let sortButtton = UIButton(type: .Custom)
sortButtton.bounds = CGRectMake(0, 0, 44, 44)
sortButtton.setImage(UIImage(named: "Sort"), forState: .Normal)
// Stackview
let stackViewH = UIStackView(arrangedSubviews: [editButton, searchBar, sortButtton])
stackViewH.axis = .Horizontal
stackViewH.alignment = .Center
stackViewH.spacing = 8
barViewContainer.addSubview(stackViewH)
barViewContainer.addConstraints([
stackViewH.leftAnchor.constraintEqualToAnchor(barViewContainer.leftAnchor),
stackViewH.topAnchor.constraintEqualToAnchor(barViewContainer.topAnchor),
stackViewH.rightAnchor.constraintEqualToAnchor(barViewContainer.rightAnchor),
stackViewH.bottomAnchor.constraintEqualToAnchor(barViewContainer.bottomAnchor)])
When you add views programmatically, iOS assumes that you want to layout those views using frames. To make this work with auto layout, behinds the scenes it adds constraints so the view will appear according to its frame. But, you are adding constraints that you want the auto layout engine to use rather than the ones it would like to create. So to tell auto layout not to generate those constraints you can set the translatesAutoresizingMaskIntoConstraints to false for the views on which you don't want this to occur.
In your case:
stackViewH.translatesAutoresizingMaskIntoConstraints = false

Resources