繁体   English   中英

通过按下圆角上的圆圈并拖动它使其变小/变大来调整 ImageView 的大小

[英]Resize ImageView by pressing on a circle on it's corner and dragging it to make it smaller/bigger

我一直在做这个包含 UIImageView 的小应用程序。我可以点击它,图像的每个角上应该会出现 4 个圆圈。 我必须能够从角落拖动手指来调整图像大小。 但是调整大小不起作用。 据我了解-我必须在touchesMoved方法中更新 imageView 的约束。

我正在使用这篇文章作为参考: How to resize UIView by dragging from its edges?

设置 imageView,scrollView 和按钮

 struct ResizeRect{
        var topTouch = false
        var leftTouch = false
        var rightTouch = false
        var bottomTouch = false
        var middelTouch = false
    }

这是我在角落里的圈子

   private var topLeftCircleLayer: CAShapeLayer!
   private var topRightCircleLayer: CAShapeLayer!
   private var bottomLeftCircleLayer: CAShapeLayer!
   private var bottomRightCircleLayer: CAShapeLayer!

imageView 的约束条件

    private var imageViewTopConstraint: NSLayoutConstraint!
    private var imageViewBottomConstraint: NSLayoutConstraint!
    private var imageViewLeadingConstraint: NSLayoutConstraint!
    private var imageViewTrailingConstraint: NSLayoutConstraint!
    private var originalImageFrame: CGRect = .zero
    private var resizeRect = ResizeRect()

设置我的视图

 override func viewDidLoad() {
        super.viewDidLoad()

        scrollView.delegate = self

        setupView()

        addTapGestureRecognizer()
        addPinchGestureRecognizer()
        addRotateButton()
        addDeletePhotoButton()
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        borderLayer.path = UIBezierPath(rect: imageView.bounds).cgPath
        addConstraintsForItems()
        createCircles()
    }

    private func addConstraintsForItems() {
        imageViewTopConstraint = imageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 180)
        imageViewBottomConstraint = imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -180)
        imageViewLeadingConstraint = imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 70)
        imageViewTrailingConstraint = imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -70)

        NSLayoutConstraint.activate([imageViewTopConstraint, imageViewBottomConstraint, imageViewLeadingConstraint, imageViewTrailingConstraint])
   }

    private func setupView() {
        view.addSubview(scrollView)
        view.addSubview(rotateButton)
        view.addSubview(deleteButton)

        scrollView.addSubview(imageView)

        borderLayer.fillColor = UIColor.clear.cgColor
        borderLayer.strokeColor = UIColor.black.cgColor
        borderLayer.lineWidth = 2
        borderLayer.isHidden = true
        imageView.layer.addSublayer(borderLayer)
    }

圈子创建

     private func updateCircles() {
        let topLeft = CGPoint(x: imageView.frame.minX, y: imageView.frame.minY)
        topLeftCircleLayer.position = topLeft
        let topRight = CGPoint(x: imageView.frame.maxX, y: imageView.frame.minY)
        topRightCircleLayer.position = topRight
        let bottomLeft = CGPoint(x: imageView.frame.minX, y: imageView.frame.maxY)
        bottomLeftCircleLayer.position = bottomLeft
        let bottomRight = CGPoint(x: imageView.frame.maxX, y: imageView.frame.maxY)
        bottomRightCircleLayer.position = bottomRight
        imageView.layer.insertSublayer(topLeftCircleLayer, at: 0)
        imageView.layer.insertSublayer(topRightCircleLayer, at: 1)
        imageView.layer.insertSublayer(bottomLeftCircleLayer, at: 2)
        imageView.layer.insertSublayer(bottomRightCircleLayer, at: 3)
    }

    private func createCircles() {
        topLeftCircleLayer = createCircle(at: CGPoint(x: imageView.frame.minX, y: imageView.frame.minY))
        topRightCircleLayer = createCircle(at: CGPoint(x: imageView.frame.maxX, y: imageView.frame.minY))
        bottomLeftCircleLayer = createCircle(at: CGPoint(x: imageView.frame.minX, y: imageView.frame.maxY))
        bottomRightCircleLayer = createCircle(at: CGPoint(x: imageView.frame.maxX, y: imageView.frame.maxY))
    }

    private func createCircle(at position: CGPoint) -> CAShapeLayer {
        let circle = CAShapeLayer()
        circle.path = UIBezierPath(arcCenter: position, radius: 10, startAngle: 0, endAngle: .pi * 2, clockwise: true).cgPath
        circle.fillColor = UIColor.systemPink.cgColor
        circle.strokeColor = UIColor.white.cgColor
        circle.lineWidth = 6
        circle.isHidden = !isCirclesVisible
        imageView.layer.addSublayer(circle)
        return circle
    }

