私の場合、親UIViewController
にはUIPageViewController
が含まれていますUINavigationController
にはUIViewController
が含まれています。最後のView Controllerにスワイプジェスチャーを追加する必要がありますが、スワイプはPage View Controllerに属しているかのように処理されます。プログラムとxibの両方でこれを実行しようとしましたが、結果はありませんでした。
ですから、UIPageViewController
がジェスチャーを処理するまで、目標を達成できません。この問題を解決するには?
UIPageViewController
がスクロールしないようにする文書化された方法は、dataSource
プロパティを割り当てないことです。データソースを割り当てると、「ジェスチャベース」ナビゲーションモードに移行します。これは、防止しようとしているものです。
データソースがない場合、setViewControllers:direction:animated:completion
メソッドを使用する場合は手動でView Controllerを提供し、必要に応じてView Controller間を移動します。
上記は IPageViewControllerのAppleのドキュメント (概要、2番目の段落)から推測できます。
ジェスチャーベースのナビゲーションをサポートするには、データソースオブジェクトを使用してView Controllerを提供する必要があります。
for (UIScrollView *view in self.pageViewController.view.subviews) {
if ([view isKindOfClass:[UIScrollView class]]) {
view.scrollEnabled = NO;
}
}
ser2159978の答えを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
Edit:この回答はページカールスタイルにのみ有効です。 Jessedcの答え ははるかに優れています。スタイルに関係なく動作し、文書化された動作に依存します。
UIPageViewController
は、ジェスチャー認識機能の配列を公開します。これを使用して、それらを無効にすることができます。
// myPageViewController is your UIPageViewController instance
for (UIGestureRecognizer *recognizer in myPageViewController.gestureRecognizers) {
recognizer.enabled = NO;
}
私はしばらくの間これと戦ってきましたが、Jessedcの答えに続いて、自分の解決策を投稿すべきだと考えました。 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)
}
これが誰かの助けになることを願っています。それは私が望むほどきれいではありませんが、あまりにもハック感は感じません。
編集:誰かがこれを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
funcに入れます。 (迅速)
if let myView = view?.subviews.first as? UIScrollView {
myView.canCancelContentTouches = false
}
UIPageViewController
には、ジェスチャを処理する自動生成されたサブビューがあります。これらのサブビューがコンテンツジェスチャをキャンセルしないようにすることができます。
から...
このように解決しました(Swift 4.1)
if let scrollView = self.view.subviews.filter({$0.isKind(of: UIScrollView.self)}).first as? UIScrollView {
scrollView.isScrollEnabled = false
}
@ user3568340 answerに似ています
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の回答に感謝します。
わかりやすくします。
- (void)disableScroll{
for (UIView *view in self.pageViewController.view.subviews) {
if ([view isKindOfClass:[UIScrollView class]]) {
UIScrollView * aView = (UIScrollView *)view;
aView.scrollEnabled = NO;
}
}
}
@ lee answerの迅速な方法
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
}
}
(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
@ user2159978の応答をC#に翻訳する:
foreach (var view in pageViewController.View.Subviews){
var subView = view as UIScrollView;
if (subView != null){
subView.ScrollEnabled = enabled;
}
}