Skip to content

Instantly share code, notes, and snippets.

@marcandreappel
Forked from andreif/AppDelegate.swift
Created July 24, 2017 21:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcandreappel/62dc5771b4c050b5b34a73be1c0088e0 to your computer and use it in GitHub Desktop.
Save marcandreappel/62dc5771b4c050b5b34a73be1c0088e0 to your computer and use it in GitHub Desktop.
Example of UIPageViewController without storyboard i.e. created programmatically
// derived from https://www.veasoftware.com/posts/uipageviewcontroller-in-swift-xcode-62-ios-82-tutorial
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window = UIWindow(frame: UIScreen.mainScreen().bounds)
window!.rootViewController = ViewController()
window!.makeKeyAndVisible()
return true
}
}
struct Page {
var title: String
var image: String
}
let PAGES = [
Page(title: "Explore", image: "https://i.imgur.com/FGknouw.png"),
Page(title: "Today Widget", image: "https://i.imgur.com/feuwhEc.png"),
]
class ViewController: UIViewController {
var pageViewController: UIPageViewController!
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.whiteColor()
let pc = UIPageControl.appearance()
pc.pageIndicatorTintColor = UIColor.lightGrayColor()
pc.currentPageIndicatorTintColor = UIColor.blackColor()
pc.backgroundColor = UIColor.whiteColor()
let btn = UIButton(type: .System)
btn.setTitle("Restart", forState: .Normal)
btn.addTarget(self, action: "restartAction:", forControlEvents: .TouchUpInside)
self.pageViewController = UIPageViewController(transitionStyle: .Scroll, navigationOrientation: .Horizontal, options: nil)
self.pageViewController.dataSource = self
self.restartAction(self)
self.addChildViewController(self.pageViewController)
let views = [
"pg": self.pageViewController.view,
"btn": btn,
]
for (_, v) in views {
v.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(v)
}
NSLayoutConstraint.activateConstraints(
[NSLayoutConstraint(
item: btn,
attribute: .CenterX,
relatedBy: .Equal,
toItem: self.view,
attribute: .CenterX,
multiplier: 1,
constant: 0),
] +
NSLayoutConstraint.constraintsWithVisualFormat("H:|[pg]|", options: .AlignAllCenterX, metrics: [:], views: views) +
NSLayoutConstraint.constraintsWithVisualFormat("V:|-30-[pg]-[btn]-15-|", options: .AlignAllCenterX, metrics: [:], views: views)
)
self.pageViewController.didMoveToParentViewController(self)
}
func restartAction(sender: AnyObject) {
self.pageViewController.setViewControllers([self.viewControllerAtIndex(0)], direction: .Forward, animated: true, completion: nil)
}
func viewControllerAtIndex(index: Int) -> ContentViewController {
if (PAGES.count == 0) || (index >= PAGES.count) {
return ContentViewController()
}
let vc = ContentViewController()
vc.pageIndex = index
return vc
}
}
// MARK: - Page View Controller Data Source
extension ViewController: UIPageViewControllerDataSource {
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if (index == 0 || index == NSNotFound) {
return nil
}
index--
return self.viewControllerAtIndex(index)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if (index == NSNotFound) {
return nil
}
index++
if (index == PAGES.count) {
return nil
}
return self.viewControllerAtIndex(index)
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return PAGES.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
}
class ContentViewController: UIViewController {
var pageIndex: Int!
override func viewDidLoad() {
super.viewDidLoad()
let lb = UILabel()
lb.textAlignment = .Center
lb.text = PAGES[self.pageIndex].title
let iv = UIImageView()
iv.contentMode = .ScaleAspectFit
ImageLoader.sharedLoader.imageForUrl(PAGES[self.pageIndex].image) { (image, url) -> () in
iv.image = image
}
let views = [
"iv": iv,
"lb": lb,
]
for (_, v) in views {
v.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(v)
}
NSLayoutConstraint.activateConstraints(
NSLayoutConstraint.constraintsWithVisualFormat("H:|-[lb]-|", options: .AlignAllCenterX, metrics: [:], views: views) +
NSLayoutConstraint.constraintsWithVisualFormat("H:|-[iv]-|", options: .AlignAllCenterX, metrics: [:], views: views) +
NSLayoutConstraint.constraintsWithVisualFormat("V:|-[lb]-[iv]-|", options: .AlignAllCenterX, metrics: [:], views: views)
)
}
}
class ImageLoader {
// source and license: https://github.com/natelyman/SwiftImageLoader
let cache = NSCache()
class var sharedLoader : ImageLoader {
struct Static {
static let instance : ImageLoader = ImageLoader()
}
return Static.instance
}
func imageForUrl(urlString: String, completionHandler: (image: UIImage?, url: String) -> ()) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {()in
let data = self.cache.objectForKey(urlString) as? NSData
if let goodData = data {
let image = UIImage(data: goodData)
dispatch_async(dispatch_get_main_queue(), {() in
completionHandler(image: image, url: urlString)
})
return
}
let downloadTask: NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: urlString)!, completionHandler: {(data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
if (error != nil) {
completionHandler(image: nil, url: urlString)
return
}
if let data = data {
let image = UIImage(data: data)
self.cache.setObject(data, forKey: urlString)
dispatch_async(dispatch_get_main_queue(), {() in
completionHandler(image: image, url: urlString)
})
return
}
})
downloadTask.resume()
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment