0

你可以在下面的 gif 中看到我的 swift 代码。让用户选择其中一个图像视图,然后使用滑块增加或减小该图像视图的大小。问题是当图像视图移动时,另一个图像视图跟随它,这不应该发生。因此,应在代码第一次运行但选择其中一个图像视图之后设置约束。将它们链接在一起的约束应该被停用。造成这种情况的一条线是

** greenMove.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant :0),**

在此处输入图像描述

import UIKit

class ViewController: UIViewController {



    var image1Width: NSLayoutConstraint!
    var image1Height: NSLayoutConstraint!
    var image1Width2: NSLayoutConstraint!
    var image1Height2: NSLayoutConstraint!
    var greenMove = UIImageView()
    var slider = UISlider()
    var blueMove = UIImageView()
    var existingTransition : CGAffineTransform?
    var clock = Int()
    var currentView: UIView?
    var g2 = UIPanGestureRecognizer()
    var g3 = UIPanGestureRecognizer()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        greenMove.isUserInteractionEnabled = true
        blueMove.isUserInteractionEnabled = true

        g2 = UIPanGestureRecognizer(target: self, action: #selector(ViewController.g1Method))
        greenMove.addGestureRecognizer(g2)
        g3 = UIPanGestureRecognizer(target: self, action: #selector(ViewController.g2Method))
        blueMove.addGestureRecognizer(g3)

        greenMove.backgroundColor = .systemGreen

        blueMove.backgroundColor = .blue


        [greenMove,slider,blueMove].forEach {

            view.addSubview($0)
            $0.translatesAutoresizingMaskIntoConstraints = false

        }


        //image11
        image1Width =  greenMove.widthAnchor.constraint(equalTo:  view.widthAnchor ,multiplier:  0.2)
        image1Height =  greenMove.heightAnchor.constraint(equalTo:  view.heightAnchor ,multiplier:  0.20)

        //image12
        image1Width2 =  blueMove.widthAnchor.constraint(equalTo:  view.widthAnchor ,multiplier:  0.2)
        image1Height2 =  blueMove.heightAnchor.constraint(equalTo:  view.heightAnchor ,multiplier:  0.20)



        NSLayoutConstraint.activate([

            greenMove.topAnchor.constraint(equalTo: view.topAnchor, constant : 0),
            image1Width,
            image1Height,
            greenMove.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant :0),


            blueMove.topAnchor.constraint(equalTo: view.topAnchor, constant : 0),
            image1Width2,
            image1Height2,
            blueMove.leadingAnchor.constraint(equalTo: greenMove.trailingAnchor, constant :0)

        ])








        slider.addTarget(self, action: #selector(hhh), for: .allEvents)

    }

    override func viewDidLayoutSubviews() {
        NSLayoutConstraint.activate ([




            slider.topAnchor.constraint(equalTo: view.topAnchor, constant : greenMove.bounds.height),
            slider.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.20, constant: 0),
            slider.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.20, constant: 0),
            slider.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant : 0),


        ])
    }
    @objc func handleTapGestured(_ gesture: UIPanGestureRecognizer) {
        currentView = gesture.view
    }

    @objc func g1Method(_ sender: UIPanGestureRecognizer){
        clock = 1
        let subview = greenMove
        guard let child = sender.view else{return}
        let transitionPoint = sender.translation(in: self.view)
        let newTransition = CGAffineTransform(translationX: transitionPoint.x, y: transitionPoint.y)
        switch sender.state {

        case .ended,.cancelled:// on End
            if let existing = existingTransition{
                self.existingTransition = newTransition.concatenating(existing)
            }else{
                self.existingTransition = newTransition
            }
        default://on change and other states
            if let existing = existingTransition{
                child.transform = newTransition
                    .concatenating(existing)
            }else{
                child.transform = newTransition
            }
        }
        self.view.layoutIfNeeded()


        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGestured(_:)))
        subview.addGestureRecognizer(tapGesture)


    }
    @objc func g2Method(_ sender: UIPanGestureRecognizer){
        clock = 2
        let subview = blueMove
        guard let child = sender.view else{return}
        let transitionPoint = sender.translation(in: self.view)
        let newTransition = CGAffineTransform(translationX: transitionPoint.x, y: transitionPoint.y)
        switch sender.state {

        case .ended,.cancelled:// on End
            if let existing = existingTransition{
                self.existingTransition = newTransition.concatenating(existing)
            }else{
                self.existingTransition = newTransition
            }
        default://on change and other states
            if let existing = existingTransition{
                child.transform = newTransition
                    .concatenating(existing)
            }else{
                child.transform = newTransition
            }
        }
        self.view.layoutIfNeeded()


        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGestured(_:)))
        subview.addGestureRecognizer(tapGesture)


    }
    @objc func hhh() {

        if clock ==  1 {
            image1Width.constant = CGFloat(slider.value) * view.frame.size.width * 0.25
            image1Height.constant = CGFloat(slider.value) * view.frame.size.height * 0.25
        }
        if clock  == 2 {

            image1Width2.constant = CGFloat(slider.value) * view.frame.size.width * 0.25
            image1Height2.constant = CGFloat(slider.value) * view.frame.size.height * 0.25
        }




    }

}
4

