在我的iPad应用程序中,我希望用户能够UIView
通过从边缘拖动视图来调整大小.我将使用iOS 5 SDK,那么最简洁的方法是什么?如果不处理touchesBegan,touchesMoved等等,有没有其他方法可以实现这一目标?
您可以通过检查触摸起点来完成此操作.如果它碰到四个角中的一个,您可以根据触摸起点和当前触点之间的距离调整大小.(如果触摸起点没有碰到角落,我们只是移动视图而不是调整大小.)
CGFloat kResizeThumbSize = 45.0f;
@interface MY_CLASS_NAME : UIView { BOOL isResizingLR; BOOL isResizingUL; BOOL isResizingUR; BOOL isResizingLL; CGPoint touchStart; }
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; touchStart = [[touches anyObject] locationInView:self]; isResizingLR = (self.bounds.size.width - touchStart.x < kResizeThumbSize && self.bounds.size.height - touchStart.y < kResizeThumbSize); isResizingUL = (touchStart.x
2> Jim Puls..:我猜你的UI涉及视图两侧的某种句柄,并且将一个简单的附加
UIPanGestureRecognizer
到那些句柄控件使整个问题变得非常容易.在来自手势识别器的动作方法中,只需获取
-translationInView:
要调整大小的视图的相对值,在手势识别器的状态为时保存原始帧UIGestureRecognizerStateBegan
,并在状态为时连续调整视图的帧UIGestureRecognizerStateChanged
.
3> 小智..:我用上面的代码更新了
enum
.class ResizableView: UIView { enum Edge { case topLeft, topRight, bottomLeft, bottomRight, none } static var edgeSize: CGFloat = 44.0 private typealias `Self` = ResizableView var currentEdge: Edge = .none var touchStart = CGPoint.zero override func touchesBegan(_ touches: Set, with event: UIEvent?) { if let touch = touches.first { touchStart = touch.location(in: self) currentEdge = { if self.bounds.size.width - touchStart.x < Self.edgeSize && self.bounds.size.height - touchStart.y < Self.edgeSize { return .bottomRight } else if touchStart.x < Self.edgeSize && touchStart.y < Self.edgeSize { return .topLeft } else if self.bounds.size.width-touchStart.x < Self.edgeSize && touchStart.y < Self.edgeSize { return .topRight } else if touchStart.x < Self.edgeSize && self.bounds.size.height - touchStart.y < Self.edgeSize { return .bottomLeft } return .none }() } } override func touchesMoved(_ touches: Set , with event: UIEvent?) { if let touch = touches.first { let currentPoint = touch.location(in: self) let previous = touch.previousLocation(in: self) let originX = self.frame.origin.x let originY = self.frame.origin.y let width = self.frame.size.width let height = self.frame.size.height let deltaWidth = currentPoint.x - previous.x let deltaHeight = currentPoint.y - previous.y switch currentEdge { case .topLeft: self.frame = CGRect(x: originX + deltaWidth, y: originY + deltaHeight, width: width - deltaWidth, height: height - deltaHeight) case .topRight: self.frame = CGRect(x: originX, y: originY + deltaHeight, width: width + deltaWidth, height: height - deltaHeight) case .bottomRight: self.frame = CGRect(x: originX, y: originY, width: currentPoint.x + deltaWidth, height: currentPoint.y + deltaWidth) case .bottomLeft: self.frame = CGRect(x: originX + deltaWidth, y: originY, width: width - deltaWidth, height: height + deltaHeight) default: // Moving self.center = CGPoint(x: self.center.x + currentPoint.x - touchStart.x, y: self.center.y + currentPoint.y - touchStart.y) } } } override func touchesEnded(_ touches: Set , with event: UIEvent?) { currentEdge = .none } }
currentEdge
保存用户的触摸位置状态.
4> Jasmeet Kaur..:Swift版本的@Prerna Chavan解决方案,Prerna解决方案不检测用户是否触摸边缘,它只检测角落,但是下面代码检测到所有
class OverlayView: UIView { /* // Only override draw() if you perform custom drawing. // An empty implementation adversely affects performance during animation. override func draw(_ rect: CGRect) { // Drawing code } */ static var kResizeThumbSize:CGFloat = 44.0 private typealias `Self` = OverlayView var imageView = UIImageView() var isResizingLeftEdge:Bool = false var isResizingRightEdge:Bool = false var isResizingTopEdge:Bool = false var isResizingBottomEdge:Bool = false var isResizingBottomRightCorner:Bool = false var isResizingLeftCorner:Bool = false var isResizingRightCorner:Bool = false var isResizingBottomLeftCorner:Bool = false //Define your initialisers here override func touchesBegan(_ touches: Set, with event: UIEvent?) { if let touch = touches.first { let currentPoint = touch.location(in: self) isResizingBottomRightCorner = (self.bounds.size.width - currentPoint.x < Self.kResizeThumbSize && self.bounds.size.height - currentPoint.y < Self.kResizeThumbSize); isResizingLeftCorner = (currentPoint.x < Self.kResizeThumbSize && currentPoint.y < Self.kResizeThumbSize); isResizingRightCorner = (self.bounds.size.width-currentPoint.x < Self.kResizeThumbSize && currentPoint.y < Self.kResizeThumbSize); isResizingBottomLeftCorner = (currentPoint.x < Self.kResizeThumbSize && self.bounds.size.height - currentPoint.y < Self.kResizeThumbSize); isResizingLeftEdge = (currentPoint.x < Self.kResizeThumbSize) isResizingTopEdge = (currentPoint.y < Self.kResizeThumbSize) isResizingRightEdge = (self.bounds.size.width - currentPoint.x < Self.kResizeThumbSize) isResizingBottomEdge = (self.bounds.size.height - currentPoint.y < Self.kResizeThumbSize) // do something with your currentPoint } } override func touchesMoved(_ touches: Set , with event: UIEvent?) { if let touch = touches.first { let currentPoint = touch.location(in: self) // do something with your currentPoint } } override func touchesEnded(_ touches: Set , with event: UIEvent?) { if let touch = touches.first { let currentPoint = touch.location(in: self) // do something with your currentPoint isResizingLeftEdge = false isResizingRightEdge = false isResizingTopEdge = false isResizingBottomEdge = false isResizingBottomRightCorner = false isResizingLeftCorner = false isResizingRightCorner = false isResizingBottomLeftCorner = false } }
5> Peter Pohlma..:这是一个Swift 4.2解决方案,可与AutoLayout&Constraint-Animation一起使用。
由于在使用AutoLayout时建议设置动画约束而不是矩形的实际大小,因此此解决方案可以做到这一点。
附加的功能:
如果不在边缘,则仅调整一侧的大小。
触摸整个矩形,将其移动到中间。
在此处签出视频:https: //imgur.com/a/CrkARLi
导入是将约束作为出口连接,以对其进行动画处理。
import UIKit class ViewController: UIViewController { @IBOutlet weak var topConstraint: NSLayoutConstraint! @IBOutlet weak var rightConstraint: NSLayoutConstraint! @IBOutlet weak var leftConstraint: NSLayoutConstraint! @IBOutlet weak var bottomConstraint: NSLayoutConstraint! @IBOutlet weak var rect: UIView! struct ResizeRect{ var topTouch = false var leftTouch = false var rightTouch = false var bottomTouch = false var middelTouch = false } var touchStart = CGPoint.zero var proxyFactor = CGFloat(10) var resizeRect = ResizeRect() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func touchesBegan(_ touches: Set, with event: UIEvent?) { if let touch = touches.first{ let touchStart = touch.location(in: self.view) print(touchStart) resizeRect.topTouch = false resizeRect.leftTouch = false resizeRect.rightTouch = false resizeRect.bottomTouch = false resizeRect.middelTouch = false if touchStart.y > rect.frame.minY + (proxyFactor*2) && touchStart.y < rect.frame.maxY - (proxyFactor*2) && touchStart.x > rect.frame.minX + (proxyFactor*2) && touchStart.x < rect.frame.maxX - (proxyFactor*2){ resizeRect.middelTouch = true print("middle") return } if touchStart.y > rect.frame.maxY - proxyFactor && touchStart.y < rect.frame.maxY + proxyFactor { resizeRect.bottomTouch = true print("bottom") } if touchStart.x > rect.frame.maxX - proxyFactor && touchStart.x < rect.frame.maxX + proxyFactor { resizeRect.rightTouch = true print("right") } if touchStart.x > rect.frame.minX - proxyFactor && touchStart.x < rect.frame.minX + proxyFactor { resizeRect.leftTouch = true print("left") } if touchStart.y > rect.frame.minY - proxyFactor && touchStart.y < rect.frame.minY + proxyFactor { resizeRect.topTouch = true print("top") } } } override func touchesMoved(_ touches: Set , with event: UIEvent?) { if let touch = touches.first{ let currentTouchPoint = touch.location(in: self.view) let previousTouchPoint = touch.previousLocation(in: self.view) let deltaX = currentTouchPoint.x - previousTouchPoint.x let deltaY = currentTouchPoint.y - previousTouchPoint.y if resizeRect.middelTouch{ topConstraint.constant += deltaY leftConstraint.constant += deltaX rightConstraint.constant -= deltaX bottomConstraint.constant -= deltaY } if resizeRect.topTouch { topConstraint.constant += deltaY } if resizeRect.leftTouch { leftConstraint.constant += deltaX } if resizeRect.rightTouch { rightConstraint.constant -= deltaX } if resizeRect.bottomTouch { bottomConstraint.constant -= deltaY } UIView.animate(withDuration: 0.25, delay: 0, options: UIView.AnimationOptions.curveEaseIn, animations: { self.view.layoutIfNeeded() }, completion: { (ended) in }) } } } 我也把它作为工作项目放在Github上:https : //github.com/ppoh71/resizeRectangleOnTouchDrag