Reliably track Page Index in a UIPageViewController (Swift)












2















The problem:



I have a master UIPageViewController (MainPageVC) with three imbedded page views (A, B, & C) that are accessible both with swipe gestures and by pressing the appropriate locations in a custom page indicator* in the MainPageVC (*not a true UIPageControl but comprised of three ToggleButtons - a simple reimplementation of UIButton to become a toggle-button). My setup is as follows:



Schematic of my view hierarchy



Previous reading:
Reliable way to track Page Index in a UIPageViewController - Swift, A reliable way to get UIPageViewController current index, and UIPageViewController: return the current visible view
indicated that the best way to do this was with didFinishAnimating calls, and manually keep track of the current page index, but I'm finding that this does not deal with certain edge cases.



I have been trying to produce a safe way of keeping track of the current page index (with didFinishAnimating and willTransitionTo methods) but am having trouble with the edge case where a user is in view A, and then swipes all the way across to C (without lifting up their finger), and then beyond C, and then releasing their finger... in this instance didFinishAnimating isn't called and the app still believes it is in A (i.e. A toggle button is still pressed and pageIndex is not updated correctly by the viewControllerBefore and viewControllerAfter methods).



My code:



@IBOutlet weak var pagerView: UIView!
@IBOutlet weak var aButton: ToggleButton!
@IBOutlet weak var bButton: ToggleButton!
@IBOutlet weak var cButton: ToggleButton!

let viewControllerNames = ["aVC", "bVC", "cVC"]
lazy var buttonsArray = {
[aButton, bButton, cButton]
}()
var previousPage = "aVC"

var pageVC: UIPageViewController?

func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
print("TESTING - will transition to")

let currentViewControllerClass = String(describing: pageViewController.viewControllers![0].classForCoder);
let viewControllerIndex = viewControllerNames.index(of: currentViewControllerClass);

if currentViewControllerClass == previousPage {
return
}

let pastIndex = viewControllerNames.index(of: previousPage)
if buttonsArray[pastIndex!]?.isOn == true {
buttonsArray[pastIndex!]?.buttonPressed()
}

if let newPageButton = buttonsArray[viewControllerIndex!] {
newPageButton.buttonPressed()
}

self.previousPage = currentViewControllerClass
}

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
print("TESTING - did finish animating")

let currentViewControllerClass = String(describing: pageViewController.viewControllers![0].classForCoder)
let viewControllerIndex = viewControllerNames.index(of: currentViewControllerClass)

if currentViewControllerClass == previousPage {
return
}

let pastIndex = viewControllerNames.index(of: previousPage)
if buttonsArray[pastIndex!]?.isOn == true {
buttonsArray[pastIndex!]?.buttonPressed()
}

if let newPageButton = buttonsArray[viewControllerIndex!] {
newPageButton.buttonPressed()
}

self.previousPage = currentViewControllerClass
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let onboardingViewControllerClass = String(describing: viewController.classForCoder)
let viewControllerIndex = viewControllerNames.index(of: onboardingViewControllerClass)
let newViewControllerIndex = viewControllerIndex! - 1
if(newViewControllerIndex < 0) {
return nil
} else {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: viewControllerNames[newViewControllerIndex])
if let vc = vc as? BaseTabVC {
vc.mainPageVC = self
vc.intendedCollectionViewHeight = pagerViewHeight
}
return vc
}
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let onboardingViewControllerClass = String(describing: viewController.classForCoder)
let viewControllerIndex = viewControllerNames.index(of: onboardingViewControllerClass)
let newViewControllerIndex = viewControllerIndex! + 1
if(newViewControllerIndex > viewControllerNames.count - 1) {
return nil
} else {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: viewControllerNames[newViewControllerIndex])
if let vc = vc as? BaseTabVC {
vc.mainPageVC = self
vc.intendedCollectionViewHeight = pagerViewHeight
}
return vc
}
}


I'm at a loss as to how to deal with this edge case, the problem is that it can lead to fatal crashes of the app if the user then tries to press something in C that should otherwise be guaranteed to exist, and an unexpected nil or indexOutOfBounds error is thrown.