这是我尝试拖动角落的最重要部分

 override func touchesBegan(_ touches: Set<UITouch>, 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

            if touchStart.y > imageView.frame.maxY - proxyFactor &&  touchStart.y < imageView.frame.maxY + proxyFactor {
                resizeRect.bottomTouch = true
                print("bottom")
            }

            if touchStart.x > imageView.frame.maxX - proxyFactor && touchStart.x < imageView.frame.maxX + proxyFactor {
                resizeRect.rightTouch = true
                print("right")
            }

            if touchStart.x > imageView.frame.minX - proxyFactor &&  touchStart.x < imageView.frame.minX + proxyFactor {
                resizeRect.leftTouch = true
                print("left")
            }

            if touchStart.y > imageView.frame.minY - proxyFactor &&  touchStart.y < imageView.frame.minY + proxyFactor {
                resizeRect.topTouch = true
                print("top")
            }

        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, 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.topTouch && resizeRect.leftTouch {
                if imageViewTopConstraint.constant + deltaY > 0 && imageViewLeadingConstraint.constant + deltaX > 0 {
                    imageViewTopConstraint.constant += deltaY
                    imageViewLeadingConstraint.constant += deltaX

                }
            }
            if resizeRect.topTouch && resizeRect.rightTouch {
                if imageViewTopConstraint.constant + deltaY > 0 && imageViewTrailingConstraint.constant - deltaX > 0 {
                    imageViewTopConstraint.constant += deltaY
                    imageViewTrailingConstraint.constant -= deltaX
                }
            }
            if resizeRect.bottomTouch && resizeRect.leftTouch {
                if imageViewBottomConstraint.constant - deltaY > 0 && imageViewLeadingConstraint.constant + deltaX > 0 {
                    imageViewLeadingConstraint.constant += deltaX
                    imageViewBottomConstraint.constant -= deltaY
                }
            }
            if resizeRect.bottomTouch && resizeRect.rightTouch {
                if imageViewBottomConstraint.constant - deltaY > 0 && imageViewTrailingConstraint.constant - deltaX > 0 {
                    imageViewTrailingConstraint.constant -= deltaX
                    imageViewBottomConstraint.constant -= deltaY
                }
            }

            UIView.animate(withDuration: 0.25, delay: 0, options: UIView.AnimationOptions.curveEaseIn) {
                self.view.layoutIfNeeded()
            }
        }
    } 

编辑 1:我稍微更新了我的代码。 当我触摸 imageView 时,我的应用程序终于明白了,当我触摸一个角时,它可以说出哪个角被触摸了,但调整大小无法正常工作。 有时它可以工作,但调整大小的速度非常慢。 在控制台中它说我有这个错误:

Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x600000cf8910 H:|-(65)-[UIImageView:0x13a707300]   (active, names: '|':UIView:0x13c20f220 )>",
    "<NSLayoutConstraint:0x600000ce0640 H:|-(70)-[UIImageView:0x13a707300]   (active, names: '|':UIView:0x13c20f220 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600000ce0640 H:|-(70)-[UIImageView:0x13a707300]   (active, names: '|':UIView:0x13c20f220 )>

我尝试更新约束,但出于某种原因它不允许我这样做。 从一个编写解决方案的人那里克隆了 github 项目 他制作了 IBOutlets 用于约束,据我所知 - 从 IBOutlets 创建的约束与我拥有的约束有些不同。 如何解决约束问题? 如果有人能注意到我创建的圈子有什么问题,我将不胜感激。 现在我只看到图像中间下方的 1 ...

你的方法有几个问题......

首先,这些都不是:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    borderLayer.path = UIBezierPath(rect: imageView.bounds).cgPath
    addConstraintsForItems()
    createCircles()
}

