swift开发笔记29
2018-02-09 18:09 dengchaojie_learner 阅读(139) 评论(0) 编辑 收藏 举报当一个数组中包含多种数据类型时,且需要访问元素(对象)的同一种属性(例如Date),可以定一个协议,让每个元素去遵守和实现协议方法。例如:
protocol DateSortable {
var date: Date { get }
}
init(landingDate: Date = Date(timeIntervalSinceNow: -31725960)) {
self.landingDate = landingDate
}
enum WeatherCondition: String {
case cloudy = "Cloudy"
case sunny = "Sunny"
case partlyCloudy = "Partly Cloudy"
case dustStorm = "Dust Storm"
var emoji: String {
switch self {
case .cloudy: return "☁️"
case .sunny: return "☀️"
case .partlyCloudy: return "⛅️"
case .dustStorm: return "🌪"
}
}
}
let titleLabel: UILabel = {
let label = UILabel()
label.backgroundColor = UIColor.clear
label.text = "MARSLINK"
label.font = AppFont()
label.textAlignment = .center
label.textColor = UIColor.white
return label
}()// 定义时,直接做基本的初始化
//if you want a given view to size itself to its parent view, you should add it to the parent view before calling this method.
label.sizeToFit()
let statusIndicator: CAShapeLayer = {
let layer = CAShapeLayer()
layer.strokeColor = UIColor.white.cgColor
layer.lineWidth = 1
layer.fillColor = UIColor.black.cgColor
let size: CGFloat = 8
let frame = CGRect(x: 0, y: 0, width: size, height: size)
layer.path = UIBezierPath(roundedRect: frame, cornerRadius: size/2).cgPath
layer.frame = frame
return layer
}()
let path = UIBezierPath()// 贝塞尔曲线
path.move(to: .zero)
path.addLine(to: CGPoint(x: titleWidth, y: 0))
path.addLine(to: CGPoint(x: titleWidth, y: bounds.height - borderHeight))
path.addLine(to: CGPoint(x: bounds.width, y: bounds.height - borderHeight))
path.addLine(to: CGPoint(x: bounds.width, y: bounds.height))
path.addLine(to: CGPoint(x: 0, y: bounds.height))
path.close()
highlightLayer.path = path.cgPath
CATransaction.begin()
CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
statusIndicator.fillColor = (statusOn ? UIColor.white : UIColor.black).cgColor
CATransaction.commit()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.6) {
self.updateStatus()
}
statusIndicator.position = CGPoint(x: statusLabel.center.x - 50, y: statusLabel.center.y - 1)// position.For more information about the relationship between the frame, bounds, anchorPointand position properties, see Core Animation Programming Guide.
var messages: [Message] = {
var arr = [Message]()
arr.append(lewisMessage(text: "Mark, are you receiving me?", interval: -803200))
arr.append(lewisMessage(text: "I think I left behind some ABBA, might help with the drive 😜", interval: -259200))
return arr
}() {
didSet {// 当属性值发生变化时,触发didSet方法
delegate?.pathfinderDidUpdateMessages(pathfinder: self)
}
}
private func delay(time: Double = 1, execute work: @escaping @convention(block) () -> Swift.Void) {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + time) {
work()
}
}
fileprivate struct CacheEntry: Hashable {
let text: String
let font: UIFont
let width: CGFloat
let insets: UIEdgeInsets
fileprivate var hashValue: Int {
return text.hashValue ^ Int(width) ^ Int(insets.top) ^ Int(insets.left) ^ Int(insets.bottom) ^ Int(insets.right)
}
private func ==(lhs: TextSize.CacheEntry, rhs: TextSize.CacheEntry) -> Bool {
return lhs.width == rhs.width && lhs.insets == rhs.insets && lhs.text == rhs.text
}
public static func size(_ text: String, font: UIFont, width: CGFloat, insets: UIEdgeInsets = UIEdgeInsets.zero) -> CGRect {
let key = CacheEntry(text: text, font: font, width: width, insets: insets)
if let hit = cache[key] {
return hit
}
let constrainedSize = CGSize(width: width - insets.left - insets.right, height: CGFloat.greatestFiniteMagnitude)
let attributes = [ NSFontAttributeName: font ]
let options: NSStringDrawingOptions = [.usesFontLeading, .usesLineFragmentOrigin]
var bounds = (text as NSString).boundingRect(with: constrainedSize, options: options, attributes: attributes, context: nil)
bounds.size.width = width
bounds.size.height = ceil(bounds.height + insets.top + insets.bottom)
cache[key] = bounds
return bounds
}