gpt4 book ai didi

ios - 拖动 UIView

转载 作者:行者123 更新时间:2023-11-29 00:07:37 30 4
gpt4 key购买 nike

我需要一些帮助来拖动 UIView 以显示主视图下方的菜单 View 。

我有两个 UIViewmenuView - 包括菜单按钮和标签 和 mainView - 位于 menuView 之上。

我想从左边缘拖动主视图以显示菜单项并将主视图对齐到特定位置。我可以向右拖动,但向左拖动时无法将其设置回原始位置。

这是我一直在尝试但没有成功的代码。我还想在将 mainView 向右拖动时使其变小。任何帮助将不胜感激。

注意:PanGesture 附加到 mainView

@IBAction func dragMenu(_ sender: UIPanGestureRecognizer) {
let mview = sender.view!
let originalCenter = CGPoint(x: self.mainView.bounds.width/2, y: self.mainView.bounds.height/2)
switch sender.state {

case .changed:
if let mview = sender.view {
mview.center.x = mview.center.x + sender.translation(in: view).x
sender.setTranslation(CGPoint.zero, in: view)
}

case .ended:


let DraggedHalfWayRight = mview.center.x > view.center.x
if DraggedHalfWayRight {
//dragginToRight

showMenu = !showMenu
self.mainViewRight.constant = 200
self.mainTop.constant = 50
self.mainBottom.constant = 50
self.mainLeft.constant = 200

} else //dragging left and set it back to original position.
{
mview.center = originalCenter
showMenu = !showMenu
}



default:
break
}
}

最佳答案

我会提出一些建议:

  1. 拖完菜单后,确保将其 alpha 设置为零(这样,如果您在纵向模式下转到横向模式,您不会突然看那里的菜单)。

  2. 我个人只是调整拖动 View 的 transform 并避免一直将手势的平移重置为零。这是个人喜好问题。

  3. 我会让 View Controller 成为手势的委托(delegate)并实现 gestureRecognizerShouldBegin(因为如果菜单被隐藏,您不想识别滑动以尝试再次隐藏它; 如果它没有隐藏,你不想识别滑动来显示它)。

  4. 在确定是否完成手势时,我还会考虑手势的速度(例如,轻弹一下就会关闭/显示动画 View )。

因此:

class ViewController: UIViewController {

@IBOutlet weak var menuView: UIView!

var isMenuVisible = true

@IBAction func dragMenu(_ gesture: UIPanGestureRecognizer) {
let translationX = gesture.translation(in: gesture.view!).x

switch gesture.state {
case .began:
// if the menu is not visible, make sure it's off screen and then make it visible

if !isMenuVisible {
menuView.transform = CGAffineTransform(translationX: gesture.view!.bounds.width, y: 0)
menuView.alpha = 1
}
fallthrough

case .changed:
if isMenuVisible {
menuView.transform = CGAffineTransform(translationX: translationX, y: 0)
} else {
menuView.transform = CGAffineTransform(translationX: gesture.view!.bounds.width + translationX, y: 0)
}

case .ended:
let shouldComplete: Bool
if isMenuVisible {
shouldComplete = translationX > gesture.view!.bounds.width / 2 || gesture.velocity(in: gesture.view!).x > 0
} else {
shouldComplete = -translationX > gesture.view!.bounds.width / 2 || gesture.velocity(in: gesture.view!).x < 0
}

UIView.animate(withDuration: 0.25, animations: {
if self.isMenuVisible && shouldComplete || !self.isMenuVisible && !shouldComplete {
self.menuView.transform = CGAffineTransform(translationX: gesture.view!.bounds.width, y: 0)
} else {
self.menuView.transform = .identity
}

if shouldComplete{
self.isMenuVisible = !self.isMenuVisible
}
}, completion: { _ in
self.menuView.alpha = self.isMenuVisible ? 1 : 0
})

default:
break
}
}

}

extension ViewController: UIGestureRecognizerDelegate {

func gestureRecognizerShouldBegin(_ gesture: UIGestureRecognizer) -> Bool {
guard let gesture = gesture as? UIPanGestureRecognizer else { return true }

let translationX = gesture.translation(in: gesture.view!).x

return isMenuVisible && translationX > 0 || !isMenuVisible && translationX < 0
}

}

就个人而言,我更喜欢使用单独的屏幕边缘手势识别器将菜单拉回到屏幕上(你真的不希望它识别任何地方的手势,但只是在右边缘)。这种方法的另一个优点是通过在不同的函数中保留“显示”和“隐藏”,代码可读性更高(恕我直言):

class ViewController: UIViewController {

@IBOutlet weak var menuView: UIView!

var isMenuVisible = true

@IBAction func handleScreenEdgeGesture(_ gesture: UIScreenEdgePanGestureRecognizer) {
let translationX = gesture.translation(in: gesture.view!).x

switch gesture.state {
case .began:
menuView.transform = CGAffineTransform(translationX: gesture.view!.bounds.width, y: 0)
menuView.alpha = 1
fallthrough

case .changed:
menuView.transform = CGAffineTransform(translationX: gesture.view!.bounds.width + translationX, y: 0)

case .ended:
let shouldComplete = -translationX > gesture.view!.bounds.width / 2 || gesture.velocity(in: gesture.view!).x < 0

UIView.animate(withDuration: 0.25, delay:0, options: .curveEaseOut, animations: {
if shouldComplete {
self.menuView.transform = .identity
self.isMenuVisible = !self.isMenuVisible
} else {
self.menuView.transform = CGAffineTransform(translationX: gesture.view!.bounds.width, y: 0)
}
}, completion: { _ in
self.menuView.alpha = self.isMenuVisible ? 1 : 0
})

default:
break
}
}

@IBAction func dragMenu(_ gesture: UIPanGestureRecognizer) {
let translationX = gesture.translation(in: gesture.view!).x

switch gesture.state {
case .began, .changed:
menuView.transform = CGAffineTransform(translationX: translationX, y: 0)

case .ended:
let shouldComplete = translationX > gesture.view!.bounds.width / 2 || gesture.velocity(in: gesture.view!).x > 0

UIView.animate(withDuration: 0.25, delay:0, options: .curveEaseOut, animations: {
if shouldComplete {
self.menuView.transform = CGAffineTransform(translationX: gesture.view!.bounds.width, y: 0)
self.isMenuVisible = !self.isMenuVisible
} else {
self.menuView.transform = .identity
}
}, completion: { _ in
self.menuView.alpha = self.isMenuVisible ? 1 : 0
})

default:
break
}
}

}

extension ViewController: UIGestureRecognizerDelegate {

func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer is UIScreenEdgePanGestureRecognizer {
return !isMenuVisible
} else if let gesture = gestureRecognizer as? UIPanGestureRecognizer {
let translationX = gesture.translation(in: gesture.view!).x
return isMenuVisible && translationX > 0
}

return true
}

}

关于ios - 拖动 UIView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47581303/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com