2 回答 2

0

您遇到的问题是因为您对两个视图都使用了一个转换,并且在您尝试移动它时连接了应用于另一个视图的新转换信息。

对您发布的代码进行这些更改...

在类级别,创建单独的变换“跟踪器”:

// don't use this
//var existingTransition : CGAffineTransform?

// separate transforms for each "move view"
var blueTransition: CGAffineTransform?
var greenTransition: CGAffineTransform?

然后,在g1Methodg2Method使用相关的变换:

@objc func g1Method(_ sender: UIPanGestureRecognizer){
    clock = 1
    let subview = greenMove
    guard let child = sender.view else{return}
    let transitionPoint = sender.translation(in: self.view)
    let newTransition = CGAffineTransform(translationX: transitionPoint.x, y: transitionPoint.y)

    // greenMove view must track its own CGAffineTransform

    switch sender.state {

    case .ended,.cancelled:// on End
        if let existing = greenTransition {
            greenTransition = newTransition.concatenating(existing)
        } else {
            greenTransition = newTransition
        }
        //if let existing = existingTransition{
        //  self.existingTransition = newTransition.concatenating(existing)
        //}else{
        //  self.existingTransition = newTransition
        //}
    default://on change and other states
        if let existing = greenTransition {
            child.transform = newTransition
                .concatenating(existing)
        } else {
            child.transform = newTransition
        }
        //if let existing = existingTransition{
        //  child.transform = newTransition
        //      .concatenating(existing)
        //}else{
        //  child.transform = newTransition
        //}
    }
    self.view.layoutIfNeeded()

    // move this to viewDidLoad(), otherwise you are adding ANOTHER recognizer each time this method is called
    //let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGestured(_:)))
    //subview.addGestureRecognizer(tapGesture)


}
@objc func g2Method(_ sender: UIPanGestureRecognizer){
    clock = 2
    let subview = blueMove
    guard let child = sender.view else{return}
    let transitionPoint = sender.translation(in: self.view)
    let newTransition = CGAffineTransform(translationX: transitionPoint.x, y: transitionPoint.y)

    // blueMove view must track its own CGAffineTransform

    switch sender.state {

    case .ended,.cancelled:// on End
        if let existing = blueTransition {
            blueTransition = newTransition.concatenating(existing)
        } else {
            blueTransition = newTransition
        }
        //if let existing = existingTransition{
        //  self.existingTransition = newTransition.concatenating(existing)
        //}else{
        //  self.existingTransition = newTransition
        //}
    default://on change and other states
        if let existing = blueTransition {
            child.transform = newTransition
                .concatenating(existing)
        } else {
            child.transform = newTransition
        }
        //if let existing = existingTransition{
        //  child.transform = newTransition
        //      .concatenating(existing)
        //}else{
        //  child.transform = newTransition
        //}
    }
    self.view.layoutIfNeeded()

    // move this to viewDidLoad(), otherwise you are adding ANOTHER recognizer each time this method is called
    //let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGestured(_:)))
    //subview.addGestureRecognizer(tapGesture)


}
于 2020-05-11T14:30:42.247 回答
0

最好的方法是在安全区域前导和图像前导之间而不是在两个图像之间为蓝光图像创建一个前导约束,因为当您禁用两个图像之间的约束时,您将遇到错误,因为视图不知道将图片

于 2020-05-09T09:27:06.270 回答