share|improve this question





























    2















    The problem:



    I have a master UIPageViewController (MainPageVC) with three imbedded page views (A, B, & C) that are accessible both with swipe gestures and by pressing the appropriate locations in a custom page indicator* in the MainPageVC (*not a true UIPageControl but comprised of three ToggleButtons - a simple reimplementation of UIButton to become a toggle-button). My setup is as follows:



    Schematic of my view hierarchy



    Previous reading:
    Reliable way to track Page Index in a UIPageViewController - Swift, A reliable way to get UIPageViewController current index, and UIPageViewController: return the current visible view
    indicated that the best way to do this was with didFinishAnimating calls, and manually keep track of the current page index, but I'm finding that this does not deal with certain edge cases.



    I have been trying to produce a safe way of keeping track of the current page index (with didFinishAnimating and willTransitionTo methods) but am having trouble with the edge case where a user is in view A, and then swipes all the way across to C (without lifting up their finger), and then beyond C, and then releasing their finger... in this instance didFinishAnimating isn't called and the app still believes it is in A (i.e. A toggle button is still pressed and pageIndex is not updated correctly by the viewControllerBefore and viewControllerAfter methods).



    My code:



    @IBOutlet weak var pagerView: UIView!
    @IBOutlet weak var aButton: ToggleButton!
    @IBOutlet weak var bButton: ToggleButton!
    @IBOutlet weak var cButton: ToggleButton!

    let viewControllerNames = ["aVC", "bVC", "cVC"]
    lazy var buttonsArray = {
    [aButton, bButton, cButton]
    }()
    var previousPage = "aVC"

    var pageVC: UIPageViewController?

    func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
    print("TESTING - will transition to")

    let currentViewControllerClass = String(describing: pageViewController.viewControllers![0].classForCoder);
    let viewControllerIndex = viewControllerNames.index(of: currentViewControllerClass);

    if currentViewControllerClass == previousPage {
    return
    }

    let pastIndex = viewControllerNames.index(of: previousPage)
    if buttonsArray[pastIndex!]?.isOn == true {
    buttonsArray[pastIndex!]?.buttonPressed()
    }

    if let newPageButton = buttonsArray[viewControllerIndex!] {
    newPageButton.buttonPressed()
    }

    self.previousPage = currentViewControllerClass
    }

    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    print("TESTING - did finish animating")

    let currentViewControllerClass = String(describing: pageViewController.viewControllers![0].classForCoder)
    let viewControllerIndex = viewControllerNames.index(of: currentViewControllerClass)

    if currentViewControllerClass == previousPage {
    return
    }

    let pastIndex = viewControllerNames.index(of: previousPage)
    if buttonsArray[pastIndex!]?.isOn == true {
    buttonsArray[pastIndex!]?.buttonPressed()
    }

    if let newPageButton = buttonsArray[viewControllerIndex!] {
    newPageButton.buttonPressed()
    }

    self.previousPage = currentViewControllerClass
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
    let onboardingViewControllerClass = String(describing: viewController.classForCoder)
    let viewControllerIndex = viewControllerNames.index(of: onboardingViewControllerClass)
    let newViewControllerIndex = viewControllerIndex! - 1
    if(newViewControllerIndex < 0) {
    return nil
    } else {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewController(withIdentifier: viewControllerNames[newViewControllerIndex])
    if let vc = vc as? BaseTabVC {
    vc.mainPageVC = self
    vc.intendedCollectionViewHeight = pagerViewHeight
    }
    return vc
    }
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
    let onboardingViewControllerClass = String(describing: viewController.classForCoder)
    let viewControllerIndex = viewControllerNames.index(of: onboardingViewControllerClass)
    let newViewControllerIndex = viewControllerIndex! + 1
    if(newViewControllerIndex > viewControllerNames.count - 1) {
    return nil
    } else {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewController(withIdentifier: viewControllerNames[newViewControllerIndex])
    if let vc = vc as? BaseTabVC {
    vc.mainPageVC = self
    vc.intendedCollectionViewHeight = pagerViewHeight
    }
    return vc
    }
    }


    I'm at a loss as to how to deal with this edge case, the problem is that it can lead to fatal crashes of the app if the user then tries to press something in C that should otherwise be guaranteed to exist, and an unexpected nil or indexOutOfBounds error is thrown.










    share|improve this question



























      2












      2








      2








      The problem:



      I have a master UIPageViewController (MainPageVC) with three imbedded page views (A, B, & C) that are accessible both with swipe gestures and by pressing the appropriate locations in a custom page indicator* in the MainPageVC (*not a true UIPageControl but comprised of three ToggleButtons - a simple reimplementation of UIButton to become a toggle-button). My setup is as follows:



      Schematic of my view hierarchy



      Previous reading:
      Reliable way to track Page Index in a UIPageViewController - Swift, A reliable way to get UIPageViewController current index, and UIPageViewController: return the current visible view
      indicated that the best way to do this was with didFinishAnimating calls, and manually keep track of the current page index, but I'm finding that this does not deal with certain edge cases.



      I have been trying to produce a safe way of keeping track of the current page index (with didFinishAnimating and willTransitionTo methods) but am having trouble with the edge case where a user is in view A, and then swipes all the way across to C (without lifting up their finger), and then beyond C, and then releasing their finger... in this instance didFinishAnimating isn't called and the app still believes it is in A (i.e. A toggle button is still pressed and pageIndex is not updated correctly by the viewControllerBefore and viewControllerAfter methods).



      My code:



      @IBOutlet weak var pagerView: UIView!
      @IBOutlet weak var aButton: ToggleButton!
      @IBOutlet weak var bButton: ToggleButton!
      @IBOutlet weak var cButton: ToggleButton!

      let viewControllerNames = ["aVC", "bVC", "cVC"]
      lazy var buttonsArray = {
      [aButton, bButton, cButton]
      }()
      var previousPage = "aVC"

      var pageVC: UIPageViewController?

      func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
      print("TESTING - will transition to")

      let currentViewControllerClass = String(describing: pageViewController.viewControllers![0].classForCoder);
      let viewControllerIndex = viewControllerNames.index(of: currentViewControllerClass);

      if currentViewControllerClass == previousPage {
      return
      }

      let pastIndex = viewControllerNames.index(of: previousPage)
      if buttonsArray[pastIndex!]?.isOn == true {
      buttonsArray[pastIndex!]?.buttonPressed()
      }

      if let newPageButton = buttonsArray[viewControllerIndex!] {
      newPageButton.buttonPressed()
      }

      self.previousPage = currentViewControllerClass
      }

      func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
      print("TESTING - did finish animating")

      let currentViewControllerClass = String(describing: pageViewController.viewControllers![0].classForCoder)
      let viewControllerIndex = viewControllerNames.index(of: currentViewControllerClass)

      if currentViewControllerClass == previousPage {
      return
      }

      let pastIndex = viewControllerNames.index(of: previousPage)
      if buttonsArray[pastIndex!]?.isOn == true {
      buttonsArray[pastIndex!]?.buttonPressed()
      }

      if let newPageButton = buttonsArray[viewControllerIndex!] {
      newPageButton.buttonPressed()
      }

      self.previousPage = currentViewControllerClass
      }

      func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
      let onboardingViewControllerClass = String(describing: viewController.classForCoder)
      let viewControllerIndex = viewControllerNames.index(of: onboardingViewControllerClass)
      let newViewControllerIndex = viewControllerIndex! - 1
      if(newViewControllerIndex < 0) {
      return nil
      } else {
      let storyboard = UIStoryboard(name: "Main", bundle: nil)
      let vc = storyboard.instantiateViewController(withIdentifier: viewControllerNames[newViewControllerIndex])
      if let vc = vc as? BaseTabVC {
      vc.mainPageVC = self
      vc.intendedCollectionViewHeight = pagerViewHeight
      }
      return vc
      }
      }

      func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
      let onboardingViewControllerClass = String(describing: viewController.classForCoder)
      let viewControllerIndex = viewControllerNames.index(of: onboardingViewControllerClass)
      let newViewControllerIndex = viewControllerIndex! + 1
      if(newViewControllerIndex > viewControllerNames.count - 1) {
      return nil
      } else {
      let storyboard = UIStoryboard(name: "Main", bundle: nil)
      let vc = storyboard.instantiateViewController(withIdentifier: viewControllerNames[newViewControllerIndex])
      if let vc = vc as? BaseTabVC {
      vc.mainPageVC = self
      vc.intendedCollectionViewHeight = pagerViewHeight
      }
      return vc
      }
      }


      I'm at a loss as to how to deal with this edge case, the problem is that it can lead to fatal crashes of the app if the user then tries to press something in C that should otherwise be guaranteed to exist, and an unexpected nil or indexOutOfBounds error is thrown.










      share|improve this question
















      The problem:



      I have a master UIPageViewController (MainPageVC) with three imbedded page views (A, B, & C) that are accessible both with swipe gestures and by pressing the appropriate locations in a custom page indicator* in the MainPageVC (*not a true UIPageControl but comprised of three ToggleButtons - a simple reimplementation of UIButton to become a toggle-button). My setup is as follows:



      Schematic of my view hierarchy



      Previous reading:
      Reliable way to track Page Index in a UIPageViewController - Swift, A reliable way to get UIPageViewController current index, and UIPageViewController: return the current visible view
      indicated that the best way to do this was with didFinishAnimating calls, and manually keep track of the current page index, but I'm finding that this does not deal with certain edge cases.



      I have been trying to produce a safe way of keeping track of the current page index (with didFinishAnimating and willTransitionTo methods) but am having trouble with the edge case where a user is in view A, and then swipes all the way across to C (without lifting up their finger), and then beyond C, and then releasing their finger... in this instance didFinishAnimating isn't called and the app still believes it is in A (i.e. A toggle button is still pressed and pageIndex is not updated correctly by the viewControllerBefore and viewControllerAfter methods).



      My code:



      @IBOutlet weak var pagerView: UIView!
      @IBOutlet weak var aButton: ToggleButton!
      @IBOutlet weak var bButton: ToggleButton!
      @IBOutlet weak var cButton: ToggleButton!

      let viewControllerNames = ["aVC", "bVC", "cVC"]
      lazy var buttonsArray = {
      [aButton, bButton, cButton]
      }()
      var previousPage = "aVC"

      var pageVC: UIPageViewController?

      func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
      print("TESTING - will transition to")

      let currentViewControllerClass = String(describing: pageViewController.viewControllers![0].classForCoder);
      let viewControllerIndex = viewControllerNames.index(of: currentViewControllerClass);

      if currentViewControllerClass == previousPage {
      return
      }

      let pastIndex = viewControllerNames.index(of: previousPage)
      if buttonsArray[pastIndex!]?.isOn == true {
      buttonsArray[pastIndex!]?.buttonPressed()
      }

      if let newPageButton = buttonsArray[viewControllerIndex!] {
      newPageButton.buttonPressed()
      }

      self.previousPage = currentViewControllerClass
      }

      func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
      print("TESTING - did finish animating")

      let currentViewControllerClass = String(describing: pageViewController.viewControllers![0].classForCoder)
      let viewControllerIndex = viewControllerNames.index(of: currentViewControllerClass)

      if currentViewControllerClass == previousPage {
      return
      }

      let pastIndex = viewControllerNames.index(of: previousPage)
      if buttonsArray[pastIndex!]?.isOn == true {
      buttonsArray[pastIndex!]?.buttonPressed()
      }

      if let newPageButton = buttonsArray[viewControllerIndex!] {
      newPageButton.buttonPressed()
      }

      self.previousPage = currentViewControllerClass
      }

      func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
      let onboardingViewControllerClass = String(describing: viewController.classForCoder)
      let viewControllerIndex = viewControllerNames.index(of: onboardingViewControllerClass)
      let newViewControllerIndex = viewControllerIndex! - 1
      if(newViewControllerIndex < 0) {
      return nil
      } else {
      let storyboard = UIStoryboard(name: "Main", bundle: nil)
      let vc = storyboard.instantiateViewController(withIdentifier: viewControllerNames[newViewControllerIndex])
      if let vc = vc as? BaseTabVC {
      vc.mainPageVC = self
      vc.intendedCollectionViewHeight = pagerViewHeight
      }
      return vc
      }
      }

      func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
      let onboardingViewControllerClass = String(describing: viewController.classForCoder)
      let viewControllerIndex = viewControllerNames.index(of: onboardingViewControllerClass)
      let newViewControllerIndex = viewControllerIndex! + 1
      if(newViewControllerIndex > viewControllerNames.count - 1) {
      return nil
      } else {
      let storyboard = UIStoryboard(name: "Main", bundle: nil)
      let vc = storyboard.instantiateViewController(withIdentifier: viewControllerNames[newViewControllerIndex])
      if let vc = vc as? BaseTabVC {
      vc.mainPageVC = self
      vc.intendedCollectionViewHeight = pagerViewHeight
      }
      return vc
      }
      }


      I'm at a loss as to how to deal with this edge case, the problem is that it can lead to fatal crashes of the app if the user then tries to press something in C that should otherwise be guaranteed to exist, and an unexpected nil or indexOutOfBounds error is thrown.







      ios swift uipageviewcontroller uipagecontrol






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 23 '18 at 14:18







      zb1995

















      asked Nov 23 '18 at 12:37









      zb1995zb1995

      2610




      2610
























          1 Answer
          1






          active

          oldest

          votes


















          1














          Very well written question. Especially for a newbie. (Voted.) You clearly state the problem you're having, including illustrations and your current code.



          The solution I proposed in another thread was to subclass UIPageControl and have it implement a didSet on its currentPage property. You can then have the page control notify the view controller of the current page index. (By giving your custom subclass a delegate property, by sending a notification center message, or whatever method best fits your needs.)



          (I did a simple test of this approach and it worked. I didn't test exhaustively however.)



          The fact that the UIPageViewController reliably updates the page control but that there's no reliable, obvious way to figure out the current page index seems like an oversight in the design of this class.






          share|improve this answer
























          • Thanks for your suggestion, I shall give that a go and get back to you. I started going down the rabbit hole of trying to prevent "overscroll" of the views inside a UIPageViewController but was getting nowhere. It was probably my inexperience / not quite wording my searches correctly as I was constantly pointed towards UIScrollView's bounce property (which wasn't relevant). Do you think that attempting to disable swiping gestures to the left (on the rightmost page) and vice versa would also adequately eliminate this edge case?

            – zb1995
            Nov 23 '18 at 14:12











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53446854%2freliably-track-page-index-in-a-uipageviewcontroller-swift%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          Very well written question. Especially for a newbie. (Voted.) You clearly state the problem you're having, including illustrations and your current code.



          The solution I proposed in another thread was to subclass UIPageControl and have it implement a didSet on its currentPage property. You can then have the page control notify the view controller of the current page index. (By giving your custom subclass a delegate property, by sending a notification center message, or whatever method best fits your needs.)



          (I did a simple test of this approach and it worked. I didn't test exhaustively however.)



          The fact that the UIPageViewController reliably updates the page control but that there's no reliable, obvious way to figure out the current page index seems like an oversight in the design of this class.






          share|improve this answer
























          • Thanks for your suggestion, I shall give that a go and get back to you. I started going down the rabbit hole of trying to prevent "overscroll" of the views inside a UIPageViewController but was getting nowhere. It was probably my inexperience / not quite wording my searches correctly as I was constantly pointed towards UIScrollView's bounce property (which wasn't relevant). Do you think that attempting to disable swiping gestures to the left (on the rightmost page) and vice versa would also adequately eliminate this edge case?

            – zb1995
            Nov 23 '18 at 14:12
















          1














          Very well written question. Especially for a newbie. (Voted.) You clearly state the problem you're having, including illustrations and your current code.



          The solution I proposed in another thread was to subclass UIPageControl and have it implement a didSet on its currentPage property. You can then have the page control notify the view controller of the current page index. (By giving your custom subclass a delegate property, by sending a notification center message, or whatever method best fits your needs.)



          (I did a simple test of this approach and it worked. I didn't test exhaustively however.)



          The fact that the UIPageViewController reliably updates the page control but that there's no reliable, obvious way to figure out the current page index seems like an oversight in the design of this class.






          share|improve this answer
























          • Thanks for your suggestion, I shall give that a go and get back to you. I started going down the rabbit hole of trying to prevent "overscroll" of the views inside a UIPageViewController but was getting nowhere. It was probably my inexperience / not quite wording my searches correctly as I was constantly pointed towards UIScrollView's bounce property (which wasn't relevant). Do you think that attempting to disable swiping gestures to the left (on the rightmost page) and vice versa would also adequately eliminate this edge case?

            – zb1995
            Nov 23 '18 at 14:12














          1












          1








          1







          Very well written question. Especially for a newbie. (Voted.) You clearly state the problem you're having, including illustrations and your current code.



          The solution I proposed in another thread was to subclass UIPageControl and have it implement a didSet on its currentPage property. You can then have the page control notify the view controller of the current page index. (By giving your custom subclass a delegate property, by sending a notification center message, or whatever method best fits your needs.)



          (I did a simple test of this approach and it worked. I didn't test exhaustively however.)



          The fact that the UIPageViewController reliably updates the page control but that there's no reliable, obvious way to figure out the current page index seems like an oversight in the design of this class.






          share|improve this answer













          Very well written question. Especially for a newbie. (Voted.) You clearly state the problem you're having, including illustrations and your current code.



          The solution I proposed in another thread was to subclass UIPageControl and have it implement a didSet on its currentPage property. You can then have the page control notify the view controller of the current page index. (By giving your custom subclass a delegate property, by sending a notification center message, or whatever method best fits your needs.)



          (I did a simple test of this approach and it worked. I didn't test exhaustively however.)



          The fact that the UIPageViewController reliably updates the page control but that there's no reliable, obvious way to figure out the current page index seems like an oversight in the design of this class.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 23 '18 at 14:01









          Duncan CDuncan C

          92.4k13114196




          92.4k13114196













          • Thanks for your suggestion, I shall give that a go and get back to you. I started going down the rabbit hole of trying to prevent "overscroll" of the views inside a UIPageViewController but was getting nowhere. It was probably my inexperience / not quite wording my searches correctly as I was constantly pointed towards UIScrollView's bounce property (which wasn't relevant). Do you think that attempting to disable swiping gestures to the left (on the rightmost page) and vice versa would also adequately eliminate this edge case?

            – zb1995
            Nov 23 '18 at 14:12



















          • Thanks for your suggestion, I shall give that a go and get back to you. I started going down the rabbit hole of trying to prevent "overscroll" of the views inside a UIPageViewController but was getting nowhere. It was probably my inexperience / not quite wording my searches correctly as I was constantly pointed towards UIScrollView's bounce property (which wasn't relevant). Do you think that attempting to disable swiping gestures to the left (on the rightmost page) and vice versa would also adequately eliminate this edge case?

            – zb1995
            Nov 23 '18 at 14:12

















          Thanks for your suggestion, I shall give that a go and get back to you. I started going down the rabbit hole of trying to prevent "overscroll" of the views inside a UIPageViewController but was getting nowhere. It was probably my inexperience / not quite wording my searches correctly as I was constantly pointed towards UIScrollView's bounce property (which wasn't relevant). Do you think that attempting to disable swiping gestures to the left (on the rightmost page) and vice versa would also adequately eliminate this edge case?

          – zb1995
          Nov 23 '18 at 14:12





          Thanks for your suggestion, I shall give that a go and get back to you. I started going down the rabbit hole of trying to prevent "overscroll" of the views inside a UIPageViewController but was getting nowhere. It was probably my inexperience / not quite wording my searches correctly as I was constantly pointed towards UIScrollView's bounce property (which wasn't relevant). Do you think that attempting to disable swiping gestures to the left (on the rightmost page) and vice versa would also adequately eliminate this edge case?

          – zb1995
          Nov 23 '18 at 14:12


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53446854%2freliably-track-page-index-in-a-uipageviewcontroller-swift%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Berounka

          Sphinx de Gizeh

          Fiat S.p.A.