在UINavigationController中控制向后滑动操作

时间:2017-01-20 00:21:57

标签: ios swift uiscrollview uinavigationcontroller

我正在制作一个简单的闪存卡应用,如下图所示:

flash cards not animated

我想要向后滑动,就像这样:

flash cards animated

要做到这一点,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()
    }
}

3 个答案:

答案 0 :(得分:5)

如果我正确理解了您的问题,那么当您点击&#34;下一步&#34;时,您希望能够在问题之间滑动和/或具有滑动效果。或&#34;返回&#34;。如果是这种情况,我建议您将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来处理分页效果,并使用UILabel数组中的相应文本为每个页面添加content。每次用户滚动到不同的页面时,index都会更新为当前页面的索引。最后,当用户点击&#34;下一步&#34;或者&#34;返回&#34;,滚动到下一页或上一页

答案 1 :(得分:1)

如果你想通过Push&amp; Pop navigationcontroller,你可以通过制作静态索引变量来实现。 这是代码

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

    }

}

答案 2 :(得分:1)

我可以告诉你,滑动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];