Control backward scrolling in a UINavigationController

I am creating a simple flash card as shown below:

flash cards are not animated

I want the scroll back to happen as follows:

flash cards animated

To do this, onBack(index: Int) is what I need to call when scrolling happens (to update the map displayed):

 import UIKit class ViewController: UIViewController { @IBOutlet weak var flashCardLabel: UILabel! // Populate initial content let content = ["Lorem", "Ipsum", "Dolor", "Sit"] // Index of where we are in content var index = 0 override func viewDidLoad() { super.viewDidLoad() } // Label text based on index func setLabelToIndex() { flashCardLabel.text = content[index] } // Go back @IBAction func back(_ sender: Any) { if index > 0 { index = index - 1 setLabelToIndex() } } // Go forward @IBAction func next(_ sender: Any) { if index + 1 < content.count { index = index + 1 setLabelToIndex() } } // Desired function to be called // when swiping back in navigation stack func onBack(index: Int) { self.index = index setLabelToIndex() } } 
+5
source share
3 answers

If I understand your question correctly, you want to be able to scroll between questions and / or have a swipe effect when you click Next or Back. In this case, I suggest you insert the UILabel into the UIScrollView . Check this:

 class ViewController: UIViewController,UIScrollViewDelegate { let content = ["Lorem", "Ipsum", "Dolor", "Sit"] let scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: 320, height: 300)) var index = 0 override func viewDidLoad() { super.viewDidLoad() scrollView.delegate = self scrollView.contentSize = CGSize(width: self.view.frame.width * content.count, height: self.scrollView.frame.size.height) scrollView.isPagingEnabled = true // add labels to pages for i in 0 ..< content.count { let label = UILabel(frame: CGRect(x: self.view.center.x * (i + 1), y: self.view.center.y, width: 100, height: 50)) label.textAlignment = .center label.text = content[i] scrollView.addSubview(label) } self.view.addSubview(scrollView) } // Go back @IBAction func back(_ sender: Any) { if index > 0 { index = index - 1 // scroll to page let offset = CGPoint(x: CGFloat(index) * self.view.frame.width, y: 0) self.scrollView.setContentOffset(offset, animated: true) } } // Go forward @IBAction func next(_ sender: Any) { if index + 1 < content.count { index = index + 1 // scroll to page let offset = CGPoint(x: CGFloat(index) * self.view.frame.width, y: 0) self.scrollView.setContentOffset(offset, animated: true) } } func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { index = round(scrollView.contentOffset.x / scrollView.frame.size.width) } } 

Explanation:

Basically, you create a UIScrollView to handle the pagination effect and add a UILabel to each page with the corresponding text from the content array. Each time a user scrolls to another page, index updated to the index of the current page. And finally, when the user clicks "Next" or "Back", you go to the next or previous page

+4
source

If you want this to be using the Push and Pop navigationcontroller, you can do this by specifying a static index variable. Here is the code

 class ViewController: UIViewController { @IBOutlet weak var flashCardLabel: UILabel! // Populate initial content let content = ["Lorem", "Ipsum", "Dolor", "Sit"] // Index of where we are in content static var INDEX = 0; override func viewDidLoad() { super.viewDidLoad() self.next(nil); } // Label text based on index func setLabelToIndex() { flashCardLabel.text = content[ViewController.INDEX] } // Go back @IBAction func back(_ sender: Any?) { if ViewController.INDEX > 0 { ViewController.INDEX = ViewController.INDEX - 1 setLabelToIndex() } } // Go forward @IBAction func next(_ sender: Any?) { if ViewController.INDEX + 1 < content.count { ViewController.INDEX = ViewController.INDEX + 1 setLabelToIndex() } } // Desired function to be called // when swiping back in navigation stack func onBack(index: Int) { ViewController.INDEX -= 1; //setLabelToIndex() } override func didMove(toParentViewController parent: UIViewController?) { if parent == nil { self.onBack(index: ViewController.INDEX); } } } 
+1
source

I can tell you that the swipe, that the UINavigationController suppport is a swipe, when the user starts to scroll his finger to the left of the screen to the right to pull the view out of the navigation, you cannot push it away by moving it from the right to the left in the iPhone, this is used by default in UINavigationController

I am writing my code, since I use you to configure it accordingly, I did not have time to edit, I will tell you more

 #pragma mark for pageView - (UIViewController *) viewControllerAtIndex:(NSUInteger)index { if (index > (self.imageArray.count-1)) return nil; UIViewController *viewController = nil; //// GalleryItems *item = self.imageArray[index]; NSString *cachedGalleryItemName = [item getCachedPhotoFileNameWithPath]; if ([[NSFileManager defaultManager] fileExistsAtPath:cachedGalleryItemName]) { ImageViewController *imageVC = [[ImageViewController alloc] initWithNibName:@"ImageViewController" bundle:nil]; imageVC.galleryItem = item; imageVC.cachedGalleryItemName = cachedGalleryItemName; imageVC.index = index; viewController = imageVC; } else { if (self.downloadViewController) { if (self.indexOfDownloadInProgress == index) viewController = self.downloadViewController; else { FileDownloader *fileDownloader = [DataDownloadManager existingFileDownloader:cachedGalleryItemName]; if (! fileDownloader) { fileDownloader = [[FileDownloader alloc] init]; [fileDownloader loadURL:item.photoURL forFilePath:cachedGalleryItemName withReceipt:nil]; fileDownloader.delegate = nil; fileDownloader.notificationName = item.contentId; fileDownloader.queuePriority = NSOperationQueuePriorityNormal; [[DataDownloadManager sharedInstance].operationQueue addOperation:fileDownloader]; } } } else { DownloadViewController *downloadVC = [[DownloadViewController alloc] initWithNibName:@"DownloadViewController" bundle:nil]; downloadVC.delegate = self; downloadVC.downloadCompleteNotificationName = item.contentId; downloadVC.asset = item; downloadVC.backgroundImageFileName = nil; downloadVC.totalFileSize = nil; downloadVC.URLString = item.photoURL; downloadVC.cachedFileName = cachedGalleryItemName; self.indexOfDownloadInProgress = index; self.downloadViewController = downloadVC; viewController = downloadVC; } } return viewController; } 

Now use this function to identify the view controller

 -(NSUInteger) indexOfViewController:(UIViewController *)viewController { NSUInteger index = nil; if ([viewController isMemberOfClass:[ImageViewController class]]) { ImageViewController *currentViewController = (ImageViewController *)viewController; index = currentViewController.index; } else if ([viewController isMemberOfClass:[DownloadViewController class]]) index = self.indexOfDownloadInProgress; return index; } - (UIViewController *)viewController:(UIViewController *)viewController ForBeforeAfter:(NSInteger) beforeAfter { NSUInteger index = [self indexOfViewController:viewController]; if (index == NSNotFound) return nil; index = index + beforeAfter; if ([DataDownloadManager sharedInstance].internetNotAvailable) { while (index < self.imageArray.count - 1) { GalleryItems *item = self.imageArray[index]; if ([item isDownloaded]) break; index = index + beforeAfter; } } return [self viewControllerAtIndex:index]; } 

now do this in the page list controller delegate

 -(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController { return [self viewController:viewController ForBeforeAfter:-1]; } -(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController { return [self viewController:viewController ForBeforeAfter:+1]; } 

page view control

 - (void)initPageViewController:(UIViewController *)initViewController { self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil]; [self.pageViewController setDataSource:self]; [self.pageViewController setViewControllers:@[initViewController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil]; [self.pageViewController.view setFrame:self.view.frame]; [self addChildViewController:self.pageViewController]; [self.view addSubview:self.pageViewController.view]; [self.pageViewController didMoveToParentViewController:self]; [self.view sendSubviewToBack:self.pageViewController.view]; } 

in viewDidLoad class (in my case it is DisplayImageViewController), you use this page, you can add this code to initialize

 [self initPageViewController:[self viewControllerAtIndex:self.index]]; 

this DisplayImageViewController class is used to display an image that you just remove the UIIMAGE so that you need something.

and before you click this view controller in the navigation system, set a property like this

 DisplayImageViewController *divc = initialize display view controller class; // here you just set the item in array in which you want to implement swipe divc.imageArray = self.imageArray; divc.galleryAsset = self.gallery; divc.index = indexPath.item; [self presentViewController:divc animated:YES completion:nil]; 
+1
source

Source: https://habr.com/ru/post/1263080/


All Articles