如何对一张图片打Tag标签
来源:互联网 发布:java多线程同步和死锁 编辑:程序博客网 时间:2024/04/29 15:08
import UIKit
@objc public protocol QfWaveLayerDelegate : NSObjectProtocol {
func layerDidFinishAnimation()
}
let QfWaveLayerDuration = 0.8
let QfWaveLayerNumberOfWaves = 2
let QfWaveLayerSpawnInterval = 0.65
let QfWaveLayerSpawnSize : CGFloat = 4.0
let QfWaveLayerScaleFactor : CGFloat = 4.0
let QfWaveLayerShadowRadius : CGFloat = 2.0
public classQfWaveLayer :CALayer {
public weak var parentView :QfWaveLayerDelegate? =nil
private var _scaleAnimation :CABasicAnimation!
private var _opacityAnimation :CABasicAnimation!
public overridefunc drawInContext(ctx: CGContext!) {
CGContextSetRGBStrokeColor(ctx,0, 0,0, 1.0)
CGContextSetLineWidth(ctx,1.5)
let rect =CGRectMake(self.bounds.size.width/ 2- QfWaveLayerSpawnSize/ 2,self.bounds.size.height/ 2- QfWaveLayerSpawnSize/ 2,QfWaveLayerSpawnSize, QfWaveLayerSpawnSize)
println(rect)
CGContextStrokeEllipseInRect(ctx, rect)
}
public func startAnimation() {
self.addAnimation(self.scaleAnimation(), forKey:"scale")
self.addAnimation(self.opacityAnimation(), forKey:"opacity")
}
public func scaleAnimation() ->CABasicAnimation! {
if self._scaleAnimation ==nil {
self._scaleAnimation =CABasicAnimation(keyPath: "transform.scale")
self._scaleAnimation.duration =RyxWaveLayerDuration
self._scaleAnimation.delegate =self
self._scaleAnimation.repeatCount =0
self._scaleAnimation.removedOnCompletion =false
self._scaleAnimation.fillMode =kCAFillModeForwards
self._scaleAnimation.toValue =QfWaveLayerScaleFactor
}
returnself._scaleAnimation
}
public func opacityAnimation() ->CABasicAnimation! {
ifself._opacityAnimation ==nil {
self._opacityAnimation =CABasicAnimation(keyPath: "opacity")
self._opacityAnimation.duration =QfWaveLayerDuration
self._opacityAnimation.repeatCount =0
self._opacityAnimation.removedOnCompletion =false
self._opacityAnimation.fillMode =kCAFillModeForwards
self._opacityAnimation.toValue =0
}
returnself._opacityAnimation
}
public overrideinit() {
super.init()
}
public requiredinit(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
public overridefunc animationDidStop(anim: CAAnimation!, finished flag:Bool) {
self.parentView?.layerDidFinishAnimation()
(dispatch_get_main_queue(),2) ~>> {
self.startAnimation()
}
}
}
public class QfWaveAnimationView :UIView, QfWaveLayerDelegate {
private var wavesSpawned =0
private var wavesDone =0
private var waveLayer :QfWaveLayer?
private var timer :NSTimer? = nil
deinit {
self.timer?.invalidate()
for layer inself.layer.sublayers {
if layer isQfWaveLayer {
(layer as QfWaveLayer).parentView = nil
}
}
}
public class func waveAnimation(position: CGPoint, view: UIView?) -> QfWaveAnimationView {
let av = QfWaveAnimationView(frame:CGRectMake(0, 0,100, 100))
av.center = position
view?.addSubview(av)
return av
}
public overrideinit(frame: CGRect) {
super.init(frame: frame)
let wave = RyxWaveLayer()
wave.bounds =CGRectMake(0,0, QfWaveLayerSpawnSize+ QfWaveLayerShadowRadius+ 2,QfWaveLayerSpawnSize +QfWaveLayerShadowRadius +2)
wave.position = CGPointMake(self.bounds.size.width/ 2, self.bounds.size.height/ 2)
wave.shadowColor =UIColor.yellowColor().CGColor
wave.shadowOffset =CGSizeMake(0,0)
wave.shadowOpacity = 1.0
wave.shadowRadius =QfWaveLayerShadowRadius
wave.parentView = self
self.layer.addSublayer(wave)
self.waveLayer = wave
self.spawnWave()
ifQfWaveLayerNumberOfWaves > 1 {
var spawnInterval = QfWaveLayerSpawnInterval
if spawnInterval > QfWaveLayerDuration * 1.25 {
spawnInterval = QfWaveLayerDuration *1.25
}
self.timer =NSTimer.scheduledTimerWithTimeInterval(spawnInterval, target:self, selector: Selector("spawnWave"), userInfo:nil, repeats: true)
}
}
public requiredinit(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
public func spawnWave() {
self.waveLayer!.setNeedsDisplay()
self.waveLayer!.startAnimation()
self.wavesSpawned++
ifself.wavesSpawned ==QfWaveLayerNumberOfWaves {
self.timer?.invalidate()
self.timer =nil
}
}
public func layerDidFinishAnimation() {
self.wavesDone++
ifself.wavesDone ==self.wavesSpawned {
self.wavesDone =0
}
}
}
public class QfTagLabel :UILabel {
public var tagInfo :RyxTag? = nil
public overrideinit(frame: CGRect) {
super.init(frame: frame)
}
public requiredinit(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
public overridefunc drawTextInRect(rect: CGRect) {
let insets = UIEdgeInsets(top:5, left: 5, bottom: 5, right: 5)
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets))
}
public overridefunc drawRect(rect: CGRect) {
super.drawRect(rect)
}
public overridefunc drawLayer(layer: CALayer!, inContext ctx:CGContext!) {
super.drawLayer(layer, inContext: ctx)
}
}
private enum RSPopLabelArrowType :Int {
case Left = 0
case Right = 1
}
private let ArrowPointCount =7
private extension UIBezierPath {
private class func arrowFromPoint(startPoint: CGPoint, endPoint:CGPoint, tailWidth: CGFloat, headWidth:CGFloat, headLength: CGFloat) -> UIBezierPath! {
func getAxisAlignedArrowPoints(length:CGFloat, tailWidth: CGFloat, headWidth:CGFloat, headLength: CGFloat) -> [CGPoint] {
var points = [CGPoint](count:ArrowPointCount, repeatedValue: CGPointZero)
let tailLength = length - headLength
points[0] = CGPointMake(0, tailWidth/ 2)
points[1] = CGPointMake(tailLength, tailWidth/ 2);
points[2] = CGPointMake(tailLength, headWidth/ 2);
points[3] = CGPointMake(length,0);
points[4] = CGPointMake(tailLength,-headWidth / 2);
points[5] = CGPointMake(tailLength,-tailWidth / 2);
points[6] = CGPointMake(0,-tailWidth / 2);
return points
}
func transform(startPoint: CGPoint, endPoint: CGPoint, length: CGFloat) -> CGAffineTransform {
let cosine = (endPoint.x- startPoint.x) / length
let sine = (endPoint.y- startPoint.y) / length
return CGAffineTransformMake(cosine, sine,-sine, cosine, startPoint.x, startPoint.y)
}
let length = CGFloat(hypotf(Float(endPoint.x- startPoint.x), Float(endPoint.y - startPoint.y)))
var points = getAxisAlignedArrowPoints(length, tailWidth, headWidth, headLength)
var transformData = transform(startPoint, endPoint, length)
let path =CGPathCreateMutable()
withUnsafePointer(&transformData, { (td) ->Void in
CGPathAddLines(path, td, points,UInt(points.count))
})
CGPathCloseSubpath(path)
let uiPath = UIBezierPath(CGPath: path)
return uiPath
}
private class func arrow(startPoint: CGPoint, endPoint: CGPoint, headWidth: CGFloat, headLength: CGFloat) -> UIBezierPath {
return arrowFromPoint(startPoint, endPoint: endPoint, tailWidth: headWidth, headWidth: headWidth, headLength: headLength)
}
}
public class QfArrowView :UIView {
private var label =QfTagLabel(frame: CGRectZero)
public var tipPoint =CGPointZero
private var tipSize =12
privatevar arrowType : RSPopLabelArrowType = .Left
private var targetFrame =CGRectZero
private var bgImageView =UIImageView()
private var bgImageView2 =UIImageView()
private var shapeLayer =CAShapeLayer()
private class var tipPadding : CGFloat {
get {
return 8.0
}
}
private class var cornerRadius : CGFloat {
get {
return 6.0
}
}
lazy public var labelColor = UIColor(white: 0.0, alpha:0.75)
lazy public var labelTextColor = UIColor.whiteColor()
lazy public var labelTextHightlightColor = UIColor.whiteColor()
lazy public var labelFont : UIFont = {
returnUIFont.systemFontOfSize(12)
}()
@IBInspectable public var text : String? {
get {
return self.label.text
}
set {
self.label.text = newValue
}
}
public overridefunc awakeFromNib() {
super.awakeFromNib()
self.shapeLayer.fillRule =kCAFillRuleNonZero
self.layer.insertSublayer(self.shapeLayer, atIndex:0)
}
public init(text:String) {
super.init(frame:CGRectZero)
self.label.text = text
self.shapeLayer.fillRule =kCAFillRuleNonZero
self.layer.insertSublayer(self.shapeLayer, atIndex:0)
}
public overrideinit(frame: CGRect) {
super.init(frame: frame)
self.shapeLayer.fillRule =kCAFillRuleNonZero
self.layer.insertSublayer(self.shapeLayer, atIndex:0)
self.addSubview(bgImageView2)
self.addSubview(bgImageView)
}
public requiredinit(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.shapeLayer.fillRule =kCAFillRuleNonZero
self.layer.insertSublayer(self.shapeLayer, atIndex:0)
}
public class var arrowSize : CGFloat {
get {
return 8
}
}
public func setupApperance() {
self.backgroundColor =UIColor.clearColor()
self.label.textAlignment = .Left
self.label.numberOfLines =0
self.label.text =text
self.addSubview(self.label)
self.label.textColor =self.labelTextColor
self.label.font =self.labelFont
let maxWidth =UIScreen.mainScreen().applicationFrame.size.width* 0.8
let maxHeight =UIScreen.mainScreen().applicationFrame.size.height* 0.8
let attributedText = NSAttributedString(string: self.label.text!, attributes: [NSFontAttributeName:self.labelFont])
var rect = attributedText.boundingRectWithSize(CGSizeMake(maxWidth,CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, context:nil)
var minWidth = min(rect.size.width+ QfArrowView.arrowSize, 180)
var minHeigth = min(rect.size.height, maxHeight)
self.label.frame =CGRectMake(QfArrowView.arrowSize,0, minWidth, minHeigth)
self.label.sizeToFit()
self.targetFrame =self.label.frame
let height = self.targetFrame.size.height+ CGFloat(self.tipSize *2)
self.frame =CGRectMake(self.tipPoint.x, (self.tipPoint.y- height / 2) , minWidth+ QfArrowView.arrowSize + 5, height)
self.label.frame =CGRectMake(QfArrowView.arrowSize,0, minWidth + 5, height)
return
}
public overridefunc layoutSubviews() {
super.layoutSubviews()
self.setupApperance()
}
private func checkLeft() ->Bool {
let width =UIScreen.mainScreen().applicationFrame.width
if self.arrowType== .Left {
if self.tipPoint.x+ self.fram e.width > width {
return false
}
return true
}
return false
}
private func checkRight() ->Bool {
ifself.arrowType== .Right {
if self.tipPoint.x >self.frame.width {
return false
}
return true
}
return false
}
private func bestArrowDirection() -> (RSPopLabelArrowType,CGFloat) {
if self.checkLeft() {
return (.Left,0)
} else if self.checkRight() {
return (.Right,0)
}
// check tipLocation...
return {() -> (RSPopLabelArrowType,CGFloat) in
let width =UIScreen.mainScreen().applicationFrame.width
if self.tipPoint.x <= width/ 2 {
return (.Left, width- self.tipPoint.x)
}
return (.Right, width- self.tipPoint.x)
}()
}
public func popAtView(view:UIView) {
if self.hidden ==false {
return
}
var (arrowType, space) = self.bestArrowDirection()
self.arrowType = arrowType
if space ==0 {
} else {
}
}
public overridefunc drawRect(rect: CGRect) {
// super.drawRect(rect)
var roundedRect = rect
roundedRect.origin.y+= QfArrowView.tipPadding
roundedRect.size.height-=QfArrowView.tipPadding * 2
var viewBackgroundPath : UIBezierPath!
if self.arrowType== .Left {
viewBackgroundPath = UIBezierPath.arrow(roundedRect.rightCenter, endPoint: roundedRect.leftCenter, headWidth:25, headLength: QfArrowView.arrowSize)
} else if self.arrowType == .Right {
viewBackgroundPath = UIBezierPath.arrow(roundedRect.leftCenter, endPoint: roundedRect.rightCenter, headWidth:25, headLength: QfArrowView.arrowSize)
}
self.shapeLayer.path = viewBackgroundPath.CGPath
self.shapeLayer.fillColor =self.labelColor.CGColor
self.shapeLayer.strokeColor =UIColor.redColor().CGColor
}
}
public class QfDraggableArrowView :QfArrowView {
publicvar animationView : QfAnimationView =QfAnimationView()
public var timer :NSTimer?
public var showTime :NSTimeInterval =1.5
private var isAnimation :Bool = false
public requiredinit(coder aDecoder: NSCoder) {
self.voluntaryHidden =false;
super.init(coder: aDecoder)
}
public overrideinit(frame: CGRect) {
self.voluntaryHidden =false;
super.init(frame: frame)
animationView = QfAnimationView(frame:self.bounds, image: nil)
self.addSubview(animationView)
self.voluntaryHidden =false
}
public var voluntaryHidden :Bool {
willSet (newValue) {
if self.voluntaryHidden ==true && newValue == true {
self.stopTimer()
}
self.startTimer()
}
didSet {
if self.voluntaryHidden ==true {
} else {
self.stopTimer()
}
}
}
public func startTimer() {
if self.isAnimation ==true {
return
}
self.timer =NSTimer.scheduledTimerWithTimeInterval(self.showTime, target:self, selector: Selector("hiddenArrowView"), userInfo:nil, repeats: false)
}
public func stopTimer() {
if self.isAnimation ==true {
return
}
self.hidden =false
self.alpha =1.0
self.timer?.invalidate()
self.timer =nil
}
public func hiddenArrowView() {
self.hidden =true
}
deinit {
self.stopTimer()
}
public overrideinit(text: String) {
self.voluntaryHidden =false
super.init(text: text)
}
public overridefunc layoutSubviews() {
super.layoutSubviews()
animationView.frame =self.bounds
}
private var currentPoint =CGPointZero
public overridefunc touchesBegan(touches: NSSet, withEvent event:UIEvent) {
// Promote the touched view
self.superview?.bringSubviewToFront(self)
currentPoint = touches.anyObject()!.locationInView(self)
}
public overridefunc touchesMoved(touches: NSSet, withEvent event:UIEvent) {
let activePoint = touches.anyObject()!.locationInView(self)
var newPoint = CGPointMake(self.center.x+ (activePoint.x - currentPoint.x), self.center.y + (activePoint.y - currentPoint.y))
let midPointX = CGRectGetMidX(self.bounds)
if newPoint.x >self.superview!.bounds.size.width- midPointX {
newPoint.x = self.superview!.bounds.size.width- midPointX
} else if newPoint.x< midPointX {
newPoint.x = midPointX
}
let midPointY = CGRectGetMidY(self.bounds)
if newPoint.y >self.superview!.bounds.size.height- midPointY {
newPoint.y = self.superview!.bounds.size.height- midPointY
} else if newPoint.y< midPointY {
newPoint.y = midPointY
}
self.center = newPoint
}
public overridefunc touchesEnded(touches: NSSet, withEvent event:UIEvent) {
let activePoint = touches.anyObject()!.locationInView(self)
var newPoint = CGPointMake(self.center.x+ (activePoint.x - currentPoint.x), self.center.y + (activePoint.y - currentPoint.y))
self.willChangeValueForKey("tipPoint")
self.tipPoint = newPoint
self.didChangeValueForKey("tipPoint")
}
}
- 如何对一张图片打Tag标签
- git tag 打标签
- git tag打标签
- Git打标签tag
- Git tag 打标签
- 如何打tag
- git tag 给提交内容打标签
- git 使用详解-- tag打标签
- git 使用详解-- tag打标签
- git 项目管理之打标签tag
- Git tag 给当前分支打标签
- Git tag 给当前分支打标签
- 自定义编辑EditText打tag标签View
- 如何翻转一张图片
- 如何裁剪一张图片
- ClearCase如何打标签
- 如何取得打好TAG的代码
- git 使用详解(8)-- tag打标签
- hdu 5044 树链剖分+前缀和
- requirejs 简单用法
- 交换两个变量的值
- window查找指定字符串在当前目录下的所有文件中是否存在
- IO模型之IO多路复用
- 如何对一张图片打Tag标签
- Java内部类的一些小结(一)
- vlc开发学习
- Swift语法基础:3 - Swift的函数和闭包
- 我的Android学习之旅[1]——Android的系统架构
- hdu 1166 敌兵布阵
- 算法之美——寻找发帖水王算法
- 递归研究(四) 八皇后问题
- 23.HCNA-HNTD——Telnet原理与配置