আমি কীভাবে ইউআইপিএজভিউ কনট্রোলারের সোয়াইপ অঙ্গভঙ্গি অক্ষম করব?


125

আমার ক্ষেত্রে পিতামাতার UIViewControllerমধ্যে UIPageViewControllerরয়েছে UINavigationControllerযা রয়েছে UIViewController। আমাকে শেষ দেখার নিয়ামকটিতে একটি সোয়াইপ অঙ্গভঙ্গি যুক্ত করতে হবে তবে সোয়াইপগুলি এমনভাবে পরিচালনা করা হয় যেন তারা পৃষ্ঠাগুলি নিয়ন্ত্রকের অন্তর্ভুক্ত। আমি প্রোগ্রামগতভাবে এবং এক্সিবের মাধ্যমে উভয়ই এটি করার চেষ্টা করেছি তবে কোনও ফলাফল হয়নি।

সুতরাং আমি যেমন বুঝতে পেরেছি আমি যতক্ষণ না UIPageViewControllerতার ইশারায় পরিচালনা করি ততক্ষণ আমি আমার লক্ষ্য অর্জন করতে পারি না । কিভাবে এই সমস্যা সমাধানের জন্য?


7
ব্যবহারpageViewControllerObject.view.userInteractionEnabled = NO;
শ্রীকান্ত

6
ভুল, কারণ এটি এর সমস্ত সামগ্রীকেও ব্লক করে। তবে আমার কেবল তার অঙ্গভঙ্গিগুলি ব্লক করতে হবে
ইউজার 2159978

তুমি কেন এটা করছ? অ্যাপ থেকে আপনি কী আচরণ চান? মনে হচ্ছে আপনি আর্কিটেকচারকে অতিরিক্ত জটিল করে তুলছেন। আপনি কী আচরণের জন্য লক্ষ্য করছেন তা ব্যাখ্যা করতে পারেন।
ফাগমিস্টার

এর একটি পৃষ্ঠায় UIPageViewControllerরয়েছে UINavigationController। গ্রাহক সোয়াইপ
ইশারায়

@ শ্রীকান্ত ধন্যবাদ, আমার প্রয়োজনটা ঠিক এটাই! আমার পৃষ্ঠার ভিউ ক্র্যাশ হচ্ছিল যখন আমি যখন কোনও পৃষ্ঠা পরিবর্তনকে অগ্রগতিতে ট্রিগার করতাম এবং কেউ এটিকে সোয়াইপ করে বাধা দেয়, তাই প্রতিবার পৃষ্ঠা পরিবর্তনের কোডে
ট্রিপিংয়ের

উত্তর:


262

UIPageViewControllerস্ক্রোলিং থেকে রোধ করার নথিযুক্ত উপায় হ'ল dataSourceসম্পত্তি বরাদ্দ করা নয় । আপনি যদি ডেটা উত্সটি বরাদ্দ করেন তবে এটি 'অঙ্গভঙ্গি-ভিত্তিক' নেভিগেশন মোডে চলে যাবে যা আপনি এড়াতে চাইছেন।

কোনও ডেটা উত্স ব্যতীত আপনি setViewControllers:direction:animated:completionপদ্ধতিটি করতে চাইলে ম্যানুয়ালি ভিউ কন্ট্রোলার সরবরাহ করেন এবং এটি চাহিদা অনুযায়ী ভিউ কন্ট্রোলারের মধ্যে চলে যাবে।

ইউআইপেজভিউ কনট্রোলারের অ্যাপল এর ডকুমেন্টেশন (ওভারভিউ, দ্বিতীয় অনুচ্ছেদ) থেকে উপরের অংশগুলি হ্রাস করা যেতে পারে :

অঙ্গভঙ্গি-ভিত্তিক নেভিগেশন সমর্থন করতে, আপনাকে অবশ্যই কোনও ডেটা উত্স অবজেক্ট ব্যবহার করে আপনার ভিউ কন্ট্রোলার সরবরাহ করতে হবে।


1
আমি এই সমাধানটিও পছন্দ করি। আপনি কোনও ভেরিয়েবলের মধ্যে পুরানো ডেটাসোর্সটি সঞ্চয় করতে পারেন, ডাটাসোর্সটি শূন্য করতে সেট করুন এবং তারপরে স্ক্রোলিংটিকে পুনরায় সক্ষম করতে পুরাতন ডেটাসোর্স পুনরুদ্ধার করতে পারেন। সমস্ত পরিষ্কার নয়, তবে স্ক্রোল ভিউটি খুঁজে পাওয়ার জন্য অন্তর্নিহিত ভিউ হায়ারার্কিকে অনুসরণ করার চেয়ে অনেক ভাল।
ম্যাট আর

