UIPageViewController with Peeking

uipageviewcontroller show multiple pages
ios paging view controller
uiscrollview autolayout

I'm trying to create a page browser by using a UIPageViewController in Interface Builder that allows displaying part of the adjacent pages (aka peeking). I've been following a tutorial at http://www.appcoda.com/uipageviewcontroller-storyboard-tutorial/ (and ported it into Swift) which is rather straightforward but I can't quite figure out what changes to make to have a page displayed in the UIPageViewController which is smaller than the screen (and centered) and having the adjacent pages appear partly on the screen left and right.

I've tried to resize the page content view controller in IB and with code but the page view controller will still fill the whole screen.

Does anyone know of a tutorial that covers this functionality or what is a good approach to get the desired effect?

This screenshot below from Bamboo Paper shows what I'm trying to achieve...

Like @davew said, peeking views will need to use UIScrollView. I too searched for a way to use UIPageViewController but couldn't find any resource.

Using UIScrollView to make this feature was less painful that I had imagined.


Here is a simple example to see the basic controls in action.

First: make a UIViewController, then in the viewDidLoad method, add the following code:

float pad = 20;
NSArray* items = @[@"One", @"Two", @"Three", @"Four"];

self.view.backgroundColor = [UIColor greenColor];

UIScrollView* pageScrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
pageScrollView.opaque = NO;
pageScrollView.showsHorizontalScrollIndicator = NO;
pageScrollView.clipsToBounds = NO;
pageScrollView.pagingEnabled = YES;

adjustFrame(pageScrollView, pad, deviceH()/4, -pad*3, -deviceH()/2);

[self.view addSubview: pageScrollView];

float w = pageScrollView.frame.size.width;

for(int i = 0; i < [items count]; i++){
    UIView* view = [[UIView alloc] initWithFrame:pageScrollView.bounds];
    view.backgroundColor = [UIColor blueColor];
    setFrameX(view, (i*w)+pad);
    setFrameW(view, w-(pad*1));
    [pageScrollView addSubview:view];
}

pageScrollView.contentSize = CGSizeMake(w*[items count], pageScrollView.frame.size.height);

FYI, I used these util functions to adjust the size of the view frames; I get sick of manually changing them with 3+ lines of code.

Update

I have wrapped up this code in a simple ViewController and put it on GitHub

https://github.com/kjantzer/peek-page-view-controller

It is in no way complete, but it's a working start.

Using ScrollStyle with UIPageViewController, One of the changes introduced with iOS 6 is the ability to use the UIPageViewController to use a scrolling animation instead of the standard� Overview. Page view controller–navigation can be controlled programmatically by your app or directly by the user using gestures. When navigating from page to page, the page view controller uses the transition that you specify to animate the change.

koreyhinton/PagedController, UIPageViewController has always been difficult to implement. It can also be the source of many obscure and sometimes less-obscure bugs. I found myself� UIPageViewController(UIPageViewControllerTransitionStyle, UIPageViewControllerNavigationOrientation, UIPageViewControllerSpineLocation) Creates an initialized UIPageViewController object by using a UIPageViewControllerTransitionStyle of transition between pages, a UIPageViewControllerNavigationOrientation orientation of navigation, and a spineLocation .

I rewrite Kevin Jantzer answer in swift 4 and it's works!

override func viewDidLoad() {
    super.viewDidLoad()
    let pad: CGFloat = 20
    let items: [UIColor] = [.blue, .yellow, .red, .green]

    self.view.backgroundColor = .white

    var pageScrollView = UIScrollView(frame: self.view.frame)
    pageScrollView.isOpaque = false
    pageScrollView.showsHorizontalScrollIndicator = false
    pageScrollView.clipsToBounds = false
    pageScrollView.isPagingEnabled = true
    adjustFrame(myView: pageScrollView, x: pad, y: UIScreen.main.bounds.height / 4, w: -pad * 3, h: -UIScreen.main.bounds.height/2)

    self.view.addSubview(pageScrollView)
    let w = pageScrollView.frame.size.width

    for (i, item) in items.enumerated() {
        let myView = UIView(frame: pageScrollView.bounds)
        myView.backgroundColor = item
        setFrameX(myView: myView, x: (CGFloat(i) * w) + pad);
        setFrameW(myView: myView, w: w-(pad*1));
        pageScrollView.addSubview(myView)
    }

    pageScrollView.contentSize = CGSize(width: w * CGFloat(items.count), height: pageScrollView.frame.size.height);
}

