Cannot change the size of a popover - swift

I've been trying to create my own code, as well as copy and paste examples, but my popover seems to fill the entire screen. Generally my code looks like below, but like I said, I've tried at least two other examples (some with CGSizeMake(), sourceRect, sourceView), and the results are always the same.
Class TableView: UITableViewController, UIPopoverPresentationControllerDelegate {
let popover = UIViewController()
func someButton() {
popover.modalPresentationStyle = .Popover
popover.preferredContentSize = CGSize(1, 1)
let menu = popover.popoverPresentationController
menu!.delegate = self
menu!.barButtonItem = someOtherCorrectButton
self.presentViewController(popover, animated: true, completion: nil)
}
}
What's the problem?

Try below code
popover.modalPresentationStyle = .Popover
var popupHeight:CGFloat = 542
let popupWidth = 400 as CGFloat
popover.preferredContentSize = CGSizeMake(400,popupHeight)
let window = UIApplication.sharedApplication().delegate!.window!!
let screenSize: CGRect = window.bounds
var XCordinate = (screenSize.width - popupWidth) / 2
var YCordinate = (screenSize.height / 2) + 20
let menu = popover.popoverPresentationController
menu!.delegate = self
menu!.sourceView = window
menu!.sourceRect = CGRect( x: XCordinate, y: YCordinate, width: 1, height: 1)
self.presentViewController(popover, animated: true, completion: nil)
May be it works for you.

Related

CAEmitterLayer doesn't work in MacOS with Swift

I just simply create a storyboard program, and change the main ViewController code to the code below which works well in others' example. but it appears nothing on the view? seeking help.
What I did:
create an project with storyboard, and I got 'AppDelegate.swift' and 'ViewController.swift'
paste 'Ball_green.png' to my project and see it under the file tree of my project.
paste the code below in 'ViewController.swift'
import Cocoa
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
self.view.wantsLayer = true
self.addLayer()
}
func addLayer(){
let rootLayer = self.view.layer
let snowEmitter = CAEmitterLayer()
snowEmitter.drawsAsynchronously = true
snowEmitter.name = "snowEmitter"
snowEmitter.zPosition = 10.0
snowEmitter.emitterPosition = CGPoint(x: 0, y: 0)
snowEmitter.renderMode = CAEmitterLayerRenderMode.backToFront
snowEmitter.emitterShape = CAEmitterLayerEmitterShape.circle
snowEmitter.emitterZPosition = -43.00
snowEmitter.emitterSize = CGSize(width: 160, height: 160)
snowEmitter.velocity = 20.57
snowEmitter.emitterMode = CAEmitterLayerEmitterMode.points
snowEmitter.birthRate = 10
let snowFlakesCell2 = CAEmitterCell()
snowFlakesCell2.emissionRange = .pi
snowFlakesCell2.lifetime = 10.0
snowFlakesCell2.birthRate = 4.0
snowFlakesCell2.velocity = 2.0
snowFlakesCell2.velocityRange = 100.0
snowFlakesCell2.yAcceleration = 300.0
snowFlakesCell2.contents = NSImage(named: "Ball_green.png")!.cgImage
snowFlakesCell2.magnificationFilter = convertFromCALayerContentsFilter(CALayerContentsFilter.nearest)
snowFlakesCell2.scale = 0.72
snowFlakesCell2.scaleRange = 0.14
snowFlakesCell2.spin = 0.38
snowFlakesCell2.spinRange = 0
snowEmitter.emitterCells = [snowFlakesCell2]
rootLayer!.addSublayer(snowEmitter)
}
}
fileprivate func convertFromCALayerContentsFilter(_ input: CALayerContentsFilter) -> String {
return input.rawValue
}
extension NSImage {
var cgImage: CGImage {
get {
let imageData = self.tiffRepresentation
let source = CGImageSourceCreateWithData(imageData as! CFData, nil)
let maskRef = CGImageSourceCreateImageAtIndex(source!, 0, nil)
return maskRef!
}
}
}
I've solved the problem after adding the code.

swift custom context menu previewprovider can not click any view inside(using tapgesture)