3
পাঠ্য ক্ষেত্রের মতামতের জন্য কীবোর্ড বিজ্ঞপ্তিগুলির প্রতিক্রিয়া হিসাবে এমনটি করার সময় ডেটা উত্স অক্ষম করা সমস্যার কারণ হয়। ইউআইএসক্রোলভিউটি দেখার জন্য ভিউর সংক্ষিপ্তসারগুলি পর্যালোচনা করা আরও নির্ভরযোগ্য বলে মনে হয়।
এআর ইওনস

9
এটি কি পর্দার নীচে বিন্দুগুলি সরিয়ে দেয় না? এবং যদি আপনার কোনও সোয়াইপিং এবং বিন্দু না থাকে তবে পেজভিউ কনট্রোলারটি মোটেও ব্যবহার করার তেমন কোনও লাভ নেই। আমি অনুমান করছি যে প্রশ্নকর্তারা বিন্দুগুলি ধরে রাখতে চান।
লিও ফ্ল্যাহার্টি

পৃষ্ঠাগুলি যখন অবিচ্ছিন্নভাবে লোড করা হয় এবং ব্যবহারকারী একটি সোয়াইপ অঙ্গভঙ্গি করেন তখন আমি যে সমস্যার মুখোমুখি হয়েছি তা সমাধান করতে সহায়তা করেছে। ব্র্যাভো :)
জ্যাক

1
উ। আর ইওন সঠিক। আপনি যদি কোনও কীবোর্ড বিজ্ঞপ্তির প্রতিক্রিয়া হিসাবে পেজভিউ কনট্রোলারের ডেটাসোর্সটি অক্ষম করছেন (যেমন: আপনি কীবোর্ডটি চালু হওয়ার পরে ব্যবহারকারী অনুভূমিকভাবে স্ক্রোল করতে চান না) তবে আপনি পৃষ্ঠাভিউ কনট্রোলারের ডেটা উত্সটি সরিয়ে ফেললে আপনার কীবোর্ড তত্ক্ষণাত্ অদৃশ্য হয়ে যাবে।
micnguyen

82
for (UIScrollView *view in self.pageViewController.view.subviews) {

    if ([view isKindOfClass:[UIScrollView class]]) {

        view.scrollEnabled = NO;
    }
}

5
এটি একটি পৃষ্ঠা নিয়ন্ত্রণ রাখে, যা দুর্দান্ত।
মার্কাস অ্যাডামস

1
এটি পৃষ্ঠ নিয়ন্ত্রণ নিয়ন্ত্রণ (ছোট বিন্দু) রাখার কারণে এটি একটি দুর্দান্ত পদ্ধতি। পৃষ্ঠাটি ম্যানুয়ালি পরিবর্তন করার সময় আপনি সেগুলি আপডেট করতে চাইবেন। আমি এই স্ট্যাকওভারফ্লো.com
a/28356383/

1
কেন নেইfor (UIView *view in self.pageViewController.view.subviews) {
দেংআপ্রো

দয়া করে মনে রাখবেন যে ব্যবহারকারীরা পৃষ্ঠা নিয়ন্ত্রণটি বাম এবং ডান অর্ধে আলতো চাপ দিয়ে এখনও পৃষ্ঠাগুলির মধ্যে চলাচল করতে সক্ষম হবেন।
মাস্টারকারেল

57

আমি উত্তর অনুবাদ user2159978 করার সুইফট 5.1

func removeSwipeGesture(){
    for view in self.pageViewController!.view.subviews {
        if let subView = view as? UIScrollView {
            subView.isScrollEnabled = false
        }
    }
}

30

@ লি এর (@ ব্যবহারকারী 2159978 এর) সমাধানটি এক্সটেনশন হিসাবে কার্যকর করছে:

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

আরও মার্জিত পেতে, আপনি এটি যুক্ত করতে পারেন: var scrollView: UIScrollView? { for view in view.subviews { if let subView = view as? UIScrollView { return subView } } return nil }
ওয়াগনার বিক্রয়

এখানে প্রাপ্তি কেবল সর্বশেষ দর্শনটির সক্ষমিত স্থিতি ফিরিয়ে দেয়।
অ্যান্ড্রু ডানকান

8

আমি আপাতত এই জন্য লড়াই করছি এবং জেসেডেস্কের উত্তর অনুসরণ করে আমার সমাধান পোস্ট করা উচিত বলে ভেবেছিলাম; পেজভিউকন্ট্রোলারের ডেটা উত্স অপসারণ।

আমি আমার 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)
}

