最近项目中接到一个需求,需要在如下图所示情况下为最右侧viewController
中的tableView
添加左滑删除效果
解决思路如下
- 禁用UIPageController的Bounces效果
- 处理手势冲突
禁用bounces效果
- 禁用
UIPageController
的bounces
效果,首先要遍历到UIScrollView
或其子类的子视图,并设置代理。代码如下:
for (UIView *view in self.pageViewController.view.subviews) {
if ([view isKindOfClass:[UIScrollView class]]) {
UIScrollView *scrollView = (UIScrollView *)view;
scrollView.allowSolveGestureConflict = YES;
scrollView.delegate = self;
break;
}
}
其内部滚动视图的类为UIQueuingScrollView
- 实现
UIScrollViewDelegate
部分协议,如下:
以下代码是解决拖拽时无回弹效果,但如果点击tab调用
setViewControllersdirection:animated:completion:
触发滚动会发生位置错位的效果,故声明_isDrag
属性来判断是否为拖拽出发的滚动
static BOOL _isDrag;
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
_isDrag = YES;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
_isDrag = NO;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (!_isDrag) return;
CGFloat lastPosition = scrollView.contentOffset.x;
//这里是对第一页和最后一页做一个判断,
if (self.currentIndex == self.pages.count-1 && (lastPosition > scrollView.getWidth)) {
[scrollView setContentOffset:CGPointMake(scrollView.getWidth, 0)];
} else if (self.currentIndex == 0 && lastPosition < scrollView.getWidth) {
[scrollView setContentOffset:CGPointMake(scrollView.getWidth, 0)];
}
}
解决手势冲突实现左滑删除
由于无法像解决UIScrollView
与UITableView
嵌套那样,写一个继承UIScrollView
的子类实现手势的代理方法即可。
所以需要为UIScrollView
添加category
,并实现如下方法:
//让scrollview可以与其子视图同时响应手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if (gestureRecognizer.state != 0) {
return YES;
}
return NO;
}
继而引发的问题
刚才为UIScrollView
添加了扩展,所以导致所有UIScrollView
子类都会处理手势冲突,所以需要在扩展中添加一个属性,如下:
//.h
@property (nonatomic, assign) BOOL allowSolveGestureConflict;
//.m
static char allowSolveGestureConflictKey;
- (void)setAllowSolveGestureConflict:(BOOL)allowSolveGestureConflict
{
objc_setAssociatedObject(self, &allowSolveGestureConflictKey, @(allowSolveGestureConflict), OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (BOOL)allowSolveGestureConflict
{
return [objc_getAssociatedObject(self, &allowSolveGestureConflictKey) boolValue];
}
//修改该方法如下
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if (self.allowSolveGestureConflict && gestureRecognizer.state != 0) {
return YES;
}
return NO;
}
我们在需要处理手势冲突的地方对该值设置为YES
即可
网友评论