应该在那里。 viewDidLayoutSubviews()被多次调用,如果您正在更改视图/约束,它将被调用多次。

其次,您可能无法让 GitHub 项目使用代码设置(与使用@IBOutlet连接的 Storyboard 设置相反)是因为约束的顺序颠倒了。

在您的代码中,您在 imageView 上设置了所有 4 个约束,从imageView -> view开始。 可以像这样复制 Storyboard 设置:

// top and leading constraints need to be imageView -> view
imageViewTopConstraint = imageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 180)
imageViewLeadingConstraint = imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 70)
    
// trailing and bottom constraints need to be view -> imageView
imageViewTrailingConstraint = view.trailingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: 70)
imageViewBottomConstraint = view.bottomAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 180)
    

第三,您在某些需要使用.frame的地方使用.bounds

这是您的代码的修改版本。 我不知道你是如何决定何时显示/隐藏圆角的,所以我添加了一个双击手势来激活/停用“调整大小”模式:

class ResizeViewViewController: UIViewController {

    private var topLeftCircleLayer: CAShapeLayer!
    private var topRightCircleLayer: CAShapeLayer!
    private var bottomLeftCircleLayer: CAShapeLayer!
    private var bottomRightCircleLayer: CAShapeLayer!

    private var borderLayer: CAShapeLayer!

    private var imageViewTopConstraint: NSLayoutConstraint!
    private var imageViewBottomConstraint: NSLayoutConstraint!
    private var imageViewLeadingConstraint: NSLayoutConstraint!
    private var imageViewTrailingConstraint: NSLayoutConstraint!

    private var originalImageFrame: CGRect = .zero
    private var resizeRect = ResizeRect()

    private var proxyFactor: CGFloat = 10.0

    private var imageView = UIImageView()
    
    private var isResizing: Bool = false {
        didSet {
            // update circle positions and
            //  show or hide the circles and border
            updateCircles()
            topLeftCircleLayer.isHidden = !isResizing
            topRightCircleLayer.isHidden = !isResizing
            bottomLeftCircleLayer.isHidden = !isResizing
            bottomRightCircleLayer.isHidden = !isResizing
            borderLayer.isHidden = !isResizing
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
        
        setupView()

        addConstraintsForItems()
        
        createCircles()
        
        isResizing = false
        
        // let's use double-tap on the image view to
        //  toggle resizing
        let t = UITapGestureRecognizer(target: self, action: #selector(gotDoubleTap(_:)))
        t.numberOfTapsRequired = 2
        imageView.addGestureRecognizer(t)
        imageView.isUserInteractionEnabled = true

        // an instructions label at the top
        let v = UILabel()
        v.textAlignment = .center
        v.text = "Double-Tap image to toggle resizing mode."
        v.translatesAutoresizingMaskIntoConstraints = false
        // put it under the image view so it doesn't interfere
        view.insertSubview(v, at: 0)
        NSLayoutConstraint.activate([
            v.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20.0),
            v.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor),
        ])
        
    }
    
    @objc func gotDoubleTap(_ sender: Any?) {
        isResizing.toggle()
    }

    private func addConstraintsForItems() {

        // top and leading constraints need to be imageView -> view
        imageViewTopConstraint = imageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 180)
        imageViewLeadingConstraint = imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 70)

        // trailing and bottom constraints need to be view -> imageView
        imageViewTrailingConstraint = view.trailingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: 70)
        imageViewBottomConstraint = view.bottomAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 180)
        
        NSLayoutConstraint.activate([
            imageViewTopConstraint, imageViewBottomConstraint, imageViewLeadingConstraint, imageViewTrailingConstraint
        ])
    }

    private func setupView() {

        // add the image view
        imageView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(imageView)

        imageView.backgroundColor = .systemYellow

        // let's use the "swift" SF Symbol image
        if let img = UIImage(systemName: "swift") {
            imageView.image = img
            imageView.tintColor = .systemBlue
        }

        borderLayer = CAShapeLayer()
        borderLayer.fillColor = UIColor.clear.cgColor
        borderLayer.strokeColor = UIColor.black.cgColor
        borderLayer.lineWidth = 2
        borderLayer.isHidden = true
        imageView.layer.addSublayer(borderLayer)
        
    }

    private func updateCircles() {
        
        // we need to disable CALayer internal animations when
        //  changing the positions of the layers
        CATransaction.begin()
        CATransaction.setDisableActions(true)

        let topLeft = CGPoint(x: imageView.bounds.minX, y: imageView.bounds.minY)
        topLeftCircleLayer.position = topLeft
        let topRight = CGPoint(x: imageView.bounds.maxX, y: imageView.bounds.minY)
        topRightCircleLayer.position = topRight
        let bottomLeft = CGPoint(x: imageView.bounds.minX, y: imageView.bounds.maxY)
        bottomLeftCircleLayer.position = bottomLeft
        let bottomRight = CGPoint(x: imageView.bounds.maxX, y: imageView.bounds.maxY)
        bottomRightCircleLayer.position = bottomRight
        
        borderLayer.path = UIBezierPath(rect: imageView.bounds).cgPath
        
        CATransaction.commit()
        
    }

    private func createCircles() {
        // no need to pass "positions" here... they will be set when we show / update them
        topLeftCircleLayer = createCircle()
        topRightCircleLayer = createCircle()
        bottomLeftCircleLayer = createCircle()
        bottomRightCircleLayer = createCircle()

        // add the layers here
        imageView.layer.addSublayer(topLeftCircleLayer)
        imageView.layer.addSublayer(topRightCircleLayer)
        imageView.layer.addSublayer(bottomLeftCircleLayer)
        imageView.layer.addSublayer(bottomRightCircleLayer)
    }

    private func createCircle() -> CAShapeLayer {
        let circle = CAShapeLayer()
        circle.path = UIBezierPath(arcCenter: .zero, radius: 10, startAngle: 0, endAngle: .pi * 2, clockwise: true).cgPath
        circle.fillColor = UIColor.systemPink.cgColor
        circle.strokeColor = UIColor.white.cgColor
        circle.lineWidth = 6
        circle.isHidden = true
        return circle
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        if !isResizing { return() }
        
        if let touch = touches.first{
            
            let touchStart = touch.location(in: self.view)
            print(touchStart, imageView.frame)
            
            resizeRect.topTouch = false
            resizeRect.leftTouch = false
            resizeRect.rightTouch = false
            resizeRect.bottomTouch = false
            
            if touchStart.y > imageView.frame.maxY - proxyFactor &&  touchStart.y < imageView.frame.maxY + proxyFactor {
                resizeRect.bottomTouch = true
                print("bottom")
            }
            
            if touchStart.x > imageView.frame.maxX - proxyFactor && touchStart.x < imageView.frame.maxX + proxyFactor {
                resizeRect.rightTouch = true
                print("right")
            }
            
            if touchStart.x > imageView.frame.minX - proxyFactor &&  touchStart.x < imageView.frame.minX + proxyFactor {
                resizeRect.leftTouch = true
                print("left")
            }
            
            if touchStart.y > imageView.frame.minY - proxyFactor &&  touchStart.y < imageView.frame.minY + proxyFactor {
                resizeRect.topTouch = true
                print("top")
            }

        }
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        if !isResizing { return() }

        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.topTouch {
                imageViewTopConstraint.constant += deltaY
            }
            if resizeRect.leftTouch {
                imageViewLeadingConstraint.constant += deltaX
            }
            if resizeRect.rightTouch {
                imageViewTrailingConstraint.constant -= deltaX
            }
            if resizeRect.bottomTouch {
                imageViewBottomConstraint.constant -= deltaY
            }

            // don't know why you would want to animate this?
            //UIView.animate(withDuration: 0.25, delay: 0, options: UIView.AnimationOptions.curveEaseIn, animations: {
            //  self.view.layoutIfNeeded()
            //}, completion: { (ended) in
            //
            //})

            // note: this can "lag" and not precisely match the image view frame
            
            self.updateCircles()
            
            //  we can dispatch it async to allow UIKit to set the
            //  image view's frame before we move the layers
            //  but we still get a little "lag"
            DispatchQueue.main.async {
                self.updateCircles()
            }

        }

    }

}

struct ResizeRect{
    var topTouch = false
    var leftTouch = false
    var rightTouch = false
    var bottomTouch = false
    var middelTouch = false
}

