在我的情况下,父母UIViewController
包含UIPageViewController
,其中包含含有UINavigationController
的UIViewController
。我需要向最后一个视图控制器添加滑动手势,但滑动处理就像它们属于页面视图控制器一样。我尝试以编程方式和通过xib执行此操作,但没有结果。
据我所知,在UIPageViewController
处理其手势之前,我无法达到目标。如何解决这个问题?
记录的防止UIPageViewController
滚动的方法是不分配dataSource
属性。如果您分配数据源,它将进入“基于手势”的导航模式,这是您要阻止的。
如果没有数据源,您可以使用setViewControllers:direction:animated:completion
方法手动提供视图控制器,并且它将根据需要在视图控制器之间移动。
以上可以从Apple's documentation of UIPageViewController(概述,第二段)推断:
要支持基于手势的导航,必须使用数据源对象提供视图控制器。
类似于@ user3568340的答案
private var _enabled = true
public var enabled:Bool {
set {
if _enabled != newValue {
_enabled = newValue
if _enabled {
dataSource = self
}
else{
dataSource = nil
}
}
}
get {
return _enabled
}
}
翻译@ user2159978对C#的回复:
foreach (var view in pageViewController.View.Subviews){
var subView = view as UIScrollView;
if (subView != null){
subView.ScrollEnabled = enabled;
}
}
感谢@ user2159978的回答。
我让它更容易理解。
- (void)disableScroll{
for (UIView *view in self.pageViewController.view.subviews) {
if ([view isKindOfClass:[UIScrollView class]]) {
UIScrollView * aView = (UIScrollView *)view;
aView.scrollEnabled = NO;
}
}
}
(Swift 4)您可以删除pageViewController的gestureRecognizers:
pageViewController.view.gestureRecognizers?.forEach({ (gesture) in
pageViewController.view.removeGestureRecognizer(gesture)
})
如果您更喜欢扩展名:
extension UIViewController{
func removeGestureRecognizers(){
view.gestureRecognizers?.forEach({ (gesture) in
view.removeGestureRecognizer(gesture)
})
}
}
和pageViewController.removeGestureRecognizers
声明如下:
private var scrollView: UIScrollView? {
return pageViewController.view.subviews.compactMap { $0 as? UIScrollView }.first
}
然后像这样使用它:
scrollView?.isScrollEnabled = true //false
@lee答案的快捷方式
extension UIPageViewController {
var isPagingEnabled: Bool {
get {
return scrollView?.isScrollEnabled ?? false
}
set {
scrollView?.isScrollEnabled = newValue
}
}
var scrollView: UIScrollView? {
return view.subviews.first(where: { $0 is UIScrollView }) as? UIScrollView
}
}
for (UIScrollView *view in self.pageViewController.view.subviews) {
if ([view isKindOfClass:[UIScrollView class]]) {
view.scrollEnabled = NO;
}
}
我将user2159978的答案翻译成Swift
func removeSwipeGesture(){
for view in self.pageViewController!.view.subviews {
if let subView = view as? UIScrollView {
subView.scrollEnabled = false
}
}
}
实施@lee(@ user2159978)解决方案作为扩展:
extension UIPageViewController {
var isPagingEnabled: Bool {
get {
var isEnabled: Bool = true
for view in view.subviews {
if let subView = view as? UIScrollView {
isEnabled = subView.isScrollEnabled
}
}
return isEnabled
}
set {
for view in view.subviews {
if let subView = view as? UIScrollView {
subView.isScrollEnabled = newValue
}
}
}
}
}
用法:(在UIPageViewController
)
self.isPagingEnabled = false
编辑:此答案仅适用于页面卷曲样式。 Jessedc's answer要好得多:无论风格如何都有效,并且依赖于记录在案的行为。
UIPageViewController
公开了它的手势识别器数组,您可以使用它来禁用它们:
// myPageViewController is your UIPageViewController instance
for (UIGestureRecognizer *recognizer in myPageViewController.gestureRecognizers) {
recognizer.enabled = NO;
}
我已经打了一段时间了,我认为我应该发布我的解决方案,继耶塞德克的回答之后;删除PageViewController数据源。
我将它添加到我的PgeViewController类(链接到故事板中的页面视图控制器,继承UIPageViewController
和UIPageViewControllerDataSource
):
static func enable(enable: Bool){
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let pageViewController = appDelegate.window!.rootViewController as! PgeViewController
if (enable){
pageViewController.dataSource = pageViewController
}else{
pageViewController.dataSource = nil
}
}
然后可以在每个子视图出现时调用它(在这种情况下禁用它);
override func viewDidAppear(animated: Bool) {
PgeViewController.enable(false)
}
我希望这可以帮助别人,它不像我想的那样干净,但不会觉得太hacky等。
编辑:如果有人想将其翻译成Objective-C请做:)
UIPageViewController
的有用扩展,用于启用和禁用滑动。
extension UIPageViewController {
func enableSwipeGesture() {
for view in self.view.subviews {
if let subView = view as? UIScrollView {
subView.isScrollEnabled = true
}
}
}
func disableSwipeGesture() {
for view in self.view.subviews {
if let subView = view as? UIScrollView {
subView.isScrollEnabled = false
}
}
}
}
如果你想让你的UIPageViewController
保持它的滑动能力,同时允许你的内容控件使用他们的功能(滑动删除等),只需关闭canCancelContentTouches
中的UIPageViewController
。
把它放在你的UIPageViewController
的viewDidLoad
功能中。 (迅速)
if let myView = view?.subviews.first as? UIScrollView {
myView.canCancelContentTouches = false
}
UIPageViewController
有一个自动生成的子视图,用于处理手势。我们可以阻止这些子视图取消内容手势。
从...
Swipe to delete on a tableView that is inside a pageViewController
我解决了这个问题(Swift 4.1)
if let scrollView = self.view.subviews.filter({$0.isKind(of: UIScrollView.self)}).first as? UIScrollView {
scrollView.isScrollEnabled = false
}