gpt4 book ai didi

ios - 如何将拖动移动功能添加到转换后的 View ?

转载 作者:行者123 更新时间:2023-11-28 08:24:27 27 4
gpt4 key购买 nike

我制作了一个自定义 View ,可以通过拖动角圆按钮来调整大小和旋转。

我需要 View 能够通过拖动来改变它的位置。

我尝试了几种方法,但没有一个有效的属性(当结合旋转和调整大小操作时, View 表现得很奇怪)。

执行此操作的正确方法是什么?

根据这个引用苹果文档的答案,What to use to move UIView self.frame or self.transform property?我不应该将 frame 属性与转换一起使用,所以我假设我需要使用 CGAffineTransform 来更改 View 的位置?(我试过了,但效果不佳)

import Foundation
import UIKit

class ResizeRotateView: UIImageView, Resizable {

private let buttonWidth: CGFloat = 40
private var themeColor: UIColor = UIColor.magentaColor()


// Rotation Resize
var radian: CGFloat = 0

private var tempAnglePanStart : Float = 0
private var tempAngleLastPanEnd: Float = 0


// UI Subviews
lazy var cornerButton: UIView = {
let b = UIView()

b.layer.cornerRadius = self.buttonWidth / 2
b.layer.borderWidth = 1
b.layer.borderColor = self.themeColor.CGColor

let panGesture = UIPanGestureRecognizer(target: self, action: #selector(buttonTouchMoved) )
b.addGestureRecognizer(panGesture)

return b
}()




// Init

override init(frame: CGRect) {
super.init(frame: frame)

setupSuviews()
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}


func setupSuviews() {
addSubview( cornerButton )
addConstraintsWithFormat("H:[v0(\(buttonWidth))]", views: cornerButton)
addConstraintsWithFormat("V:[v0(\(buttonWidth))]", views: cornerButton)
addConstraint(NSLayoutConstraint(item: cornerButton, attribute: .CenterX, relatedBy: .Equal, toItem: self, attribute: .Right, multiplier: 1, constant: 0))
addConstraint(NSLayoutConstraint(item: cornerButton, attribute: .CenterY, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1, constant: 0))
}


override func hitTest(point: CGPoint, withEvent e: UIEvent?) -> UIView? { // This will enable gesture out of self.view's boundary. From stackoverflow.

if let result = super.hitTest(point, withEvent:e) {
return result
}

for sub in self.subviews.reverse() {
let pt = self.convertPoint(point, toView:sub)
if let result = sub.hitTest(pt, withEvent:e) {
return result
}
}
return nil
}







////// Event

func buttonTouchMoved(gestureRecognizer: UIPanGestureRecognizer) {

resize(gestureRecognizer)
rotate(gestureRecognizer)
}








////// Action

// Resize
func resize(gestureRecognizer: UIPanGestureRecognizer) {

// Temporary set aglet to 0
self.transform = CGAffineTransformMakeRotation( 0 )

// Resize
let locationInSelf = gestureRecognizer.locationInView(self)

resizeByKeepingAspectRatioByDistanceFromCenter(toLocation: locationInSelf)
layoutSubviews()

// Recover angle
self.transform = CGAffineTransformMakeRotation( radian )
layoutSubviews()

}



// Rotation
func rotate(gestureRecognizer: UIPanGestureRecognizer) {

guard let superView = self.superview else {
print("#Error: Super View not found")
return
}

let angle = self.angle(byLocation: gestureRecognizer.locationInView( superView ) )


if gestureRecognizer.state == .Began {
print("Pan begin:\(angle)")
tempAnglePanStart = angle - tempAngleLastPanEnd
}


let destinationAngle = angle - tempAnglePanStart
self.transform = CGAffineTransformMakeRotation( destinationAngle.degreesToRadians )


if gestureRecognizer.state == .Ended {
print("Pan ended")
tempAngleLastPanEnd = destinationAngle
}
}













////// Helper

func angle( firstPoint: CGPoint, secondPoint: CGPoint ) -> Float {

let dx = firstPoint.x - secondPoint.x
let dy = firstPoint.y - secondPoint.y
let angle = atan2(dy, dx).radiansToDegrees
let angleInFloat = Float( angle.double )

let formattedAngle = angleInFloat < 0 ? angleInFloat + 360.0 : angleInFloat

return formattedAngle
}


func angle(byLocation location: CGPoint) -> Float {

let targetViewCnter = self.center
return self.angle(targetViewCnter, secondPoint: location)
}

func setAngle(angle: Float) {
let radian = angle.degreesToRadians
self.transform = CGAffineTransformMakeRotation( radian )
self.radian = radian
}
}

enter image description here enter image description here


更新

我已经很接近了。我可以通过保持旋转角度和 View 大小来移动。剩下的问题是当我开始拖动时 View 跳动了一点。

import Foundation
import UIKit

class ResizeRorateMovableView: ResizeRotateView {

var startCenter: CGPoint = CGPointZero


override init(frame: CGRect) {
super.init(frame: frame)

setupSuviews()

let panGesture = UIPanGestureRecognizer(target: self, action: #selector(panGestureEvent))
addGestureRecognizer( panGesture )
userInteractionEnabled = true
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}



func panGestureEvent(panGesture: UIPanGestureRecognizer) {

if panGesture.state == .Began {
self.startCenter = self.center
return
}

if panGesture.state == .Changed {

let location = panGesture.translationInView(self)

// Rotate first, then move
var transfrom = CGAffineTransformMakeRotation( self.radian )
transfrom = CGAffineTransformTranslate(transfrom, location.x, location.y)
self.transform = transfrom

return
}

}
}

最佳答案

它可能会跳动,因为用户不一定要触摸中心,但您将中心设置为他们拖动的位置。如果您开始靠近中心拖动,它不会像您开始靠近边缘拖动那样跳跃。要修复,当手势开始时,获取从触摸到当前中心的距离,并在进行平移时使用该偏移量。

关于ios - 如何将拖动移动功能添加到转换后的 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40477747/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com