func setFrame(myView: UIView, x: CGFloat?, y: CGFloat?, w: CGFloat?, h: CGFloat?){
    var f = myView.frame

    if let safeX = x {
        f.origin = CGPoint(x: safeX, y: f.origin.y)
    }
    if let safeY = y {
        f.origin = CGPoint(x: f.origin.x, y: safeY)
    }
    if let safeW = w {
        f.size.width = safeW
    }
    if let safeH = h {
        f.size.height = safeH
    }

    myView.frame = f
}

func setFrameX(myView: UIView, x: CGFloat) {
    setFrame(myView: myView, x: x, y: nil, w: nil, h: nil)
}
func setFrameY(myView: UIView, y: CGFloat) {
    setFrame(myView: myView, x: nil, y: y, w: nil, h: nil)
}
func setFrameW(myView: UIView, w: CGFloat) {
    setFrame(myView: myView, x: nil, y: nil, w: w, h: nil)
}
func setFrameH(myView: UIView, h: CGFloat) {
    setFrame(myView: myView, x: nil, y: nil, w: nil, h: h)
}

func adjustFrame(f: CGRect, x: CGFloat?, y: CGFloat?, w: CGFloat?, h: CGFloat?) -> CGRect {
    var rect = f

    if let safeX = x {
        rect.origin = CGPoint(x: rect.origin.x + safeX, y: f.origin.y)
    }
    if let safeY = y {
        rect.origin = CGPoint(x: f.origin.x, y: rect.origin.y + safeY)
    }
    if let safeW = w {
        rect.size.width = safeW + rect.size.width
    }
    if let safeH = h {
        rect.size.height = safeH + rect.size.height
    }

    return rect
}

func adjustFrame(myView: UIView, x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat) {
    myView.frame = adjustFrame(f: myView.frame, x: x, y: y, w: w, h: h);
}
}

How do I implement a behaviour where user is swiping through , It should be swipe-able simply left/right just like UIPageViewController, but on each page, you When you're researching how to do it use the term “peeking”. The UIPageViewController class was first introduced in iOS 5 SDK that lets developers build pages of content, where each page is managed by its own view controller. The class was further improved in iOS 6 to support the scrolling transition. With page view, users can easily navigate between multiple pages through simple gesture.

UIPageViewController, In tvOS, the UIPageViewController class provides only a way to swipe between full-screen content pages. Unlike in iOS, a user cannot interact with or move� I’ve found a few questions about how to make a UIPageViewController jump to a specific page, but I’ve noticed an added problem with jumping that none of the answers seem to acknowledge. Without going into the details of my iOS app (which is similar to a paged calendar), here is what I’m experiencing.

UIPageViewController与Peeking, Remarks. The UIPageViewController presents its ViewControllers one or two at a time, Registers this view controller for 3D Touch peek and pop operations. Display a PDF with UIPageViewController. Contribute to sdesimone/UIPageViewController-PDF development by creating an account on GitHub.

UIPageViewController Class (UIKit), Like @davew said, peeking views will need to use UIScrollView. I too searched for a way to use UIPageViewController but couldn't find any resource. 4. Create UIPageViewController class and inherit from UIPageViewController, UIPageViewControllerDatasource, and UIPageViewControllerDelegate 6. Set the UIPageViewController in storyboard its custom…

Comments
  • Have you got any success here?
  • @Pramod see my answer below
  • How will this work if we have views of different heights ?