如何在 panGesture 之后修复新的 textField 位置?
How to fix a new textField position after panGesture?
我需要一些帮助来解决我代码中的乱码问题。
我有一个视图,上面有两个 textField,另一个在底部,都在 imageView 之上。
我在两个文本字段中应用了平移手势,以允许在用户加载图像后更改它们的位置。
但是当我显示一个 activityView 来共享新图像时,textFields return 以前的位置。
我想在 panGesture 之后将它们修复到新位置。
我能做些什么?或者我忘了做什么?
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 方法...
@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 动作触发。最重要的是,与其担心是什么触发了约束被重新应用,不如确保您的视图保持在您希望的位置,即使发生这种情况也是如此。
一个解决方案是更新视图的 transform
而不是 center
,例如:
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
}
}
这项技术有效,但也感觉有点脆弱,它依赖于约束和视图转换之间记录不佳的行为。
另一种更稳健但稍微复杂一点的方法是调整约束 constant
属性。例如,您可以为约束本身创建 @IBOutlet
引用,在 IB 中连接这些插座,然后您的手势识别器可以相应地更新它们的 constant
属性:
@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
}
}
现在,很明显,如果您可能拖拽不同的视图,这可能会变得有点混乱,但希望以上说明了基本思想。
无论您应用哪种技术,基本概念都是避免更新 center
或 frame
其位置由自动布局约束决定的视图。
我需要一些帮助来解决我代码中的乱码问题。 我有一个视图,上面有两个 textField,另一个在底部,都在 imageView 之上。 我在两个文本字段中应用了平移手势,以允许在用户加载图像后更改它们的位置。 但是当我显示一个 activityView 来共享新图像时,textFields return 以前的位置。 我想在 panGesture 之后将它们修复到新位置。 我能做些什么?或者我忘了做什么?
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 方法...
@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 动作触发。最重要的是,与其担心是什么触发了约束被重新应用,不如确保您的视图保持在您希望的位置,即使发生这种情况也是如此。
一个解决方案是更新视图的 transform
而不是 center
,例如:
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
}
}
这项技术有效,但也感觉有点脆弱,它依赖于约束和视图转换之间记录不佳的行为。
另一种更稳健但稍微复杂一点的方法是调整约束 constant
属性。例如,您可以为约束本身创建 @IBOutlet
引用,在 IB 中连接这些插座,然后您的手势识别器可以相应地更新它们的 constant
属性:
@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
}
}
现在,很明显,如果您可能拖拽不同的视图,这可能会变得有点混乱,但希望以上说明了基本思想。
无论您应用哪种技术,基本概念都是避免更新 center
或 frame
其位置由自动布局约束决定的视图。