12

我知道标题有点混乱,所以我会尽力解释清楚。我有一个固定宽度为 100 的 UIView 和一个从 0 开始的可变高度。我想要做的是将我的手指从 UIView 的底部拖到屏幕顶部,然后将 UIView改变它的高度/延伸到我手指的位置。如果这仍然很复杂,只需将其想象为从某物下方拉出的一条纸条。

如果你能帮上忙,那就太好了。我觉得应该不会太难,但我只是初学者,如果我没有解释清楚,我可以理解!

4

3 回答 3

15

这应该是直截了当的UIPanGestureRecognizer一点点数学。要将视图更改为正确的框架(我使用的是 name _viewToChange,因此稍后将其替换为您的视图),只需添加:

UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
pan.maximumNumberOfTouches = pan.minimumNumberOfTouches = 1;
[self addGestureRecognizer:pan];

到您init的超级视图方法,并定义方法:

- (void)pan:(UIPanGestureRecognizer *)aPan; {
  CGPoint currentPoint = [aPan locationInView:self];

  [UIView animateWithDuration:0.01f
                   animations:^{
                     CGRect oldFrame = _viewToChange.frame;
                     _viewToChange.frame = CGRectMake(oldFrame.origin.x, currentPoint.y, oldFrame.size.width, ([UIScreen mainScreen].bounds.size.height - currentPoint.y));
                   }];
}

当用户手指移动时,这应该会为视图设置动画。希望有帮助!

于 2013-08-25T08:28:39.043 回答
10

使用 UIPanGestureRecognizer 的 Swift 版本

使用从 Storyboard 添加到 UIView 的 PanGesture 并将委托设置为 self。UIView 附加到屏幕底部。

class ViewController: UIViewController {
var translation: CGPoint!
var startPosition: CGPoint! //Start position for the gesture transition
var originalHeight: CGFloat = 0 // Initial Height for the UIView
var difference: CGFloat!

override func viewDidLoad() {
    super.viewDidLoad()
    originalHeight = dragView.frame.height
}

@IBOutlet weak var dragView: UIView! // UIView with UIPanGestureRecognizer

@IBOutlet var gestureRecognizer: UIPanGestureRecognizer!

@IBAction func viewDidDragged(_ sender: UIPanGestureRecognizer) {

    if sender.state == .began {
        startPosition = gestureRecognizer.location(in: dragView) // the postion at which PanGestue Started
    }

    if sender.state == .began || sender.state == .changed {
        translation = sender.translation(in: self.view)
        sender.setTranslation(CGPoint(x: 0.0, y: 0.0), in: self.view)
        let endPosition = sender.location(in: dragView) // the posiion at which PanGesture Ended
        difference = endPosition.y - startPosition.y
        var newFrame = dragView.frame
        newFrame.origin.x = dragView.frame.origin.x
        newFrame.origin.y = dragView.frame.origin.y + difference //Gesture Moving Upward will produce a negative value for difference
        newFrame.size.width = dragView.frame.size.width
        newFrame.size.height = dragView.frame.size.height - difference //Gesture Moving Upward will produce a negative value for difference
        dragView.frame = newFrame
    }

    if sender.state == .ended || sender.state == .cancelled {
        //Do Something
    }
  }
}
于 2018-03-27T17:58:49.290 回答
4

这是我使用自动布局和要调整大小的视图的高度约束的快速解决方案,同时根据安全区域设置上限和下限

private var startPosition: CGPoint!
private var originalHeight: CGFloat = 0

override func viewDidLoad() {
    super.viewDidLoad()

    let panGesture = UIPanGestureRecognizer(target: self, action: #selector(viewDidDrag(_:)))
    resizableView.addGestureRecognizer(panGesture)
}

@objc private func viewDidDrag(_ sender: UIPanGestureRecognizer) {
    if sender.state == .began  {
        startPosition = sender.location(in: self.view)
        originalHeight = detailsContainerViewHeight.constant
    }

    if sender.state == .changed {
        let endPosition = sender.location(in: self.view)
        let difference = endPosition.y - startPosition.y
        var newHeight = originalHeight - difference

        if view.bounds.height - newHeight < topSafeArea + backButtonSafeArea {
            newHeight = view.bounds.height - topSafeArea - backButtonSafeArea
        } else if newHeight < routeDetailsHeaderView.bounds.height + bottomSafeArea {
            newHeight = routeDetailsHeaderView.bounds.height
        }

        resizableView.constant = newHeight
    }

    if sender.state == .ended || sender.state == .cancelled {
        //Do Something if interested when dragging ended.
    }
}
于 2018-07-30T06:35:36.740 回答