swift 在文本字段中输入文本导致uipangesture对象移回其原始位置

46scxncf  于 2023-01-01  发布在  Swift
关注(0)|答案(3)|浏览(96)

我下面的swift代码有一个连接到pangesture的图像视图。当移动图像视图后,在文本域中输入内容时。图像视图会恢复到原来的位置。gif表示正在发生的事情。我只是不希望文本输入到文本域后pangesutre的效果无效。


链接到吉思堡https://github.com/redrock34/sse

import UIKit

class ViewController: UIViewController {

    var pic = UIImageView()
    let fight = (0..<10).map { _ in UIImageView() }
    var textEnter = UITextField()
    var g2 = UIPanGestureRecognizer()

    var slider = UISlider()

    override func viewDidLoad() {
        super.viewDidLoad()

        fight[0].image  = UIImage(named: "a.png")

        fight.forEach{
            $0.isUserInteractionEnabled = true
        }
        [slider,textEnter].forEach{
            $0.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview($0)

            $0.backgroundColor = .blue
        }

        slider.backgroundColor = .clear

        g2 = UIPanGestureRecognizer(target: self, action: #selector(ViewController.g1Method))
        fight[0].addGestureRecognizer(g2)

        pic.backgroundColor = .clear
        pic.backgroundColor = .systemGreen

        fight.forEach{
            $0.backgroundColor = .clear
            view.addSubview($0)
            $0.translatesAutoresizingMaskIntoConstraints = false
        }            

        [pic].forEach{

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

        // Do any additional setup after loading the view.
        NSLayoutConstraint.activate ([

            pic.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant :0),
            pic.topAnchor.constraint(equalTo: fight[0].bottomAnchor, constant : 0),

            pic.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.62, constant: 0),
            pic.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant : 0),

            textEnter.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant :0),
            textEnter.topAnchor.constraint(equalTo: view.topAnchor, constant : 0),
            textEnter.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.1, constant: 0),
            textEnter.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant : 0),

            fight[0].trailingAnchor.constraint(equalTo: view.trailingAnchor, constant :0),
            fight[0].topAnchor.constraint(equalTo: textEnter.bottomAnchor, constant : 0),

            fight[0].heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.10, constant: 0),
            fight[0].widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.10, constant: 0),
            fight[0].leadingAnchor.constraint(equalTo: view.leadingAnchor, constant : 0),

            slider.topAnchor.constraint(equalTo: pic.bottomAnchor, constant : 0),

            slider.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.08, constant: 0),
            slider.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1, constant: 0),
            slider.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant : 0),

        ])
        textEnter.textAlignment = .center

        self.view.sendSubviewToBack(pic)
    }

    @objc func g1Method(_ sender: UIPanGestureRecognizer){

        let tranistioon = sender.translation(in: self.view)
        sender.view!.center = CGPoint(x: sender.view!.center.x + tranistioon.x, y: sender.view!.center.y + tranistioon.y)
        sender.setTranslation(CGPoint.zero,in: self.view)    }
}
v6ylcynt

v6ylcynt1#

尝试创建一个UIImageVIew类并编写以下代码:

import UIKit

class draggableImage:UIImageView {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.layer.borderWidth = 1
        self.layer.borderColor = UIColor.red.cgColor
        self.isUserInteractionEnabled = true
    }


    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first;
        let location = touch?.location(in: self.superview);
        if(location != nil)
        {
        self.frame.origin = CGPoint(x: location!.x-self.frame.size.width/2, y: location!.y-self.frame.size.height/2);
        }
    }

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

    }

}

不要忘记从属性菜单中将类draggableImage分配给Image View。

5lhxktic

5lhxktic2#

对于同一对象,不能将显式框架设置与自动布局约束混合使用。
例如,如果您:

  • 将标签添加到主视图
  • 设置label.translatesAutoresizingMaskIntoConstraints = false
  • 设置标签的约束

然后通过密码。

  • 更改标签的.center属性

