Skip to content

Commit

Permalink
Merge pull request #90 from emrcftci/master
Browse files Browse the repository at this point in the history
Improvements
  • Loading branch information
tmdvs authored Jan 24, 2020
2 parents c617bb9 + d78f417 commit 43db411
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 82 deletions.
4 changes: 0 additions & 4 deletions TDBadgedCell/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?


private func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
return true
}

}

112 changes: 59 additions & 53 deletions TDBadgedCell/TDBadgedCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,128 +14,134 @@ import UIKit
open class TDBadgedCell: UITableViewCell {

/// Badge value
public var badgeString : String = "" {
public var badgeString: String = "" {
didSet {
if(badgeString == "") {
badgeView.removeFromSuperview()
if badgeString == "" {
badgeImageView.removeFromSuperview()
layoutSubviews()
} else {
contentView.addSubview(badgeView)
contentView.addSubview(badgeImageView)
drawBadge()
}
}
}

/// Badge background color for normal states
public var badgeColor : UIColor = UIColor(red: 0, green: 0.478, blue: 1, alpha: 1.0)
public var badgeColor = UIColor(red: 0, green: 0.478, blue: 1, alpha: 1)

/// Badge background color for highlighted states
public var badgeColorHighlighted : UIColor = .darkGray
/// Badge font size
public var badgeFontSize : Float = 11.0
/// Badge text style if dyanmic type desired
public var badgeColorHighlighted: UIColor = .darkGray

public var badgeFontSize: Float = 11.0

/// Badge text style if dyanmic type desired
public var badgeTextStyle: UIFont.TextStyle?
/// Badge text color

public var badgeTextColor: UIColor?

/// Badge text offset from the left hand side of the Badge
public var badgeTextOffset: Float = 0

/// Corner radius of the badge. Set to 0 for square corners.
public var badgeRadius : Float = 20
public var badgeRadius: Float = 20

/// The Badges offset from the right hand side of the Table View Cell
public var badgeOffset = CGPoint(x:10, y:0)

/// The Image view that the badge will be rendered into
internal let badgeView = UIImageView()
internal let badgeImageView = UIImageView()

override open func layoutSubviews() {
super.layoutSubviews()

// Layout our badge's position
var offsetX = badgeOffset.x
if(isEditing == false && accessoryType != .none || (accessoryView) != nil) {
if (!isEditing) && (accessoryType != .none) || (accessoryView != nil) {
offsetX = 0 // Accessory types are a pain to get sizing for?
}
badgeView.frame.origin.x = floor(contentView.frame.width - badgeView.frame.width - offsetX)
badgeView.frame.origin.y = floor((frame.height / 2) - (badgeView.frame.height / 2))

badgeImageView.frame.origin.x = floor(contentView.frame.width - badgeImageView.frame.width - offsetX)
badgeImageView.frame.origin.y = floor((frame.height / 2) - (badgeImageView.frame.height / 2))

// Now lets update the width of the cells text labels to take the badge into account
let labelWidth = self.contentView.frame.width - (badgeView.frame.width + (offsetX * 2));
let labelWidth = contentView.frame.width - (badgeImageView.frame.width + (offsetX * 2))

if textLabel != nil {
textLabel!.frame.size.width = labelWidth - textLabel!.frame.origin.x
}

if detailTextLabel != nil {
detailTextLabel!.frame.size.width = labelWidth - detailTextLabel!.frame.origin.x
}
}

// When the badge
override open func setHighlighted(_ highlighted: Bool, animated: Bool) {
super.setHighlighted(highlighted, animated: animated)
drawBadge()
}

override open func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
drawBadge()
}

/// Generate the badge image
internal func drawBadge() {

var badgeFont = UIFont.boldSystemFont(ofSize:CGFloat(badgeFontSize))
if let textStyle = self.badgeTextStyle
{
badgeFont = UIFont.preferredFont(forTextStyle: textStyle)
}
func drawBadge() {

var badgeFont = UIFont.boldSystemFont(ofSize:CGFloat(badgeFontSize))

if let textStyle = badgeTextStyle {
badgeFont = UIFont.preferredFont(forTextStyle: textStyle)
}

// Calculate the size of our string
let textSize : CGSize = NSString(string: badgeString).size(withAttributes:[NSAttributedString.Key.font:badgeFont])
let textSize: CGSize = NSString(string: badgeString).size(withAttributes: [NSAttributedString.Key.font: badgeFont])

// Create a frame with padding for our badge
let height = textSize.height + 10
var width = textSize.width + 16
if(width < height) {

if width < height {
width = height
}
let badgeFrame : CGRect = CGRect(x:0, y:0, width:width, height:height)

let badge = CALayer()
badge.frame = badgeFrame
if(isHighlighted || isSelected) {

if isHighlighted || isSelected {
badge.backgroundColor = badgeColorHighlighted.cgColor
} else {
badge.backgroundColor = badgeColor.cgColor
}

badge.cornerRadius = (CGFloat(badgeRadius) < (badge.frame.size.height / 2)) ? CGFloat(badgeRadius) : CGFloat(badge.frame.size.height / 2)

let isRadiusLower = CGFloat(badgeRadius) < (badge.frame.size.height / 2)
badge.cornerRadius = isRadiusLower ? CGFloat(badgeRadius) : CGFloat(badge.frame.size.height / 2)

// Draw badge into graphics context
UIGraphicsBeginImageContextWithOptions(badge.frame.size, false, UIScreen.main.scale)
let ctx = UIGraphicsGetCurrentContext()!
ctx.saveGState()
badge.render(in:ctx)
ctx.saveGState()

// Draw string into graphics context
if(badgeTextColor == nil) {
ctx.setBlendMode(CGBlendMode.clear)
if badgeTextColor == nil {
ctx.setBlendMode(.clear)
}
NSString(string: badgeString).draw(in:CGRect(x: CGFloat(8 + badgeTextOffset), y: 5, width: textSize.width, height: textSize.height), withAttributes: [

NSString(string: badgeString).draw(in: CGRect(x: CGFloat(8 + badgeTextOffset), y: 5, width: textSize.width, height: textSize.height), withAttributes: [
NSAttributedString.Key.font:badgeFont,
NSAttributedString.Key.foregroundColor: badgeTextColor ?? UIColor.clear
])

let badgeImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()

badgeView.frame = CGRect(x:0, y:0, width:badgeImage.size.width, height:badgeImage.size.height)
badgeView.image = badgeImage
badgeImageView.frame = CGRect(x:0, y:0, width:badgeImage.size.width, height:badgeImage.size.height)
badgeImageView.image = badgeImage

layoutSubviews()
}
}
33 changes: 17 additions & 16 deletions TDBadgedCell/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import UIKit

class ViewController: UITableViewController {

/// List of example table view cells
let demoItems : [[String:String]] = [
["title" : "This is an example badge", "badge": "1"],
Expand All @@ -18,27 +18,29 @@ class ViewController: UITableViewController {
["title" : "Another text badge with a really long title!", "badge": "Danger!"],
["title" : "Another text badge with offset from the left", "badge": "1!"]
]

override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = editButtonItem
tableView.tableFooterView = UIView()
}


override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return demoItems.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier:"BadgedCell") as? TDBadgedCell;
if(cell == nil) {
cell = TDBadgedCell(style: .default, reuseIdentifier: "BadgedCell");
var cell = tableView.dequeueReusableCell(withIdentifier:"BadgedCell") as? TDBadgedCell

if cell == nil {
cell = TDBadgedCell(style: .default, reuseIdentifier: "BadgedCell")
}


cell?.textLabel!.text = demoItems[indexPath.row]["title"]
cell?.detailTextLabel?.text = demoItems[indexPath.row]["title"]
cell?.badgeString = demoItems[indexPath.row]["badge"]!

let item = demoItems[indexPath.row]

cell?.textLabel!.text = item["title"]
cell?.detailTextLabel?.text = item["title"]
cell?.badgeString = item["badge"] ?? ""

switch indexPath.row {
case 0:
Expand All @@ -62,16 +64,15 @@ class ViewController: UITableViewController {
break
}

// Uncomment this to test with dynamic type.
// cell?.badgeTextStyle = .caption1
// Uncomment this to test with dynamic type.
// cell?.badgeTextStyle = .caption1

return cell!
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
tableView.deselectRow(at: indexPath, animated: true)
}
}
}

12 changes: 3 additions & 9 deletions TDBadgedCellTests/TDBadgedCellTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,14 @@ import XCTest

class TDBadgedCellTests: XCTestCase {

var cell : TDBadgedCell?
var cell: TDBadgedCell?

override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
cell = TDBadgedCell(style: .default, reuseIdentifier: "Cell")
}

override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}

func testSetBadgeString() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
Expand All @@ -34,8 +29,7 @@ class TDBadgedCellTests: XCTestCase {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
cell?.badgeString = "Testing 1,2,3"
XCTAssert(cell?.badgeView != nil)
XCTAssert(cell!.badgeView.image != nil)
XCTAssert(cell?.badgeImageView != nil)
XCTAssert(cell!.badgeImageView.image != nil)
}

}

0 comments on commit 43db411

Please sign in to comment.