I'm building a typical Xcode 6 iOS app.
My goal is:
A screen that has an sub-area that can be swiped to change the content.
For example, the home screen has a logo image, a middle area that I want to be swipeable, and a bottom button.
When the user swipes (or taps) the middle area, the area shows the next (or previous) information, which is a typical UIImage and UILabel caption.
The rest of the screen stays the same, i.e. there is no navigation change.
The code is here. It use the recommendations from the StackOverflow post here.
My question: how can I implement the code below better, while still using an XIB?
My current implementation does work, and uses this approach...
A typical Swift Demo.swift
file that is a UIViewController that has:
A typical Demo.xib
file that has:
I am seeking better ways to accomplish this; I've read many of Xcode tutorials and so far none seem definitive for Xcode 6, XIBs, and Swift.
Here are some implementations that I've researched that seem promising...
Is there a way to implement a subview area in the XIB?
Is there an idiomatic way to write the code for changeable content?
Is there a way to make a PageControl XIB object large enough to cover the entire UIImageView and UILabel, so I can skip making the UIImageView respond to gestures.
The bounty will be for expert advice.
One way to do this is programmatically create an UIScrollView in your UIViewController . To control the scrollability you can set the ScrollView contentSize property.
1. Add scrollView(1) in storyboard, add needed constraint to top/bottom/trailing/leading. 2. Then uncheck "Content Layout Guides" in Size inspector section for your scrollView.
To make a UIPageViewController swipe-able you should implement the UIPageViewControllerDataSource
protocol and provide a view controller for the pageViewController(pageViewController:viewControllerBeforeViewController) -> UIViewController?
and the ...viewControllerAfterViewController)
methods.
Provide a custom view controller for each page that presents an image and label and takes them as properties so you can provide them from the PageViewController.
My trick it to create a method that instantiates a new view controller in these methods:
// MARK:- UIPageViewControllerDataSource
extension MyPageViewController: UIPageViewControllerDataSource {
func viewControllerWithIndex(var index: Int) -> UIViewController! {
let viewController = storyboard?.instantiateViewControllerWithIdentifier("MyViewController") as! MyViewController // This VC has to be in the storyboard, otherwise just use MyVC()
// Adjust the index to be cyclical, not required
if let count = data?.endIndex {
if count == 1 && index != 0 { return nil }
if index < 0 { index += count }
index %= count
}
viewController.view.tag = index
viewController.record = data?[index]
return viewController
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let index = viewController.view?.tag ?? 0
return viewControllerWithIndex(index + 1)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let index = viewController.view?.tag ?? 0
return viewControllerWithIndex(index - 1)
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return countAndSetupPageControl()
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return viewController?.view.tag ?? 0
}
}
Now for the "sub-area" you will need to implement a ChildViewController
. If you're using storyboards you can just drag a Container View
and put PageViewController
in the embedded view controller, otherwise you need to add the PageViewController.view
as a subview and set the frame
to the middle.
You can find more info in the apple documentation but basically you MUST call these methods:
addChildViewController(pageViewController)
view.addSubView(pageViewController.view)
pageViewController.view.frame = ... // This is your "sub-area"
pageViewController.didMoveToParentViewController(self)
If you add a height constraint to PageControl you can set it's height to whatever you want.
I don't see a problem with your current implementation. Changing it to use a PageViewController would be quite more work.
If I were you I would add an animation in pageUpdate function so the image would fade in or slide in...
It would only make sense to use a PageViewController if you want to be able to scroll to the next page (as in content moving in the same time your finger is moving onscreen). And you can use a PageViewController or a CollectionView with paging enabled.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With