আমি আশা করি এটি কাউকে সাহায্য করবে, এটি আমার পছন্দ মতো পরিষ্কার নয় তবে খুব বেশি হ্যাক লাগছে না ইত্যাদি

সম্পাদনা: যদি কেউ এটির উদ্দেশ্য-সিতে অনুবাদ করতে চান তবে দয়া করে :)


8

সম্পাদনা করুন : এই উত্তরটি কেবল পৃষ্ঠা কার্ল শৈলীর জন্য কাজ করে। জেসেডেস্কের উত্তর আরও ভাল: শৈলী নির্বিশেষে কাজ করে এবং নথিভুক্ত আচরণের উপর নির্ভর করে ।

UIPageViewController এর অঙ্গভঙ্গি সনাক্তকারীদের অ্যারেটি প্রকাশ করে, যা আপনি তাদের অক্ষম করতে ব্যবহার করতে পারেন:

// myPageViewController is your UIPageViewController instance
for (UIGestureRecognizer *recognizer in myPageViewController.gestureRecognizers) {
    recognizer.enabled = NO;
}

8
আপনি কি আপনার কোড পরীক্ষা করেছেন? মাইপেজভিউকন্ট্রোলআলজিস্টেকার সনাক্তকারীরা সর্বদা শূন্য থাকে
ব্যবহারকারী 2159978

11
দেখে মনে হচ্ছে আপনার সমাধানটি পৃষ্ঠা কার্ল শৈলীর জন্য কাজ করে, তবে আমার অ্যাপ্লিকেশনটিতে আমি স্ক্রোল ভিউ শৈলী ব্যবহার করি
user2159978

8
অনুভূমিক স্ক্রোলিংয়ের জন্য কাজ করছে না। প্রত্যাবর্তিত মান সর্বদা একটি খালি অ্যারে হয়।
খানহ এনগুইন

আপনারা কি এগুলি স্ক্রোল শৈলীর জন্য বের করেছেন?
এসকারুথ

4

আপনি যদি চান UIPageViewControllerযে আপনার কন্টেন্ট নিয়ন্ত্রণগুলি তাদের বৈশিষ্ট্যগুলি (মুছতে সোয়াইপ ইত্যাদি) ব্যবহার করার অনুমতি দেওয়ার সময় এটির সোয়াইপ করার ক্ষমতা বজায় রাখতে চান তবে কেবলমাত্র বন্ধ canCancelContentTouchesকরুন UIPageViewController

আপনার এই রাখুন UIPageViewControllerএর viewDidLoadfunc। (SWIFT)

if let myView = view?.subviews.first as? UIScrollView {
    myView.canCancelContentTouches = false
}

UIPageViewControllerএকটি স্বয়ংক্রিয়ভাবে তৈরি subview যে অঙ্গভঙ্গি পরিচালনা হয়েছে। আমরা এই সংক্ষিপ্তসারগুলি সামগ্রীর অঙ্গভঙ্গি বাতিল করা থেকে বিরত রাখতে পারি।

থেকে ...

পৃষ্ঠার ভিউকন্ট্রোলারের ভিতরে থাকা টেবিলভিউতে মুছতে সোয়াইপ করুন


ধন্যবাদ কার্টার আমি আপনার সমাধান চেষ্টা করেছি। যাইহোক, এখনও বার পৃষ্ঠা ভিউকন্ট্রোলার চাইল্ড টেবিলের দৃশ্য থেকে দূরে অনুভূমিক সোয়াইপ ক্রিয়াটিকে অতিরিক্ত গ্রহণ করুন। আমি কীভাবে নিশ্চিত করতে পারি যে যখন ব্যবহারকারীরা শিশু টেবিল ভিউটিতে সোয়াইপ করে, টেবিল ভিউটি সর্বদা অঙ্গভঙ্গিটি পেতে অগ্রাধিকার দেওয়া হয়?
ডেভিড লিউ

3

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
            }
        }
    }
}

