如何在 panGesture 之后修复新的 textField 位置? [英] How to fix a new textField position after panGesture?

查看:29
本文介绍了如何在 panGesture 之后修复新的 textField 位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一些帮助来解决我的代码中的垃圾问题.我有一个视图,上面有两个 textField,一个在顶部,另一个在底部,都在 imageView 上.我在两个文本字段中都应用了平移手势,以允许在用户加载图像后更改它们的位置.但是当我显示一个 activityView 来共享新图像时,textFields 返回以前的位置.我想在 panGesture 之后将它们修复到新位置.我能做什么?或者我忘了做什么?

I need some help with a litter issue in my code. I have a view with two textField one on the top and another on the bottom, both over a imageView. I applied a Pan Gesture in both textfields to allow change their position after the user load an image. But when I show a activityView to share the new image, the textFields return the previous location. I'd like to fix them in the new location after panGesture. What can I do? Or What am I forgetting to do?

   This is my Pan Gesture Action
@IBAction func didPanTfTop(_ sender: UIPanGestureRecognizer) {

    let translation = sender.translation(in: self.view)

    if sender.state == .began {
        print("Gesture began")
        textFieldOriginalCenter = tfTop.center
    } else if sender.state == .changed {
        print("Gesture is changed")
        tfTop.center = CGPoint(x: textFieldOriginalCenter.x + translation.x, y: textFieldOriginalCenter.y + translation.y)
    } else if sender.state == .ended {
        print("Gesture ended")

    }
}

这是我的activityView方法...

And this is my activityView methods...

@IBAction func share(_ sender: UIBarButtonItem) {
    Feedback.share.hapticFeedback()
    let memeImage = generateMemedImage()
    let activityView = UIActivityViewController(activityItems: [memeImage], applicationActivities: nil)
    activityView.completionWithItemsHandler = { (activityType: UIActivity.ActivityType?, completed: Bool, returnedItems: [Any]?, error: Error?) -> Void in

        if completed {
            self.save()
            print("Image has saved")
        }
    }
    present(activityView, animated: true, completion: nil)
}

推荐答案

一般来说,这种看到视图返回原始位置的行为是 (a) 使用自动布局约束的组合的结果;(b) 做一些触发重新应用约束的事情.这种重新应用约束的过程有时会被最无害的 UI 操作触发.最重要的是,与其担心是什么触发了重新应用的约束,最好确保您的视图保持在您想要的位置,即使在这种情况发生之后.

Generally, this behavior of seeing views snapping back to their original locations is a result of a combination of (a) using auto-layout constraints; and (b) doing something that triggers the constraints to be reapplied. This process of constraints being reapplied can sometimes be triggered by the most innocuous of UI action. Bottom line, rather than worrying about what triggered the constraints from being re-applied, it’s best to just make sure that your views will stay where you want them to, even after this happens.

一种解决方案是更新transform<视图的/a> 而不是 center,例如:

One solution is to update the transform of the views rather than the center, e.g.:

var originalTransform: CGAffineTransform!

@IBAction func handlePan(_ gesture: UIPanGestureRecognizer) {
    switch gesture.state {
    case .began:
        originalTransform = gesture.view!.transform

    case .changed, .ended:
        let translation = gesture.translation(in: gesture.view)
        gesture.view?.transform = originalTransform.translatedBy(x: translation.x, y: translation.y)

    default:
        break
    }
}

这种技术有效,但也感觉有点脆弱,这取决于约束和视图转换之间记录不佳的行为.

This technique works, but also feels a bit fragile, dependent upon poorly documented behavior between constraints and view transforms.

另一种更健壮但稍微复杂一点的方法是调整约束的 constant 属性.例如,您可以为约束本身创建 @IBOutlet 引用,在 IB 中连接这些插座,然后您的手势识别器可以相应地更新它们的 constant 属性:

Another, more robust, but a little more complicated, approach is to adjust the constraints’ constant property. For example, you can create @IBOutlet references for the constraints, themselves, hook up those outlets in IB, and then you gesture recognizer can update their constant properties accordingly:

@IBOutlet weak var horizontalConstraint: NSLayoutConstraint!
@IBOutlet weak var verticalConstraint: NSLayoutConstraint!

private var originalHorizontalConstant: CGFloat!
private var originalVerticalConstant: CGFloat!

@IBAction func handlePan(_ gesture: UIPanGestureRecognizer) {
    switch gesture.state {
    case .began:
        originalHorizontalConstant = horizontalConstraint.constant
        originalVerticalConstant = verticalConstraint.constant

    case .changed, .ended:
        let translation = gesture.translation(in: gesture.view)
        horizontalConstraint.constant = originalHorizontalConstant + translation.x
        verticalConstraint.constant = originalVerticalConstant + translation.y

    default:
        break
    }
}

现在,很明显,如果您可能会在此周围拖动不同的视图可能会变得有点混乱,但希望以上说明了基本思想.

Now, clearly if you’re potentially dragging different views around this can get a little messier, but hopefully the above illustrates the basic idea.

无论您应用哪种技术,基本概念都是避免更新位置由自动布局约束决定的视图的 centerframe.

Whichever technique you apply, the basic notion is to avoid updating center or frame of a view whose position is dictated by auto-layout constraints.

这篇关于如何在 panGesture 之后修复新的 textField 位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