UIPageViewController中的UIButton交互

时间:2011-11-07 13:59:00

标签: iphone objective-c xcode uipageviewcontroller

我在我的应用程序中使用了UIPageViewController,我想在其中有一些UIButtons,有点像菜单。我遇到的问题是,当我在屏幕边缘附近放置UIButton(或任何其他交互元素)并点击它时,而不是应用UIButton操作,会发生什么变化,页面会发生变化(因为边缘点击屏幕更改UIPageViewController上的页面)。我想知道是否有办法使UIButton具有比UIPageViewController更高的优先级,这样当我点击按钮时,它会应用相应的操作而不是更改页面。

8 个答案:

答案 0 :(得分:7)

我带着同样的问题来到这里。斯普利特的link有答案。

让您的根视图控制器成为每个UIPageViewController手势识别器的代理,然后防止触摸在任何UIControl内发生时传递:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    return ([touch.view isKindOfClass:[UIControl class]] == NO);
}

答案 1 :(得分:4)

UIPageViewController有两个UIGestureRecognizer。您可以通过gestureRecognizers属性访问它们。确定哪一个是UITapGestureRecognizer,然后使用this.希望这会有所帮助。

答案 2 :(得分:2)

对于那些只想复制/粘贴代码的人来说,这是我的:

// I don't want the tap on borders to change the page
-(void) desactivatePageChangerGesture {
     for (UIGestureRecognizer* gestureRecognizer in self.pageViewController.gestureRecognizers) {
        if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
            gestureRecognizer.enabled = NO;
        }
    }
}

在创建UIPageViewController之后调用此函数。

答案 3 :(得分:1)

从您的代码中注释掉这一行

self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;

或使用Split命中的UIGestureRecognizer

希望这会对你有所帮助

答案 4 :(得分:1)

我遇到了同样的问题,并且不确定如何处理UIGestureRecognizer委托方法。这个简短的例子假设你在Xcode 4中使用了“基于页面的应用程序”项目类型。这就是我所做的:

  • RootViewController.h中,我确保宣布RootViewController将处理UIGestureRecognizerDelegate协议:

    @interface RootViewController : UIViewController <UIPageViewControllerDelegate, UIGestureRecognizerDelegate>
    
  • RootViewController.m中,我将RootViewController指定为UITapGestureRecognizer的委托。这是在viewDidLoad方法结束时完成的。我通过迭代每个gestureRecognizer来查看哪个是UITapGestureRecognizer。

    NSEnumerator *gestureLoop = [self.view.gestureRecognizers objectEnumerator];
    id gestureRecognizer;
    while (gestureRecognizer = [gestureLoop nextObject]) {
        if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
            [(UITapGestureRecognizer *)gestureRecognizer setDelegate:self];
        }
    }
    
  • 最后,我将gestureRecognizer:shouldReceiveTouch方法添加到RootViewController.m的底部(这是直接从Split的链接中复制的):

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
        if ([touch.view isKindOfClass:[UIControl class]]) {
            // we touched a button, slider, or other UIControl
            return NO; // ignore the touch
        }
        return YES; // handle the touch
    }
    

答案 5 :(得分:0)

OLD ANSWER:如果您的UIPageViewController transitionStyle UIPageViewControllerTransitionStyleScroll且您使用的是iOS 6.0以上,那么您无法使用gestureRecognizer:shouldReceiveTouch:方法,因为self无法将委托设置为gestureRecognizers,因为pageViewController.gestureRecognizers将返回nil。有关详细信息,请参阅UIPageViewController returns no Gesture Recognizers in iOS 6

如果您只想确保UIPageViewController按钮触摸事件到UIButton,您可以使用

for (UIScrollView *view in _pageViewController.view.subviews) {
    if ([view isKindOfClass:[UIScrollView class]]) {
        view.delaysContentTouches = NO;
    }
}

如果你有transitionStyle UIPageViewControllerTransitionStyleScroll并且你使用的是iOS 6.0 +。

请参阅this answer,了解delaysContentTouches = NO

UIButton的某些案例需要UIScrollView的原因

更新经过多一点研究后,如果您的问题是UIButton点击似乎只被称为有时,那么实际上可能是UIScrollView内所需的行为。 UIScrollView使用delaysContentTouches属性自动确定用户是否正在尝试滚动或尝试按滚动视图内的按钮。我认为最好不要将此行为更改为默认为NO,因为这样做会导致无法滚动,如果用户的手指在按钮上。

答案 6 :(得分:0)

这里没有你拦截UIPageViewController的轻敲手势识别器的解决方案对我有用。我的目标是iOS 8和9。

在我的自定义按钮(touchesBegan的子类)中覆盖函数touchesCancelledtouchesMovedtouchesEndedUIControl是有效的。然后,如果触摸开始并在我的自定义按钮的框架内结束,我只需手动发送.TouchUpInside控制事件。

我不需要为包含页面视图控制器或包含页面视图控制器的视图控制器做任何特殊操作。

答案 7 :(得分:0)

在这里迅速回答5个问题。

pageViewController.view.subviews.compactMap({ $0 as? UIScrollView }).first?.delaysContentTouches = false