Skip to content

Instantly share code, notes, and snippets.

@uruly
Last active April 12, 2018 08:36
Show Gist options
  • Save uruly/43dfda5790fb1bf37b6f15077026f4b4 to your computer and use it in GitHub Desktop.
Save uruly/43dfda5790fb1bf37b6f15077026f4b4 to your computer and use it in GitHub Desktop.
import UIKit
class MyShapeLayer: CALayer {
func drawRect(lineWidth:CGFloat){
let rect = CAShapeLayer()
rect.strokeColor = UIColor.black.cgColor
rect.fillColor = UIColor.clear.cgColor
rect.lineWidth = lineWidth
rect.path = UIBezierPath(rect:CGRect(x:0,y:0,width:self.frame.width,height:self.frame.height)).cgPath
self.addSublayer(rect)
}
func drawOval(lineWidth:CGFloat){
let ovalShapeLayer = CAShapeLayer()
ovalShapeLayer.strokeColor = UIColor.blue.cgColor
ovalShapeLayer.fillColor = UIColor.clear.cgColor
ovalShapeLayer.lineWidth = lineWidth
ovalShapeLayer.path = UIBezierPath(ovalIn: CGRect(x:0, y:0, width:self.frame.width, height: self.frame.height)).cgPath
self.addSublayer(ovalShapeLayer)
}
}
import UIKit
class ShapeViewController: UIViewController {
private var selectLayer:CALayer!
private var touchLastPoint:CGPoint!
private var beginGestureScale:CGFloat!
private var effectiveScale:CGFloat!
override func viewDidLoad() {
super.viewDidLoad()
effectiveScale = 1.0
let width = self.view.bounds.width
let height = self.view.bounds.height
//丸を生成するボタン
let ovalBtn = UIButton()
ovalBtn.frame = CGRect(x:0,y:0,width:100,height:50)
ovalBtn.center = CGPoint(x:width / 3,y:height - 30)
ovalBtn.addTarget(self, action: #selector(self.ovalBtnTapped(sender:)), for: .touchUpInside)
ovalBtn.setTitle("丸",for:.normal)
ovalBtn.backgroundColor = UIColor.green
self.view.addSubview(ovalBtn)
//四角を生成するボタン
let rectBtn = UIButton()
rectBtn.frame = CGRect(x:0,y:0,width:100,height:50)
rectBtn.center = CGPoint(x:width * 2 / 3,y:height - 30)
rectBtn.addTarget(self, action: #selector(self.rectBtnTapped(sender:)), for: .touchUpInside)
rectBtn.setTitle("四角",for:.normal)
rectBtn.backgroundColor = UIColor.red
self.view.addSubview(rectBtn)
//ピンチ
let pinch = UIPinchGestureRecognizer()
pinch.addTarget(self,action:#selector(self.pinchGesture(sender:)))
pinch.delegate = self
self.view.addGestureRecognizer(pinch)
}
/************** Button Tapped ***********/
@objc func ovalBtnTapped(sender:UIButton){
//丸を描く
let oval = MyShapeLayer()
oval.frame = CGRect(x:30,y:30,width:80,height:80)
oval.drawOval(lineWidth:1)
self.view.layer.addSublayer(oval)
}
@objc func rectBtnTapped(sender:UIButton){
//四角を描く
let rect = MyShapeLayer()
rect.frame = CGRect(x:40,y:40,width:50,height:50)
rect.drawRect(lineWidth:1)
self.view.layer.addSublayer(rect)
}
/************* pinch ***************/
@objc func pinchGesture(sender:UIPinchGestureRecognizer){
effectiveScale = beginGestureScale * sender.scale
//選択されてるやつだけ
if (selectLayer != nil){
selectLayer.setAffineTransform(CGAffineTransform(scaleX: effectiveScale,y:effectiveScale))
}
}
/************** Touch Action ****************/
func hitLayer(touch:UITouch) -> CALayer{
var touchPoint:CGPoint = touch.location(in:self.view)
touchPoint = self.view.layer.convert(touchPoint, to: self.view.layer.superlayer)
return self.view.layer.hitTest(touchPoint)!
}
func selectLayerFunc(layer:CALayer?) {
if((layer == self.view.layer) || (layer == nil)){
selectLayer = nil
return
}
selectLayer = layer
}
//タッチをした時
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//すでに選択されているレイヤーがあるかもしれないのでnilにしておく
selectLayer = nil
//タッチを取得
let touch:UITouch = touches.first!
//タッチした場所にあるレイヤーを取得
let layer:CALayer = hitLayer(touch: touch)
//タッチされた座標を取得
let touchPoint:CGPoint = touch.location(in: self.view)
//最後にタッチされた場所に座標を入れて置く
touchLastPoint = touchPoint
//選択されたレイヤーをselectLayerにいれる
self.selectLayerFunc(layer:layer)
}
//タッチが動いた時
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch:UITouch = touches.first!
let touchPoint:CGPoint = touch.location(in:self.view)
//直前の座標との差を取得
let touchOffsetPoint:CGPoint = CGPoint(x:touchPoint.x - touchLastPoint.x,
y:touchPoint.y - touchLastPoint.y)
touchLastPoint = touchPoint
if (selectLayer != nil){
//hitしたレイヤーがあった場合
let px:CGFloat = selectLayer.position.x
let py:CGFloat = selectLayer.position.y
//レイヤーを移動させる
CATransaction.begin()
CATransaction.setDisableActions(true)
selectLayer.position = CGPoint(x:px + touchOffsetPoint.x,y:py + touchOffsetPoint.y)
selectLayer.borderWidth = 3.0
selectLayer.borderColor = UIColor.green.cgColor
CATransaction.commit()
}
}
//タッチを終えた時
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if(selectLayer != nil){
selectLayer.borderWidth = 0
}
}
//タッチがキャンセルされた時
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
if(selectLayer != nil){
selectLayer.borderWidth = 0
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ShapeViewController : UIGestureRecognizerDelegate {
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if(gestureRecognizer.isKind(of:UIPinchGestureRecognizer.self)){
beginGestureScale = effectiveScale
}
return true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment