
ペイントアプリなんかでよくある、選択した範囲を動く点線で囲むサンプルです。また使いそうなのでメモ代わりに。
こういうやつ

仕組みは、点線の枠のオフセットをタイマーで変更して動いているように見せているだけです。簡単だけど、点線が動くだけですごくリッチな感じに見えますね。
ドラッグの処理はUIPanGestureRecognizerで行ってます。
ViewController.swift
import UIKit
class ViewController: UIViewController {
var panGestureRecognizer: UIPanGestureRecognizer! = nil
var selectAreaView: SelectAreaView! = nil
var selectStartPoint: CGPoint = CGPointZero
override func viewDidLoad() {
super.viewDidLoad()
panGestureRecognizer = UIPanGestureRecognizer(target: self, action: "dragView:")
self.view.addGestureRecognizer(panGestureRecognizer)
}
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
self.view.removeGestureRecognizer(panGestureRecognizer)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func dragView(sender: UIPanGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Began {
// ドラッグ開始
selectStartPoint = sender.locationInView(self.view)
var frame = CGRectMake( selectStartPoint.x, selectStartPoint.y, 0, 0)
selectAreaView = SelectAreaView(frame: frame)
self.view.addSubview(selectAreaView)
} else if sender.state == UIGestureRecognizerState.Changed {
// ドラッグ中
var tapPoint = sender.translationInView(self.view)
var frame: CGRect = CGRectZero
if tapPoint.x > 0 && tapPoint.y > 0 {
frame = CGRectMake(
selectStartPoint.x,
selectStartPoint.y,
tapPoint.x,
tapPoint.y)
} else if tapPoint.x < 0 && tapPoint.y > 0 {
frame = CGRectMake(
selectStartPoint.x + tapPoint.x,
selectStartPoint.y,
fabs(tapPoint.x),
tapPoint.y
)
} else if tapPoint.x > 0 && tapPoint.y < 0 {
frame = CGRectMake(
selectStartPoint.x,
selectStartPoint.y + tapPoint.y,
tapPoint.x,
fabs(tapPoint.y)
)
} else if tapPoint.x < 0 && tapPoint.y < 0 {
frame = CGRectMake(
selectStartPoint.x + tapPoint.x,
selectStartPoint.y + tapPoint.y,
fabs(tapPoint.x),
fabs(tapPoint.y)
)
}
selectAreaView.changeFrame(frame)
} else if sender.state == UIGestureRecognizerState.Ended {
// ドラッグ終了
selectAreaView.removeFromSuperview()
}
}
}
こちらが動く点線枠のクラス
SelectAreaView.swift
import Foundation
import UIKit
class SelectAreaView: UIView {
let segmentSize: CGFloat = 4.0 // 点線の線のサイズ
let gapSize: CGFloat = 4.0 // 点線の間のサイズ
var myTimer: NSTimer! = nil
var phaseCount: CGFloat = 0.0
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.clearColor()
myTimer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "phaseChange:", userInfo: nil, repeats: true)
}
deinit {
if myTimer != nil {
myTimer.invalidate()
myTimer = nil
}
}
func phaseChange(timer: NSTimer) {
phaseCount += 1.0
if phaseCount >= segmentSize + gapSize {
phaseCount = 0
}
self.setNeedsDisplay()
}
override func drawRect(rect: CGRect) {
var path = UIBezierPath()
UIColor.blackColor().set()
path.lineWidth = 1
var dashPattern = [segmentSize, gapSize]
path.setLineDash(dashPattern, count:2, phase:phaseCount)
path.moveToPoint(CGPointZero)
path.addLineToPoint(CGPointMake(self.frame.size.width, 0))
path.addLineToPoint(CGPointMake(self.frame.size.width, self.frame.size.height))
path.addLineToPoint(CGPointMake(0, self.frame.size.height))
path.addLineToPoint(CGPointMake(0, 0))
path.stroke()
}
func changeFrame(frame: CGRect) {
self.frame = frame
self.setNeedsDisplay()
}
}