当您运行它时,您会注意到在拖动和调整大小时存在一些“滞后”——请参阅代码中的注释。

一种类似的方法可能会发现它的响应速度更快,并且更易于管理……

我们将添加“圆形视图”作为图像视图的子视图,而不是添加“圆形图层”。 然后我们可以对图像视图角设置约束,并让自动布局处理所有定位。

更少的代码……利用自动布局……更灵敏……

首先运行上面的版本,然后试试这个:

class CircleView: UIView {
    
    // this allows us to use the "base" layer as a shape layer
    //  instead of adding a sublayer
    lazy var shapeLayer: CAShapeLayer = self.layer as! CAShapeLayer
    override class var layerClass: AnyClass {
        return CAShapeLayer.self
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    func commonInit() {
        shapeLayer.fillColor = UIColor.systemPink.cgColor
        shapeLayer.strokeColor = UIColor.white.cgColor
        shapeLayer.lineWidth = 6
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        shapeLayer.path = UIBezierPath(ovalIn: bounds).cgPath
    }

}

class ResizeViewViewController: UIViewController {
    
    private var topLeftCircleView = CircleView()
    private var topRightCircleView = CircleView()
    private var bottomLeftCircleView = CircleView()
    private var bottomRightCircleView = CircleView()
    
    private var borderView = UIView()
    
    private var imageViewTopConstraint: NSLayoutConstraint!
    private var imageViewBottomConstraint: NSLayoutConstraint!
    private var imageViewLeadingConstraint: NSLayoutConstraint!
    private var imageViewTrailingConstraint: NSLayoutConstraint!
    
    private var originalImageFrame: CGRect = .zero
    private var resizeRect = ResizeRect()
    
    private var proxyFactor: CGFloat = 10.0
    
    private var imageView = UIImageView()
    
    private var isResizing: Bool = false {
        didSet {
            // show or hide the circles and image view border
            [topLeftCircleView, topRightCircleView, bottomLeftCircleView, bottomRightCircleView].forEach { v in
                v.isHidden = !isResizing
            }
            borderView.layer.borderWidth = isResizing ? 2.0 : 0.0
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
        
        setupView()
        
        addConstraintsForItems()
        
        createCircles()
        
        isResizing = false

        // let's use double-tap on the image view to
        //  toggle resizing
        let t = UITapGestureRecognizer(target: self, action: #selector(gotDoubleTap(_:)))
        t.numberOfTapsRequired = 2
        imageView.addGestureRecognizer(t)
        imageView.isUserInteractionEnabled = true

        // an instructions label at the top
        let v = UILabel()
        v.textAlignment = .center
        v.text = "Double-Tap image to toggle resizing mode."
        v.font = .systemFont(ofSize: 15.0, weight: .light)
        v.translatesAutoresizingMaskIntoConstraints = false
        // put it under the image view so it doesn't interfere
        view.insertSubview(v, at: 0)
        NSLayoutConstraint.activate([
            v.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20.0),
            v.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor),
        ])
        
    }
    
    @objc func gotDoubleTap(_ sender: Any?) {
        isResizing.toggle()
    }
    
    private func addConstraintsForItems() {
        
        // top and leading constraints need to be imageView -> view
        imageViewTopConstraint = imageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 180)
        imageViewLeadingConstraint = imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 70)
        
        // trailing and bottom constraints need to be view -> imageView
        imageViewTrailingConstraint = view.trailingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: 70)
        imageViewBottomConstraint = view.bottomAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 180)
        
        NSLayoutConstraint.activate([
            imageViewTopConstraint, imageViewBottomConstraint, imageViewLeadingConstraint, imageViewTrailingConstraint,

            // constrain all 4 sides of the borderView to the imageView
            borderView.topAnchor.constraint(equalTo: imageView.topAnchor),
            borderView.leadingAnchor.constraint(equalTo: imageView.leadingAnchor),
            borderView.trailingAnchor.constraint(equalTo: imageView.trailingAnchor),
            borderView.bottomAnchor.constraint(equalTo: imageView.bottomAnchor),
        ])
    }
    
    private func setupView() {

        // add the image view
        imageView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(imageView)

        imageView.backgroundColor = .systemYellow

        // add the borderView to the image view
        //  we'd like to just use the image view's layer border, but
        //  setting its border width draws on top of the circle subviews
        borderView.translatesAutoresizingMaskIntoConstraints = false
        imageView.addSubview(borderView)
        
        // let's use the "swift" SF Symbol image
        if let img = UIImage(systemName: "swift") {
            imageView.image = img
            imageView.tintColor = .systemBlue
        }
        
        // border view layer border starts at width: 0 (not showing)
        borderView.layer.borderColor = UIColor.black.cgColor
        borderView.layer.borderWidth = 0
        
    }
    

    private func createCircles() {

        // add the circle views to the image view
        //  constraining width: 20 and height = width
        [topLeftCircleView, topRightCircleView, bottomLeftCircleView, bottomRightCircleView].forEach { v in
            v.translatesAutoresizingMaskIntoConstraints = false
            v.widthAnchor.constraint(equalToConstant: 20.0).isActive = true
            v.heightAnchor.constraint(equalTo: v.widthAnchor).isActive = true
            // they start hidden
            v.isHidden = true
            imageView.addSubview(v)
        }
        
        // constrain circleViews to the image view corners
        NSLayoutConstraint.activate([
            topLeftCircleView.centerXAnchor.constraint(equalTo: imageView.leadingAnchor),
            topLeftCircleView.centerYAnchor.constraint(equalTo: imageView.topAnchor),
            
            topRightCircleView.centerXAnchor.constraint(equalTo: imageView.trailingAnchor),
            topRightCircleView.centerYAnchor.constraint(equalTo: imageView.topAnchor),
            
            bottomLeftCircleView.centerXAnchor.constraint(equalTo: imageView.leadingAnchor),
            bottomLeftCircleView.centerYAnchor.constraint(equalTo: imageView.bottomAnchor),
            
            bottomRightCircleView.centerXAnchor.constraint(equalTo: imageView.trailingAnchor),
            bottomRightCircleView.centerYAnchor.constraint(equalTo: imageView.bottomAnchor),
        ])

    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        // only want to drag-resize if the corner circles are showing
        if !isResizing { return() }
        
        if let touch = touches.first{
            
            let touchStart = touch.location(in: self.view)
            print(touchStart, imageView.frame)
            
            resizeRect.topTouch = false
            resizeRect.leftTouch = false
            resizeRect.rightTouch = false
            resizeRect.bottomTouch = false
            
            if touchStart.y > imageView.frame.maxY - proxyFactor &&  touchStart.y < imageView.frame.maxY + proxyFactor {
                resizeRect.bottomTouch = true
                print("bottom")
            }
            
            if touchStart.x > imageView.frame.maxX - proxyFactor && touchStart.x < imageView.frame.maxX + proxyFactor {
                resizeRect.rightTouch = true
                print("right")
            }
            
            if touchStart.x > imageView.frame.minX - proxyFactor &&  touchStart.x < imageView.frame.minX + proxyFactor {
                resizeRect.leftTouch = true
                print("left")
            }
            
            if touchStart.y > imageView.frame.minY - proxyFactor &&  touchStart.y < imageView.frame.minY + proxyFactor {
                resizeRect.topTouch = true
                print("top")
            }
            
        }
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        // only want to drag-resize if the corner circles are showing
        if !isResizing { return() }
        
        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.topTouch {
                imageViewTopConstraint.constant += deltaY
            }
            if resizeRect.leftTouch {
                imageViewLeadingConstraint.constant += deltaX
            }
            if resizeRect.rightTouch {
                imageViewTrailingConstraint.constant -= deltaX
            }
            if resizeRect.bottomTouch {
                imageViewBottomConstraint.constant -= deltaY
            }
            
            // don't know why you would want to animate this?
            //UIView.animate(withDuration: 0.25, delay: 0, options: UIView.AnimationOptions.curveEaseIn, animations: {
            //  self.view.layoutIfNeeded()
            //}, completion: { (ended) in
            //
            //})

        }
        
    }
    
}

struct ResizeRect{
    var topTouch = false
    var leftTouch = false
    var rightTouch = false
    var bottomTouch = false
    var middelTouch = false
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM