NetNewsWire/iOS/MasterFeed/Cell/MasterFeedUnreadCountView.s...

116 lines
2.7 KiB
Swift

//
// MasterUnreadCountView.swift
// NetNewsWire
//
// Created by Brent Simmons on 11/22/15.
// Copyright © 2015 Ranchero Software, LLC. All rights reserved.
//
import UIKit
class MasterFeedUnreadCountView : UIView {
private let padding = UIEdgeInsets(top: 1.0, left: 7.0, bottom: 1.0, right: 7.0)
private let cornerRadius = 8.0
private let bgColor = UIColor.darkGray
private let textColor = UIColor.white
private var textAttributes: [NSAttributedString.Key: AnyObject] {
let textFont = UIFont.preferredFont(forTextStyle: .caption1)
return [NSAttributedString.Key.foregroundColor: textColor, NSAttributedString.Key.font: textFont, NSAttributedString.Key.kern: NSNull()]
}
private var textSizeCache = [Int: CGSize]()
var unreadCount = 0 {
didSet {
invalidateIntrinsicContentSize()
setNeedsDisplay()
}
}
var unreadCountString: String {
return unreadCount < 1 ? "" : "\(unreadCount)"
}
private var intrinsicContentSizeIsValid = false
private var _intrinsicContentSize = CGSize.zero
override init(frame: CGRect) {
super.init(frame: frame)
self.isOpaque = false
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.isOpaque = false
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
textSizeCache = [Int: CGSize]()
invalidateIntrinsicContentSize()
setNeedsDisplay()
}
override var intrinsicContentSize: CGSize {
if !intrinsicContentSizeIsValid {
var size = CGSize.zero
if unreadCount > 0 {
size = textSize()
size.width += (padding.left + padding.right)
size.height += (padding.top + padding.bottom)
}
_intrinsicContentSize = size
intrinsicContentSizeIsValid = true
}
return _intrinsicContentSize
}
override func invalidateIntrinsicContentSize() {
intrinsicContentSizeIsValid = false
}
private func textSize() -> CGSize {
if unreadCount < 1 {
return CGSize.zero
}
if let cachedSize = textSizeCache[unreadCount] {
return cachedSize
}
var size = unreadCountString.size(withAttributes: textAttributes)
size.height = ceil(size.height)
size.width = ceil(size.width)
textSizeCache[unreadCount] = size
return size
}
private func textRect() -> CGRect {
let size = textSize()
var r = CGRect.zero
r.size = size
r.origin.x = (bounds.maxX - padding.right) - r.size.width
r.origin.y = padding.top
return r
}
override func draw(_ dirtyRect: CGRect) {
let cornerRadii = CGSize(width: cornerRadius, height: cornerRadius)
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: .allCorners, cornerRadii: cornerRadii)
bgColor.setFill()
path.fill()
if unreadCount > 0 {
unreadCountString.draw(at: textRect().origin, withAttributes: textAttributes)
}
}
}