【问题标题】:Control swipe back action in UINavigationController在 UINavigationController 中控制向后滑动操作
【发布时间】:2017-06-04 21:02:24
【问题描述】:

我正在创建一个简单的闪存卡应用程序,如下图所示:

我希望像这样向后滑动:

为此,onBack(index: Int) 是我需要在向后滑动时调用的名称(以更新显示的卡片):

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

【问题讨论】:

  • 对不起,这个问题一团糟。我无法理解你想要做什么。
  • 为什么不使用UINavigationController?在每个“后退”和“下一个”上,您都可以在没有动画的情况下推动/弹出。向后滑动会自动工作。
  • @Sulthan 这个方法是否将每个 ViewController 存储在内存中?

标签: ios swift uiscrollview uinavigationcontroller


【解决方案1】:

如果我正确理解您的问题,您希望能够在问题之间滑动和/或在单击“下一步”或“返回”时产生滑动效果。如果是这种情况,我建议您将UILabel 嵌入UIScrollView。看看这个:

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

说明:

您基本上创建一个UIScrollView 来处理分页效果,并使用content 数组中的相应文本将UILabel 添加到每个页面。每次用户滚动到不同的页面时,index 都会更新为当前页面的索引。最后,当用户点击“下一页”或“后退”时,您会滚动到下一页或上一页

【讨论】:

    【解决方案2】:

    如果您希望通过 Push & Pop 导航控制器来实现,您可以通过设置静态索引变量来实现。 这是代码

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

    【讨论】:

      【解决方案3】:

      我可以告诉你,UINavigationController 支持的滑动是当用户开始将手指从屏幕左侧滑动到右侧时的滑动,只是为了从导航中弹出视图,你不能通过从右边缘向左滑动来将其推回在 iPhone 中,这是 UINavigationController 中的默认设置

      我正在编写我的代码,因为我正在使用你需要相应地自定义它,我没有时间在办公室编辑,我会告诉你更多

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

      现在使用这个函数来识别视图控制器

      -(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];
      }
      

      现在在页面视图控制器委托中执行此操作

      -(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];
      }
      

      像这样初始化页面视图控制器

      - (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];
      }
      

      在类的viewDidLoad中(在我的例子中是DisplayImageViewController)你正在使用这个页面你可以添加这段代码来初始化

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

      这个 DisplayImageViewController 类用于显示你刚刚删除 UIIMAGE 到你想要的东西的图像。

      在导航中推送此视图控制器之前,请像这样设置属性

      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];
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-02
        • 1970-01-01
        • 2013-06-17
        • 2020-01-17
        • 2017-06-24
        相关资源
        最近更新 更多