im working with reaction like message, here is what i did (using customProvider from contextMenu)
below is the code when i added emoji action to customProvider controller
private func addReactionList(_ items : [Reaction]) -> UIView{
let reactionView = UIView()
var arrangedSubviews: [UIView] = []
for reaction in items {
let imgView = UIImageView(image: AppUtils.reactionToImage(reaction: reaction))
imgView.isUserInteractionEnabled = true
imgView.frame = CGRect(x: 0, y: 0, width: iconHeight, height: iconHeight)
imgView.layer.cornerRadius = (imgView.frame.height) / 2
imgView.layer.masksToBounds = true
imgView.layer.borderColor = UIColor.clear.cgColor
imgView.layer.borderWidth = 0
imgView.contentMode = .scaleAspectFit
imgView.restorationIdentifier = reaction.Type
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(_:)))
tapGesture.delegate = self
tapGesture.numberOfTapsRequired = 1
tapGesture.delaysTouchesBegan = true
tapGesture.cancelsTouchesInView = false
imgView.isUserInteractionEnabled = true
imgView.addGestureRecognizer(tapGesture)
arrangedSubviews.append(imgView)
}
let stackView = UIStackView(arrangedSubviews: arrangedSubviews)
stackView.distribution = .fillEqually
stackView.spacing = padding
stackView.layoutMargins = UIEdgeInsets(top: padding, left: padding, bottom: padding, right: padding)
stackView.isLayoutMarginsRelativeArrangement = true
let width = (CGFloat(items.count) * iconHeight) + (CGFloat(items.count+1) * padding)
reactionView.frame = CGRect(x: 0, y: 0, width: width, height: iconHeight + 2 * padding)
reactionView.layer.cornerRadius = 12
reactionView.addSubview(stackView)
stackView.frame = reactionView.frame
stackView.isUserInteractionEnabled = false
reactionView.isUserInteractionEnabled = false
return reactionView
}
then i added this to custom provider vc:
let actionsReacts = addReactionList(likeReactions)
let emojiReacts = addReactionList(emojiReactions)
if let snap = customView.snapshotView(afterScreenUpdates: true) as UIView?{
view.addSubview(snap)
view.addSubview(actionsReacts)
view.addSubview(emojiReacts)
let maxWidth = snap.frame.size.width >= actionsReacts.frame.size.width ? snap.frame.size.width : actionsReacts.frame.size.width
var currentSnapFrame = snap.frame
currentSnapFrame = CGRect(Int((maxWidth - snap.frame.size.width)) / 2, 0 , Int(snap.frame.size.width), Int(snap.frame.size.height))
snap.frame = currentSnapFrame
var currentActionsReactFrame = actionsReacts.frame
currentActionsReactFrame = CGRect(0, Int(snap.frame.size.height), Int(actionsReacts.frame.size.width), Int(actionsReacts.frame.size.height))
actionsReacts.frame = currentActionsReactFrame
var currentEmojiReactFrame = actionsReacts.frame
currentEmojiReactFrame = CGRect(0, Int(snap.frame.size.height) + Int(emojiReacts.frame.size.height), Int(emojiReacts.frame.size.width), Int(emojiReacts.frame.size.height))
emojiReacts.frame = currentEmojiReactFrame
preferredContentSize = CGSize(width: maxWidth, height: snap.frame.size.height + actionsReacts.frame.size.height + emojiReacts.frame.size.height)
}
But the gesture can not fire, i tried to change img to button, but still not get click
#objc func handleTapGesture(_ sender : UITapGestureRecognizer){
let tappedImage = sender.view as! UIImageView
let reactionType = tappedImage.restorationIdentifier ?? ""
onSelectedReaction?(reactionType)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
i do not know why i can not click any where, even i tried to add gesture click to viewcontroller view. Can anyone explain it? Thanks in advance
i changed to present new VC with hero animation, so bored, but it is my best choice for now
I tried to reconstruct your demo app from what you have provided, but it is still not clear to me what your code is or how it behaves.
One thing I note that you are creating n gesture-recognizers and hooking each to an imageview.
Try instead using 1 gesture recognizer. Hook it to your parent view, and on tap-event, get the subview which is being hit.
Some code:
let tap = UITapGestureRecognizer(target: self, action: #selector(self.onViewTap))
parentView.addGestureRecognizer(tap)
#objc func onViewTap(_ sender: UITapGestureRecognizer) {
let point = sender.location(in: containerView)
if let hitSubview = parentView.hitTest(point, with: nil) {
// check which subview (imageView) is being hit by checking its tag or similar
}

Navigation view transition full screen to a view with corner radius

I am trying to create an app home screen animation from splash, like after launch screen completed (full)screen color transforms into an app logo background color. Currently below code kind of archive what I expected. But, that transformation CAShapeLayer doesn't do with corner radius. Without corner radius it works as normal, when I try to use circle/oval/corner radius animation seems like below gif.
Tried few other StackOverflow answers which create circle animation those are not working. Here one of those.
weak var viewTransitionContext: UIViewControllerContextTransitioning!
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
viewTransitionContext = transitionContext
guard let fromVC = viewTransitionContext.viewController(forKey: .from) else { return }
guard let toVC = viewTransitionContext.viewController(forKey: .to) else { return }
if fromVC.isKind(of: SOGSplashViewController.self) && toVC.isKind(of: SOGHomeViewController.self) {
guard let toVCView = transitionContext.view(forKey: .to) else { return }
guard let fromVCView = transitionContext.view(forKey: .from) else { return }
let containerView = transitionContext.containerView
let labelWidth = UIDevice.width() * 0.75
let labelHeight = labelWidth * 0.7
let xAxis = (UIDevice.width() - labelWidth)/2.0
let yAxis = ((UIDevice.height()/2.0) - labelHeight)/2.0
let labelRect = CGRect(x: xAxis, y: yAxis, width: labelWidth, height: labelHeight)
let radius = (UIDevice.height()/2.0)*0.1
let fromFrame = fromVCView.bounds
let animationTime = transitionDuration(using: transitionContext)
let maskLayer = CAShapeLayer()
maskLayer.isOpaque = false
maskLayer.fillColor = fromVCView.backgroundColor?.cgColor
maskLayer.backgroundColor = UIColor.clear.cgColor
maskLayer.path = toPathValue.cgPath
let maskAnimationLayer = CABasicAnimation(keyPath: "path")
maskAnimationLayer.fromValue = (UIBezierPath(rect: fromFrame)).cgPath
maskAnimationLayer.toValue = toPathValue.cgPath
maskAnimationLayer.duration = animationTime
maskAnimationLayer.delegate = self as? CAAnimationDelegate
containerView.addSubview(fromVCView)
containerView.addSubview(toVCView)
fromVCView.layer.add(maskAnimationLayer, forKey: nil)
maskLayer.add(maskAnimationLayer, forKey: "path")
containerView.layer.addSublayer(maskLayer)
let deadLineTime = DispatchTime.now() + .seconds(1)
DispatchQueue.main.asyncAfter(deadline: deadLineTime) {
UIView.animate(withDuration: 0.2, animations: {
maskLayer.opacity = 0
}, completion: { (isSuccess) in
self.viewTransitionContext.completeTransition(true)
})
}
}
}
Transforming a rectangular path to a rounded rectangular path is a very complex operation if you do it through a generic way like Core Animation.. You should better use the cornerRadius property of CALayer which is animatable.
Here is a working example with a constraint based animation:
class ViewController: UIViewController {
#IBOutlet var constraints: [NSLayoutConstraint]!
#IBOutlet var contentView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
self.contentView.layer.cornerRadius = 10.0
self.animate(nil)
}
#IBAction func animate(_ sender: Any?) {
for c in constraints {
c.constant = 40.0
}
UIView.animate(withDuration: 4.0) {
self.view.layoutIfNeeded()
self.contentView.layer.cornerRadius = 40.0
}
}
}
contentView points to the inner view which should be animated, and constraints refer to the four layout constraints defining the distances from the view controller's view to the content view.
This is just a simple, rough example, which can certainly be improved.

Swift add badge to navigation barButtonItem and UIButton

I am trying to display badge on my notification button, in app as displayed on AppIcon.
So far whatever i have researched is related to Obj. C, but nothing that specifically discussed way to implement that solution into Swift,
Please help to find a solution to add a custom class / code to achieve Badge on UiBarbutton and UiButton.
Researched so far:
https://github.com/Marxon13/M13BadgeView
along with MKBadge class etc.
There is a more elegant solution with an extension for UIButtonItem
extension CAShapeLayer {
func drawCircleAtLocation(location: CGPoint, withRadius radius: CGFloat, andColor color: UIColor, filled: Bool) {
fillColor = filled ? color.cgColor : UIColor.white.cgColor
strokeColor = color.cgColor
let origin = CGPoint(x: location.x - radius, y: location.y - radius)
path = UIBezierPath(ovalIn: CGRect(origin: origin, size: CGSize(width: radius * 2, height: radius * 2))).cgPath
}
}
private var handle: UInt8 = 0
extension UIBarButtonItem {
private var badgeLayer: CAShapeLayer? {
if let b: AnyObject = objc_getAssociatedObject(self, &handle) as AnyObject? {
return b as? CAShapeLayer
} else {
return nil
}
}
func addBadge(number: Int, withOffset offset: CGPoint = CGPoint.zero, andColor color: UIColor = UIColor.red, andFilled filled: Bool = true) {
guard let view = self.value(forKey: "view") as? UIView else { return }
badgeLayer?.removeFromSuperlayer()
// Initialize Badge
let badge = CAShapeLayer()
let radius = CGFloat(7)
let location = CGPoint(x: view.frame.width - (radius + offset.x), y: (radius + offset.y))
badge.drawCircleAtLocation(location: location, withRadius: radius, andColor: color, filled: filled)
view.layer.addSublayer(badge)
// Initialiaze Badge's label
let label = CATextLayer()
label.string = "\(number)"
label.alignmentMode = CATextLayerAlignmentMode.center
label.fontSize = 11
label.frame = CGRect(origin: CGPoint(x: location.x - 4, y: offset.y), size: CGSize(width: 8, height: 16))
label.foregroundColor = filled ? UIColor.white.cgColor : color.cgColor
label.backgroundColor = UIColor.clear.cgColor
label.contentsScale = UIScreen.main.scale
badge.addSublayer(label)
// Save Badge as UIBarButtonItem property
objc_setAssociatedObject(self, &handle, badge, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
func updateBadge(number: Int) {
if let text = badgeLayer?.sublayers?.filter({ $0 is CATextLayer }).first as? CATextLayer {
text.string = "\(number)"
}
}
func removeBadge() {
badgeLayer?.removeFromSuperlayer()
}
}
This great code was created by Stefano Vettor and you can find all the details at:
https://gist.github.com/freedom27/c709923b163e26405f62b799437243f4
Working Solution :
Step 1:
Firstly create new swift file which is a subclass to UIButton as follows:
import UIKit
class BadgeButton: UIButton {
var badgeLabel = UILabel()
var badge: String? {
didSet {
addbadgetobutton(badge: badge)
}
}
public var badgeBackgroundColor = UIColor.red {
didSet {
badgeLabel.backgroundColor = badgeBackgroundColor
}
}
public var badgeTextColor = UIColor.white {
didSet {
badgeLabel.textColor = badgeTextColor
}
}
public var badgeFont = UIFont.systemFont(ofSize: 12.0) {
didSet {
badgeLabel.font = badgeFont
}
}
public var badgeEdgeInsets: UIEdgeInsets? {
didSet {
addbadgetobutton(badge: badge)
}
}
override init(frame: CGRect) {
super.init(frame: frame)
addbadgetobutton(badge: nil)
}
func addbadgetobutton(badge: String?) {
badgeLabel.text = badge
badgeLabel.textColor = badgeTextColor
badgeLabel.backgroundColor = badgeBackgroundColor
badgeLabel.font = badgeFont
badgeLabel.sizeToFit()
badgeLabel.textAlignment = .center
let badgeSize = badgeLabel.frame.size
let height = max(18, Double(badgeSize.height) + 5.0)
let width = max(height, Double(badgeSize.width) + 10.0)
var vertical: Double?, horizontal: Double?
if let badgeInset = self.badgeEdgeInsets {
vertical = Double(badgeInset.top) - Double(badgeInset.bottom)
horizontal = Double(badgeInset.left) - Double(badgeInset.right)
let x = (Double(bounds.size.width) - 10 + horizontal!)
let y = -(Double(badgeSize.height) / 2) - 10 + vertical!
badgeLabel.frame = CGRect(x: x, y: y, width: width, height: height)
} else {
let x = self.frame.width - CGFloat((width / 2.0))
let y = CGFloat(-(height / 2.0))
badgeLabel.frame = CGRect(x: x, y: y, width: CGFloat(width), height: CGFloat(height))
}
badgeLabel.layer.cornerRadius = badgeLabel.frame.height/2
badgeLabel.layer.masksToBounds = true
addSubview(badgeLabel)
badgeLabel.isHidden = badge != nil ? false : true
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.addbadgetobutton(badge: nil)
fatalError("init(coder:) is not implemented")
}
}
Step 2:
Create a function in your base file which u can use in each View Controller :
func addBadge(itemvalue: String) {
let bagButton = BadgeButton()
bagButton.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
bagButton.tintColor = UIColor.darkGray
bagButton.setImage(UIImage(named: "ShoppingBag")?.withRenderingMode(.alwaysTemplate), for: .normal)
bagButton.badgeEdgeInsets = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 15)
bagButton.badge = itemvalue
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: bagButton)
}
Step 3 :
Use above function from any View Controller in this way :
self.addBadge(itemvalue: localStorage.string(forKey: "total_products_in_cart") ?? "0")
First create label, then right bar button. On right bar button add subview which will be badge count. Finally add navigation right bar button.
SWIFT 5
let badgeCount = UILabel(frame: CGRect(x: 22, y: -05, width: 20, height: 20))
badgeCount.layer.borderColor = UIColor.clear.cgColor
badgeCount.layer.borderWidth = 2
badgeCount.layer.cornerRadius = badgeCount.bounds.size.height / 2
badgeCount.textAlignment = .center
badgeCount.layer.masksToBounds = true
badgeCount.textColor = .white
badgeCount.font = badgeCount.font.withSize(12)
badgeCount.backgroundColor = .red
badgeCount.text = "4"
let rightBarButton = UIButton(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
rightBarButton.setBackgroundImage(UIImage(named: "NotificationBell"), for: .normal)
rightBarButton.addTarget(self, action: #selector(self.onBtnNotification), for: .touchUpInside)
rightBarButton.addSubview(badgeCount)
let rightBarButtomItem = UIBarButtonItem(customView: rightBarButton)
navigationItem.rightBarButtonItem = rightBarButtomItem
I had the same task. I didn't want to use third-party libraries. Firstly, I tried Stefano's solution and it's great however I decided to implement my own way to solve it.
In my humble opinion, there are simple steps described below briefly:
Create UIView instance within .xib file and put necessary items like UILabel or UIImageView instance depending on your design requirements.
The final action I did in this step is putting invisible button in the top of view's hierarchy.
Create YourCustomView.swift and link all #IBOutlets from xib to current file inside your custom view class implementation.
Next, implement class function in YourCustomView class which will load custom view from xib and return it as YourCustomView instance.
Finally, add your custom badge to your custom view controller instance!
My result is..
P.S. If you need to implement #IBActions I recommend to link your custom view and custom view controller through the delegate pattern.
using M13BadgeView.. use this code
(im using fontawesome.swift for buttons :: https://github.com/thii/FontAwesome.swift)
let rightButton = UIButton(frame: CGRect(x:0,y:0,width:30,height:30))
rightButton.titleLabel?.font = UIFont.fontAwesome(ofSize: 22)
rightButton.setTitle(String.fontAwesomeIcon(name: .shoppingBasket), for: .normal)
let rightButtonItem : UIBarButtonItem = UIBarButtonItem(customView: rightButton)
let badgeView = M13BadgeView()
badgeView.text = "1"
badgeView.textColor = UIColor.white
badgeView.badgeBackgroundColor = UIColor.red
badgeView.borderWidth = 1.0
badgeView.borderColor = UIColor.white
badgeView.horizontalAlignment = M13BadgeViewHorizontalAlignmentLeft
badgeView.verticalAlignment = M13BadgeViewVerticalAlignmentTop
badgeView.hidesWhenZero = true
rightButton.addSubview(badgeView)
self.navigationItem.rightBarButtonItem = rightButtonItem
Good answer #Julio Bailon (https://stackoverflow.com/a/45948819/1898973)!
Here is the author's site with full explanation: http://www.stefanovettor.com/2016/04/30/adding-badge-uibarbuttonitem/.
It seems not to be working on iOS 11, maybe because the script try to access the "view" property of the UIBarButtonItem. I made it work:
By creating a UIButton and then creating the UIBarButtonItem using the UIButton as a customView:
navigationItem.rightBarButtonItem = UIBarButtonItem.init(
customView: shoppingCartButton)
By replacing the line in the UIBarButtonItem extension:
guard let view = self.value(forKey: "view") as? UIView else { return }
with the following:
guard let view = self.customView else { return }
Seems elegant to me and, best of all, it worked!
You can set below constraints to UILabel with respect to UIButton
align UILabel's top and trailing to UIButton
And when you need to show badge set text to UILabel and when you don't want to show badge then set empty string to UILabel
Download This
For BarButtonItem : Drag and Drop UIBarButtonItem+Badge.h and UIBarButtonItem+Badge.m class in project.
Write this code for set Badges:
self.navigationItem.rightBarButtonItem.badgeValue = "2"
self.navigationItem.rightBarButtonItem.badgeBGColor = UIColor.black
For UIButtton : Drag and Drop UIButton+Badge.h and UIButton+Badge.m class in project.
self.notificationBtn.badgeValue = "2"
self.notificationBtn.badgeBGColor = UIColor.black
Answer with extension from Julio will not work.
Starting from iOS 11 this code will not work cause line of code below will not cast UIView. Also it's counting as private API and seems to be will not pass AppStore review.
guard let view = self.value(forKey: "view") as? UIView else { return }
Thread on Apple Developer Forum
Second thing that this snippet always draws circle, so it can't fit numbers bigger than 9.
Here the simplified version by using custom view
Easy and clear solution if you are looking for only adding the red dot without the number;
private var handle: UInt8 = 0;
extension UIBarButtonItem {
private var badgeLayer: CAShapeLayer? {
if let b: AnyObject = objc_getAssociatedObject(self, &handle) as AnyObject? {
return b as? CAShapeLayer
} else {
return nil
}
}
func setBadge(offset: CGPoint = .zero, color: UIColor = .red, filled: Bool = true, fontSize: CGFloat = 11) {
badgeLayer?.removeFromSuperlayer()
guard let view = self.value(forKey: "view") as? UIView else {
return
}
var font = UIFont.systemFont(ofSize: fontSize)
if #available(iOS 9.0, *) {
font = UIFont.monospacedDigitSystemFont(ofSize: fontSize, weight: .regular)
}
//Size of the dot
let badgeSize = UILabel(frame: CGRect(x: 22, y: -05, width: 10, height: 10))
// initialize Badge
let badge = CAShapeLayer()
let height = badgeSize.height
let width = badgeSize.width
// x position is offset from right-hand side
let x = view.frame.width + offset.x - 17
let y = view.frame.height + offset.y - 34
let badgeFrame = CGRect(origin: CGPoint(x: x, y: y), size: CGSize(width: width, height: height))
badge.drawRoundedRect(rect: badgeFrame, andColor: color, filled: filled)
view.layer.addSublayer(badge)
// initialiaze Badge's label
let label = CATextLayer()
label.alignmentMode = .center
label.font = font
label.fontSize = font.pointSize
label.frame = badgeFrame
label.foregroundColor = filled ? UIColor.white.cgColor : color.cgColor
label.backgroundColor = UIColor.clear.cgColor
label.contentsScale = UIScreen.main.scale
badge.addSublayer(label)
// save Badge as UIBarButtonItem property
objc_setAssociatedObject(self, &handle, badge, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
// bring layer to front
badge.zPosition = 1_000
}
private func removeBadge() {
badgeLayer?.removeFromSuperlayer()
}
}
// MARK: - Utilities
extension CAShapeLayer {
func drawRoundedRect(rect: CGRect, andColor color: UIColor, filled: Bool) {
fillColor = filled ? color.cgColor : UIColor.white.cgColor
strokeColor = color.cgColor
path = UIBezierPath(roundedRect: rect, cornerRadius: 7).cgPath
}
}
The source of the code:
https://gist.github.com/freedom27/c709923b163e26405f62b799437243f4
I only made a few changes to eliminate the number.
The MIBadgeButton-Swift is working also on UIBarButtonItems.
Here is my code after the navigation bar is created:
let rightBarButtons = self.navigationItem.rightBarButtonItems
let alarmsBarButton = rightBarButtons?.last
let alarmsButton = alarmsBarButton.customView as! MIBadgeButton?
alarmsButton.badgeString = "10"
You can do it programmatically with
self.tabBarItem.badgeColor = .red
or use the storyboard. See:

Add UIView in Main View As UItabBarController in swift

I am adding Tabbarcontroller in Main View, but i didn't set its background colour... I have already try tabBar.barTintColor but it's not working..
So i am trying to Add View as TabbarController (Which work like UITabbar) but i am not succeeded on it... Can any one please help me out.Here is the code
var tabBar = UITabBarController()
var frameOfView : CGRect = UIScreen.mainScreen().bounds
tabBar.view.frame = CGRectMake(frameOfView.origin.x, frameOfView.size.height, frameOfView.size.width, frameOfView.size.height-100)
var viewTabBar = UIView(frame: CGRectMake(frameOfView.origin.x, 430, frameOfView.size.width, 100))
var BtnHomeTab = UIButton(frame: CGRectMake(0, 0, 30, 30))
var imageHomeTab = UIImage(named: "home_selected.png")
viewTabBar.addSubview(BtnHomeTab)
have to hide UITabbarcontroller ..:)
and then Add this code to Your appDelegate.
//MARK: CREATE BOTTOMBAR BUTTON
func craeteBottonBarButton()
{
var viewBottom : UIView = UIView(frame: CGRectMake(0,window!.frame.size.height - 50.0,window!.frame.size.width,60.0))
viewBottom.tag = TagWindow.Tag_Bottom.rawValue
window!.addSubview(viewBottom)
window!.bringSubviewToFront(viewBottom)
viewBottom.backgroundColor = GlobalConstants.GlobalConstants.ButtonConstant.BUTTONBACKGROUNDCOLOR
viewBottom.tag = TagWindow.Tag_Bottom.rawValue
var x : CGFloat = 0.0
for var i = 0 ; i < 5 ; i++
{
var btn = createTabBarButton(viewBottom,
framebtn: CGRectMake(x,0, 65.0, 50.0),
tag: (i + 1),
imgName: arrayImage.objectAtIndex(i) as NSString , btnName: arrayLblName.objectAtIndex(i) as NSString) as UIButton
viewBottom.addSubview(btn)
x += 64.5
}
}
Give all navigation controller to the button
func createTabBar() -> UITabBarController
{
var storyBoard = UIStoryboard(name: "Main", bundle: nil)
tabBar.delegate = self
var tabBarFont = UITabBar()
let HomeTab = storyBoard.instantiateViewControllerWithIdentifier("HomeVC") as HomeVC
let navigation_home = UINavigationController(rootViewController: HomeTab)
navigation_home.navigationBarHidden = true
let SearchTab = storyBoard.instantiateViewControllerWithIdentifier("SearchVC") as SearchVC
let navigation_search = UINavigationController(rootViewController: SearchTab)
navigation_search.navigationBarHidden = true
let SettingTab = storyBoard.instantiateViewControllerWithIdentifier("SettingVC") as SettingVC
let navigation_Setting = UINavigationController(rootViewController: SettingTab)
navigation_Setting.navigationBarHidden = true
let MySeatTab = storyBoard.instantiateViewControllerWithIdentifier("MySeatVC") as MySeatVC
let navigation_MySeat = UINavigationController(rootViewController: MySeatTab)
navigation_MySeat.navigationBarHidden = true