3

আমি এটি এর মতো সমাধান করেছি (সুইচ ৪.১)

if let scrollView = self.view.subviews.filter({$0.isKind(of: UIScrollView.self)}).first as? UIScrollView {
             scrollView.isScrollEnabled = false
}

3

@ উত্তর উত্তরের জন্য দ্রুত উপায়

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
    }
}

0

@ User3568340 উত্তরের মতো

সুইফট 4

private var _enabled = true
    public var enabled:Bool {
        set {
            if _enabled != newValue {
                _enabled = newValue
                if _enabled {
                    dataSource = self
                }
                else{
                    dataSource = nil
                }
            }
        }
        get {
            return _enabled
        }
    }

0

@ ইউজার 2159978 এর উত্তর ধন্যবাদ।

আমি এটিকে আরও কিছুটা বোধগম্য করে তুলি।

- (void)disableScroll{
    for (UIView *view in self.pageViewController.view.subviews) {
        if ([view isKindOfClass:[UIScrollView class]]) {
            UIScrollView * aView = (UIScrollView *)view;
            aView.scrollEnabled = NO;
        }
    }
}

0

আমি যে উত্তরগুলি পেয়েছি তা আমার কাছে খুব বিভ্রান্তিকর বা অসম্পূর্ণ বলে মনে হচ্ছে তাই এখানে একটি সম্পূর্ণ এবং কনফিগারযোগ্য সমাধান:

ধাপ 1:

আপনার প্রতিটি পিভিসি উপাদানকে বাম এবং ডান স্ক্রোলিং সক্ষম আছে কিনা তা জানানোর জন্য দায়িত্ব দিন।

protocol PageViewControllerElement: class {
    var isLeftScrollEnabled: Bool { get }
    var isRightScrollEnabled: Bool { get }
}
extension PageViewControllerElement {
    // scroll is enabled in both directions by default
    var isLeftScrollEnabled: Bool {
        get {
            return true
        }
    }

    var isRightScrollEnabled: Bool {
        get {
            return true
        }
    }
}

আপনার প্রতিটি পিভিসি ভিউ কন্ট্রোলারের উপরের প্রোটোকলটি প্রয়োগ করা উচিত।

ধাপ ২:

আপনার পিভিসি নিয়ন্ত্রকদের মধ্যে, প্রয়োজন হলে স্ক্রোলটি অক্ষম করুন:

extension SomeViewController: PageViewControllerElement {
    var isRightScrollEnabled: Bool {
        get {
            return false
        }
    }
}

class SomeViewController: UIViewController {
    // ...    
}

ধাপ 3:

আপনার পিভিসিতে কার্যকর স্ক্রোল লক পদ্ধতি যুক্ত করুন:

class PVC: UIPageViewController, UIPageViewDelegate {
    private var isLeftScrollEnabled = true
    private var isRightScrollEnabled = true
    // ...

    override func viewDidLoad() {
        super.viewDidLoad()
        // ...
        self.delegate = self
        self.scrollView?.delegate = self
    }
} 

extension PVC: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        print("contentOffset = \(scrollView.contentOffset.x)")

        if !self.isLeftScrollEnabled {
            disableLeftScroll(scrollView)
        }
        if !self.isRightScrollEnabled {
            disableRightScroll(scrollView)
        }
    }

    private func disableLeftScroll(_ scrollView: UIScrollView) {
        let screenWidth = UIScreen.main.bounds.width
        if scrollView.contentOffset.x < screenWidth {
            scrollView.setContentOffset(CGPoint(x: screenWidth, y: 0), animated: false)
        }
    }

    private func disableRightScroll(_ scrollView: UIScrollView) {
        let screenWidth = UIScreen.main.bounds.width
        if scrollView.contentOffset.x > screenWidth {
            scrollView.setContentOffset(CGPoint(x: screenWidth, y: 0), animated: false)
        }
    }
}

extension UIPageViewController {
    var scrollView: UIScrollView? {
        return view.subviews.filter { $0 is UIScrollView }.first as? UIScrollView
    }
}

পদক্ষেপ 4:

নতুন স্ক্রিনে পৌঁছানোর সময় স্ক্রোল সম্পর্কিত বৈশিষ্ট্যগুলি আপডেট করুন (আপনি যদি কিছু স্ক্রিনে ম্যানুয়ালি রূপান্তর করেন তবে সক্ষমস্ক্রোল পদ্ধতিটি কল করতে ভুলবেন না):

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    let pageContentViewController = pageViewController.viewControllers![0]
    // ...

    self.enableScroll(for: pageContentViewController)
}

