我正在开发一个图像编辑应用程序。当贴纸添加到视图中时,pinchGesture
可用于缩放。问题是当imageView
(贴纸)非常小时,gesture
非常难以使用。我需要能够在贴纸之外pinch
并仍然缩放imageView
。
然后我将pinchGesture
添加到self.view
并检测到它的触摸;如果手指的直线与imageView
相交,则应用pinchGesture
。这样可以正常工作,直到添加了多个贴纸(imageViews
)并且gesture
同时在多个贴纸上工作。
因此,我计算了每个视图从手指到矩形的交点距离,最长距离的视图将获得pinchGesture
。
这不会一直有效。 这是代码:
@objc func pinched(sender: UIPinchGestureRecognizer){
slider.isUserInteractionEnabled = false
if sender.numberOfTouches == 2 && sender.state != .ended{
selectedView = []
let finger1 = sender.location(ofTouch: 0, in: self.view)
let finger2 = sender.location(ofTouch: 1, in: self.view)
for subview in self.view.subviews{
if subview is UIImageView{
let rect = subview.frame
let width = rect.size.width
let height = rect.size.height
let Ax = rect.origin.x
let Ay = rect.origin.y
let Bx = rect.origin.x + width
let By = rect.origin.y
let Dx = rect.origin.x
let Dy = rect.origin.y + height
let Cx = rect.origin.x + height
let Cy = rect.origin.y + width
let A = CGPoint(x: Ax, y: Ay)
let B = CGPoint(x: Bx, y: By)
let C = CGPoint(x: Cx, y: Cy)
let D = CGPoint(x: Dx, y: Dy)
let lineToAB = getIntersectionOfLines(line1: (finger1, finger2), line2: (A, B))
let lineToBC = getIntersectionOfLines(line1: (finger1, finger2), line2: (B, C))
let lineToCD = getIntersectionOfLines(line1: (finger1, finger2), line2: (C, D))
let lineToAD = getIntersectionOfLines(line1: (finger1, finger2), line2: (A, D))
var dx: CGFloat!
if lineToAB != CGPoint.zero || lineToBC != CGPoint.zero || lineToCD != CGPoint.zero || lineToAD != CGPoint.zero{
print("touched")
touched = true
if lineToAB != CGPoint.zero{
dx = distance(lineToAB, lineToCD)
}else if lineToBC != CGPoint.zero{
dx = distance(lineToBC, lineToAD)
}else if lineToCD != CGPoint.zero{
dx = distance(lineToAB, lineToCD)
}else if lineToAD != CGPoint.zero{
dx = distance(lineToAD, lineToBC)
}else{
dx = 0.0
}
}else{
dx = 0.0
touched = false
}
selectedView.append(selectedViews(distance: dx, view: subview))
}
}
var max: CGFloat = 0.0
var viewtoscale: UIView!
for item in selectedView{
if item.distance > max{
max = item.distance
viewtoscale = item.view
}
}
if viewtoscale != nil{
if viewtoscale != self.slider || viewtoscale != tempImageView || viewtoscale != drawView{
if viewtoscale is UIImageView{
viewtoscale.transform = viewtoscale.transform.scaledBy(x: sender.scale, y: sender.scale)
}
}
}
sender.scale = 1
}
}
获取交叉点和距离的功能:
func getIntersectionOfLines(line1: (a: CGPoint, b: CGPoint), line2: (a: CGPoint, b: CGPoint)) -> CGPoint {
let distance = (line1.b.x - line1.a.x) * (line2.b.y - line2.a.y) - (line1.b.y - line1.a.y) * (line2.b.x - line2.a.x)
if distance == 0 {
print("error, parallel lines")
return CGPoint.zero
}
let u = ((line2.a.x - line1.a.x) * (line2.b.y - line2.a.y) - (line2.a.y - line1.a.y) * (line2.b.x - line2.a.x)) / distance
let v = ((line2.a.x - line1.a.x) * (line1.b.y - line1.a.y) - (line2.a.y - line1.a.y) * (line1.b.x - line1.a.x)) / distance
if (u < 0.0 || u > 1.0) {
print("error, intersection not inside line1")
return CGPoint.zero
}
if (v < 0.0 || v > 1.0) {
print("error, intersection not inside line2")
return CGPoint.zero
}
return CGPoint(x: line1.a.x + u * (line1.b.x - line1.a.x), y: line1.a.y + u * (line1.b.y - line1.a.y))
}
func distance(_ a: CGPoint, _ b: CGPoint) -> CGFloat {
let xDist = a.x - b.x
let yDist = a.y - b.y
return CGFloat(sqrt((xDist * xDist) + (yDist * yDist)))
}
答案 0 :(得分:0)
您可以为每个imageView
设置标记,并将 selectedSticker 声明为Int,当用户在贴纸中将selectedSticker设置为其标记时,然后只需缩放所选贴纸。