Деактивировать ограничения между двумя объектами, связывающими их вместе - PullRequest
0 голосов
/ 09 мая 2020

Мой быстрый код, как вы можете видеть на гифке ниже. Позволяет пользователю выбрать одно из представлений изображения, а затем использовать ползунок для увеличения или уменьшения размера этого представления изображения. Проблема в том, что когда изображение перемещается, другое изображение следует за ним, чего не должно происходить. Таким образом, ограничения должны быть установлены при первом запуске кода, но после выбора одного из представлений изображения. Ограничения, связывающие их вместе, должны быть деактивированы. Строка, вызывающая это:

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

enter image description here

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
        }




    }

}

Ответы [ 2 ]

0 голосов
/ 11 мая 2020

Проблема, с которой вы столкнулись, заключается в том, что вы используете одно преобразование для обоих представлений и объединяете новую информацию преобразования, которая применяется к другому представлению, когда вы пытаетесь его переместить.

Внесите эти изменения в свой опубликованный код ...

На уровне класса создайте отдельные «трекеры» преобразования:

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

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

Затем в g1Method и g2Method используйте связанное преобразование:

@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)


}
0 голосов
/ 09 мая 2020

Лучший способ - создать ведущее ограничение для изображения blu между ведущим интервалом безопасной области и ведущим изображением между двумя изображениями, потому что, когда вы отключите ограничение между двумя изображениями, вы получите ошибку, потому что представление не знает куда положить изображение

...