Last active
February 7, 2020 18:00
-
-
Save heitara/0b49e36183e6dd695b02436ab2fa7d27 to your computer and use it in GitHub Desktop.
Add a Badge View with a Label
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Created by © 2020 SwiftEverywhere. Can be used free of charge. | |
import UIKit | |
//protocol | |
protocol BadgeContainer: class { | |
var badgeView: UIView? { get set } | |
var badgeLabel: UILabel? { get set } | |
func showBadge(blink: Bool, text: String?) | |
func hideBadge() | |
} | |
//default protocol implementation | |
extension BadgeContainer where Self: UIView { | |
func showBadge(blink: Bool, text: String?) { | |
if badgeView != nil { | |
if badgeView?.isHidden == false { | |
return | |
} | |
} else { | |
badgeView = UIView() | |
} | |
badgeView?.backgroundColor = .red | |
guard let badgeViewUnwrapped = badgeView else { | |
return | |
} | |
//adds the badge at the top | |
addSubview(badgeViewUnwrapped) | |
badgeViewUnwrapped.translatesAutoresizingMaskIntoConstraints = false | |
var size = CGFloat(6) | |
if let textUnwrapped = text { | |
if badgeLabel == nil { | |
badgeLabel = UILabel() | |
} | |
guard let labelUnwrapped = badgeLabel else { | |
return | |
} | |
labelUnwrapped.text = textUnwrapped | |
labelUnwrapped.textColor = .white | |
labelUnwrapped.font = .systemFont(ofSize: 8) | |
labelUnwrapped.translatesAutoresizingMaskIntoConstraints = false | |
badgeViewUnwrapped.addSubview(labelUnwrapped) | |
let labelConstrainst = [labelUnwrapped.centerXAnchor.constraint(equalTo: badgeViewUnwrapped.centerXAnchor), labelUnwrapped.centerYAnchor.constraint(equalTo: badgeViewUnwrapped.centerYAnchor)] | |
NSLayoutConstraint.activate(labelConstrainst) | |
size = CGFloat(12 + 2 * textUnwrapped.count) | |
} | |
let sizeConstraints = [badgeViewUnwrapped.widthAnchor.constraint(equalToConstant: size), badgeViewUnwrapped.heightAnchor.constraint(equalToConstant: size)] | |
NSLayoutConstraint.activate(sizeConstraints) | |
badgeViewUnwrapped.cornerRadius = size / 2 | |
let position = [badgeViewUnwrapped.topAnchor.constraint(equalTo: self.topAnchor, constant: -size / 2), | |
badgeViewUnwrapped.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: size/2)] | |
NSLayoutConstraint.activate(position) | |
if blink { | |
let animation = CABasicAnimation(keyPath: "opacity") | |
animation.duration = 1.2 | |
animation.repeatCount = .infinity | |
animation.fromValue = 0 | |
animation.toValue = 1 | |
animation.timingFunction = .init(name: .easeOut) | |
badgeViewUnwrapped.layer.add(animation, forKey: "badgeBlinkAnimation") | |
} | |
} | |
func hideBadge() { | |
badgeView?.layer.removeAnimation(forKey: "badgeBlinkAnimation") | |
badgeView?.removeFromSuperview() | |
badgeView = nil | |
badgeLabel = nil | |
} | |
} | |
//custom class | |
class BadgeButton: UIButton, BadgeContainer { | |
var badgeTimer: Timer? | |
var badgeView: UIView? | |
var badgeLabel: UILabel? | |
} | |
//extension of UIView for proper positioning of visual children | |
extension UIView { | |
@IBInspectable var cornerRadius: CGFloat { | |
get { | |
return layer.cornerRadius | |
} | |
set { | |
layer.cornerRadius = newValue | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment