UITextView scrolling without triggering UIPageViewControllerDataSource in UIPageViewController's view controllers

huangapple go评论77阅读模式
英文:

UITextView scrolling without triggering UIPageViewControllerDataSource in UIPageViewController's view controllers

问题

我有多个视图控制器。类似这样:

ViewControllerA
ViewControllerB
ViewControllerC

我将它们用作我的UIPageViewController的视图控制器(作为页面)。

它们每个都包含可滚动的UITextViews。我不能禁用滚动,因为文本长度应该是灵活的。

当我滚动文本视图时,UIPageViewControllerDataSource的viewControllerBefore或viewControllerAfter也会被触发。如何防止这种情况发生?

我可以禁用UIPageViewController的垂直手势以防止冲突吗?或者还有其他方法可以阻止它们同时起作用吗?我只想在水平手势上更改页面,并在垂直手势上滚动文本视图。但我不知道该如何做。我应该怎么做?

英文:

I have multiple view controllers. Something like this:

ViewControllerA
ViewControllerB
ViewControllerC

I use these as my UIPageViewController's view controllers, (as pages).

Each one of them has scrollable UITextViews inside. I cannot disable scrolling because text length should be flexible.

When I scroll the textview, UIPageViewControllerDataSource's viewControllerBefore or viewControllerAfter also is being triggered. How can I prevent this?

Can I disable vertical gestures for UIPageViewController and prevent clashes? Or is there some other way to stop them working at the same time? I want to change page only on horizontal gesture, and scroll the text view only on vertical gesture. But I don't know how to do it. What should I do?

答案1

得分: 0

感谢 @DonMag 和 @BulatYakupov 尝试帮助我并警告我提供的信息不足。我在代码共享方面有一些限制。今天我找到了另一种方法。但首先,这是我的屏幕外观:

UITextView scrolling without triggering UIPageViewControllerDataSource in UIPageViewController's view controllers

我滑动以翻页并卷曲页面。

当我滚动文本时,它也会触发viewControllerBeforeviewControllerAfter。它没有改变页面,但它会触发我的视图控制器创建函数。这个函数跟踪数组上的当前索引,以提供数据以创建视图控制器。

代码如下:

class myCustomVC: UIViewController {
    let textView = UITextView()
}

class PageVCDataService {
    var array = ["John", "Josh", "Joe", "Harvy"]
    // 跟踪当前索引以为每个页面提供正确的文本
    var currentIndex = 0

    func createAfterPage() -> UIViewController {
        currentIndex += 1
        return createVC(page: array[currentIndex])
    }
    
    func createBeforePage() -> UIViewController {
        currentIndex -= 1
        return createVC(page: array[currentIndex])
    }

    func createVC(page: String) -> UIViewController {
        let vc = myCustomVC()
        vc.textView.text = page
        return vc
    }
}

class PageVC: UIPageViewController {
    let dataService = PageVCDataService()
    // ...一些代码
}

extension PageVC: UIPageViewControllerDataSource {
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        return dataService.createBeforePage()
    }
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        return dataService.createAfterPage()
    }
}

它没有更改页面,但它更改了索引。例如,如果我滚动文本,如果我的当前索引是10(第11页),那么我的当前索引会更改为9。当我滑动到下一页时,下一页仍然是相同的页面,因为索引从9变为10,这与一开始的索引相同。

因此,我实现了UITextViewDelegate并使用了scrollViewDidScroll方法。每当文本视图滚动时,它会向我的数据服务类发送通知,告诉它检查屏幕上的文本和当前索引上的文本是否相同。如果不同,我的函数会找到屏幕上的文本的索引并更正当前索引。

这是一个不太优雅的解决方案,但也许它可以帮助其他人。

英文:

Edit: Thank you @DonMag and @BulatYakupov for trying to help me and warning me about the given information is not enough. I had some restriction on code sharing. Today I found another way. But first here how my screen looks :

UITextView scrolling without triggering UIPageViewControllerDataSource in UIPageViewController's view controllers

I was swiping to turn the page with page curl.

When I scroll the text, it was also triggering viewControllerBefore or viewControllerAfter. It wasn't changing the page, but It was triggering my view controller creating function. This function keep track of current index on an array to supply data to vc creation.

It is something like this:

class myCustomVC: UIViewController {
    let textView = UITextView()
}

class PageVCDataService {
    var array = ["John","Josh","Joe","Harvy"]
    //keeping track of the current index for suppling correct text from array for every page
    var currentIndex = 0

    func createAfterPage() -> UIViewController {
        currentIndex += 1
        return createVC(page :array[currentIndex])
    }
    
    func createBeforePage() -> UIViewController {
        currentIndex -= 1
        return createVC(page :array[currentIndex])
    }

    func createVC(page : String) ->UIViewController {
        let vc = myCustomVC()
        vc.textView.text = page
        return vc
    }
}

class PageVC : UIPageViewController {
    let dataService = PageVCDataService()
    // ...some code
}
extension PageVC: UIPageViewControllerDataSource {
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        return dataService.createBeforePage()
    }
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        return dataService.createAfterPage()
    }
}

It wasn't changing the page but it was changing the index. For example if I scroll the text and if my current index at 10 (page 11), my current index was changing to 9. When I swipe for next page, next page was the same page because index was going 9 to 10, which is the same index at the beginning.

So i implemented UITextViewDelegate and used scrollViewDidScroll method. Every time text view scrolls, it send a notification to my data service class, tell it to check if the text on the screen and the text at the current index is same. If it's not, my function find the index for the text on the screen and corrects current index.

It is an ugly solution but maybe it can help someone else.

huangapple
  • 本文由 发表于 2023年2月10日 05:33:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75404632.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定