当前位置:  开发笔记 > IOS > 正文

如何通过从边缘拖动来调整UIView的大小?

如何解决《如何通过从边缘拖动来调整UIView的大小?》经验,为你挑选了5个好方法。

在我的iPad应用程序中,我希望用户能够UIView通过从边缘拖动视图来调整大小.我将使用iOS 5 SDK,那么最简洁的方法是什么?如果不处理touchesBegan,touchesMoved等等,有没有其他方法可以实现这一目标?



1> Prerna chava..:

您可以通过检查触摸起点来完成此操作.如果它碰到四个角中的一个,您可以根据触摸起点和当前触点之间的距离调整大小.(如果触摸起点没有碰到角落,我们只是移动视图而不是调整大小.)

定义可拖动角落的大小.

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

推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有