您将看到标签移动,但下次UI更新时(编辑文本字段、点击按钮、旋转设备等),自动布局将根据标签的约束条件重置标签的框架。
因此,在平移手势处理程序中,您可以更新fight[0]对象的.constant值(而不是更改其.center),或者...
可以为fight对象保留label.translatesAutoresizingMaskIntoConstraints = true,并显式设置其框架和中心。
注意:在任何一种情况下,您都不***希望***约束任何其他相对于fight对象的元素,否则它们将随着您移动fight[0]而移动。
这是对ViewController类(来自GitHub zip)的一个修改,实现了在fight对象上使用自动布局约束的 * not * 方法。

class ViewController: UIViewController {

    var pic = UIImageView()
    let fight = (0..<10).map { _ in UIImageView() }
    var textEnter = UITextField()
    var g2 = UIPanGestureRecognizer()

    var slider = UISlider()

    override func viewDidLoad() {
        super.viewDidLoad()

        fight[0].image  = UIImage(named: "a.png")

        fight.forEach{
            $0.isUserInteractionEnabled = true
        }
        [slider,textEnter].forEach{
            $0.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview($0)
            $0.backgroundColor = .blue
        }

        slider.backgroundColor = .clear

        g2 = UIPanGestureRecognizer(target: self, action: #selector(ViewController.g1Method))
        fight[0].addGestureRecognizer(g2)

        pic.backgroundColor = .systemGreen

        fight.forEach{
            $0.backgroundColor = .clear
            view.addSubview($0)
            // do NOT use auto-layout for fight views
            //$0.translatesAutoresizingMaskIntoConstraints = false
        }

        [pic].forEach{
            view.addSubview($0)
            $0.translatesAutoresizingMaskIntoConstraints = false
        }

        // need a non-rendering "spacer" to vertically separate textEnter from Pic
        let spacer = UILayoutGuide()
        view.addLayoutGuide(spacer)

        // NOTE: do NOT constrain any elements relative to fight views

        NSLayoutConstraint.activate ([

            // constrain textEnter top / leading / trailing to view
            textEnter.topAnchor.constraint(equalTo: view.topAnchor, constant : 0),
            textEnter.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant : 0),
            textEnter.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant :0),
            // constrain textEnter height to 0.1 * view height
            textEnter.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.1, constant: 0),

            // constrain spacer top to bottom of textEnter
            spacer.topAnchor.constraint(equalTo: textEnter.bottomAnchor, constant: 0.0),
            // constrain spacer leading to view leading
            spacer.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0),
            // constrain spacer height to 0.1 * view height
            spacer.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.10),
            // spacer width doesn't matter
            spacer.widthAnchor.constraint(equalToConstant: 1.0),

            // constrain pic Top to spacer bottom
            pic.topAnchor.constraint(equalTo: spacer.bottomAnchor, constant: 0.0),
            // constrain pic leading / trailing to view
            pic.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant : 0),
            pic.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant :0),

            // constrain pic height as you had it
            pic.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.62, constant: 0),

            // slider constraints
            slider.topAnchor.constraint(equalTo: pic.bottomAnchor, constant : 0),
            slider.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.08, constant: 0),
            slider.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1, constant: 0),
            slider.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant : 0),

        ])

        textEnter.textAlignment = .center

        self.view.sendSubviewToBack(pic)

    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        // set fight[0] frame *after* textEnter has been laid-out
        fight[0].frame.size = CGSize(width: view.frame.width * 0.10, height: view.frame.height * 0.10)
        let x = view.frame.origin.x
        let y = textEnter.frame.origin.y + textEnter.frame.size.height
        fight[0].frame.origin = CGPoint(x: x, y: y)
    }

    @objc func g1Method(_ sender: UIPanGestureRecognizer){

        let tranistioon = sender.translation(in: self.view)
        sender.view!.center = CGPoint(x: sender.view!.center.x + tranistioon.x, y: sender.view!.center.y + tranistioon.y)
        sender.setTranslation(CGPoint.zero,in: self.view)

    }

}
fdbelqdn

fdbelqdn3#

请改用此方法

var existingTransition : CGAffineTransform?
    @objc func g1Method(_ sender: UIPanGestureRecognizer){
        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()
    }

对不起,如果我的代码是混乱的。但我检查了一些scenaios它的工作正常。
快乐编码

相关问题