GestureRecognizer 开始时如何以编程方式关闭 clipsToBounds 属性?

Posted

技术标签:

【中文标题】GestureRecognizer 开始时如何以编程方式关闭 clipsToBounds 属性?【英文标题】:How to dismiss programmatically the clipsToBounds property when a GestureRecognizer begin? 【发布时间】:2016-06-03 09:26:04 【问题描述】:

我有一个UIScrollView,它可以包含许多视图。为了允许良好的滚动(滚动时内容不会超出视图),在我的 Main.sotryboard 上,我点击了我的 UIScrollView ,然后在属性检查器中我允许了 Clip Subviews 属性:

我的问题: 我的UIScrollViews 中的所有视图都是可拖动的(因为它们都有一个UIPanGestureRecognizer。 因此,当我尝试将它们拖到我的UIScrollView 之外时,它们就会消失。 事实上,他们只是落后于其他所有观点

举个例子,我还有其他组件允许从先例UIScrollView 中删除视图。因此,当我开始从它拖放时,它会消失,然后重新出现在我放置视图的第二个组件中。

我的尝试:我有一个特殊的UIPanGestureRecognizer 用于拖放来自此UIScrollView 的视图。所以,我实际上有这个(显然,它不起作用,否则我不会在这里):

//Here recognizer is the `UIPanGestureRecognizer`
//selectpostit is the name of the view I want to drag
if(recognizer.state == UIGestureRecognizerStateBegan)
    selectpostit.clipsToBounds = NO;

关于如何改进它的任何想法? 提前致谢。

【问题讨论】:

应为父视图将 clipsToBounds 设置为 NO。在您的案例滚动视图中。 不要在要拖动的视图上更改clipsToBounds,而是在scrollView 上更改它。拖动视图时对我有用的另一个选项是创建和控制视图的图像快照,然后隐藏原始视图。完成拖动后,在必要时重新定位 哦,这看起来真的很棒!谢谢。但是现在,当我的 Scrollview 中有很多视图时,它们会在我拖动时出现(当拖动完成时我做了相反的操作,所以 clipToBounds = yes if(recognizer.state == UIGestureRecognizerStateEnded)。你有解决方案?@Surya Subenthiran 如果我拍摄滚动视图的快照,它是否应该解决我在下面提到的问题? @cjay 您拖动的视图的快照,而不是滚动。但是,我认为您可以同时攻击它。您也可以尝试调用正确的布局函数(setNeedsDisplay 等...)以在手势结束时重绘滚动视图 【参考方案1】:

您可以尝试在每次手势开始时将 scrollView.clipsToBounds 重置为 NO,但这会导致在拖动过程中滚动视图之外的其他内容变得可见时产生副作用。

我建议在平移开始时拍摄可拖动视图的快照,将其放在滚动视图的父级上,然后移动它。这种方法应该可以解决您的问题。

代码如下:

- (void)onPanGesture:(UIPanGestureRecognizer*)panRecognizer

    if(panRecognizer.state == UIGestureRecognizerStateBegan)
    
        //when gesture recognizer starts, making snapshot of the draggableView and hiding it
        //will move shapshot that's placed on the parent of the scroll view
        //that helps to prevent cutting by the scroll view bounds
        self.draggableViewSnapshot = [self.draggableView snapshotViewAfterScreenUpdates: NO];
        self.draggableView.hidden = YES;
        [self.scrollView.superview addSubview: self.draggableViewSnapshot];
    

    //your code that updates position of the draggable view

    //updating snapshot center, by converting coordinates from draggable view
    CGPoint snapshotCenter = [self.draggableView.superview convertPoint:self.draggableView.center toView: self.scrollView.superview];
    self.draggableViewSnapshot.center = snapshotCenter;

    if(panRecognizer.state == UIGestureRecognizerStateEnded ||
       panRecognizer.state == UIGestureRecognizerStateCancelled ||
       panRecognizer.state == UIGestureRecognizerStateFailed)
    
        //when gesture is over, cleaning up the snapshot
        //and showing draggable view back
        [self.draggableViewSnapshot removeFromSuperview];
        self.draggableViewSnapshot = nil;
        self.draggableView.hidden = NO;
    

【讨论】:

如何拍摄我的滚动视图的快照?顺便说一句,这个答案看起来真的很好 您不需要创建滚动视图的快照,每个可拖动项目一旦移动就会创建快照【参考方案2】:

我建议你看看 ray wenderlich Moving Table View Cells with a Long Press Gesture 的这篇文章

它解释了如何创建快照

【讨论】:

非常感谢,我会看看,但你应该在这个答案作为评论不?这实际上不是我最初的问题。

以上是关于GestureRecognizer 开始时如何以编程方式关闭 clipsToBounds 属性?的主要内容,如果未能解决你的问题,请参考以下文章

使用gestureRecognizer时两个手势识别器之间的顺序:shouldRecognizeSimultaneouslyWithGestureRecognizer:

从 Interface Builder 连接时,GestureRecognizer 操作未触发

GestureRecognizer:在 SIGABRT 中的地图结果上放置图钉

用Swift GestureRecognizer 的几个注意点

您可以将相同类型的 GestureRecognizer 添加到一个视图中吗?

使用 Nginx + uWSGI 部署 Flask 应用