private func enableScroll(for viewController: UIViewController) {
    guard let viewController = viewController as? PageViewControllerElement else {
        self.isLeftScrollEnabled = true
        self.isRightScrollEnabled = true
        return
    }

    self.isLeftScrollEnabled = viewController.isLeftScrollEnabled
    self.isRightScrollEnabled = viewController.isRightScrollEnabled

    if !self.isLeftScrollEnabled {
        print("Left Scroll Disabled")
    }
    if !self.isRightScrollEnabled {
        print("Right Scroll Disabled")
    }
}

0

একটা অনেক সহজ পদ্ধতির চেয়ে সবচেয়ে উত্তর এখানে পরামর্শ দিচ্ছি, ফিরে যাওয়ার জন্য যা এর nilমধ্যে viewControllerBeforeএবং viewControllerAfterডেটাউত্স callbacks।

এটি iOS 11+ ডিভাইসে স্ক্রোলিং অঙ্গভঙ্গিটি অক্ষম করে, ব্যবহার করার সম্ভাবনাটি বজায় রেখে dataSource( পৃষ্ঠার সূচকটির জন্য যেমন presentationIndex/ presentationCountব্যবহৃত জিনিসগুলির জন্য)

এটি মাধ্যমে নেভিগেশন অক্ষম করে। pageControl(নীচে বিন্দু)

extension MyPageViewController: UIPageViewControllerDataSource {
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        return nil
    }
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        return nil
    }
}


-1

সি # তে ইউজার 2159978 এর প্রতিক্রিয়া অনুবাদ করা হচ্ছে:

foreach (var view in pageViewController.View.Subviews){
   var subView = view as UIScrollView;
   if (subView != null){
     subView.ScrollEnabled = enabled;
   }
}

-1

(সুইফ্ট 4) আপনি আপনার পৃষ্ঠার ভিউকন্ট্রোলারের অঙ্গভঙ্গিগুলি সনাক্ত করতে পারেন:

pageViewController.view.gestureRecognizers?.forEach({ (gesture) in
            pageViewController.view.removeGestureRecognizer(gesture)
        })

আপনি যদি এক্সটেনশনে পছন্দ করেন:

extension UIViewController{
    func removeGestureRecognizers(){
        view.gestureRecognizers?.forEach({ (gesture) in
            view.removeGestureRecognizer(gesture)
        })
    }
}

এবং pageViewController.removeGestureRecognizers



-1

এ এর স্ক্রোলভিউ সন্ধানের জন্য সংক্ষিপ্তসারগুলি গণনা করা হচ্ছে UIPageViewController আমার পক্ষে কাজ করে না, কারণ আমি আমার পৃষ্ঠা নিয়ামক সাবক্লাসে কোনও স্ক্রোলভিও পাই না। সুতরাং আমি যা করার ভেবেছিলাম তা হল অঙ্গভঙ্গি সনাক্তকারীদের অক্ষম করা, তবে প্রয়োজনীয়গুলি অক্ষম না করার জন্য যথেষ্ট সতর্ক careful

সুতরাং আমি এটি নিয়ে এসেছি:

if let panGesture = self.gestureRecognizers.filter({$0.isKind(of: UIPanGestureRecognizer.self)}).first           
    panGesture.isEnabled = false        
}

এটি ভিতরে রাখুন viewDidLoad()এবং আপনি প্রস্তুত!


-1
 override func viewDidLayoutSubviews() {
    for View in self.view.subviews{
        if View.isKind(of: UIScrollView.self){
            let ScrollV = View as! UIScrollView
            ScrollV.isScrollEnabled = false
        }

    }
}

এটি আপনার পৃষ্ঠাভিউ নিয়ন্ত্রণকারী শ্রেণিতে যুক্ত করুন। 100% কাজ করছে


আপনি এই
কোডটির

-1

কেবলমাত্র আপনার ইউআইপেজভিউ কনট্রোলার সাবক্লাসে এই নিয়ন্ত্রণ সম্পত্তি যুক্ত করুন :

var isScrollEnabled = true {
    didSet {
        for case let scrollView as UIScrollView in view.subviews {
            scrollView.isScrollEnabled = isScrollEnabled
        }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.