How to make Images clickable in a UIPageViewController? - swift

I am creating a UIPageController which swipes 4 pages. In each page there is an image from the array I created. Now I want to make each image from the swipe view clickable to present a new specific page. Each image from the swipe view leads to a different 10 levels (buttons) page.
the project file is here:
http://s000.tinyupload.com/?file_id=90198426971136689376
This is my code in ViewController:
private var pageViewController: UIPageViewController?
private let contentImages = ["Pack_1.png",
"Pack_2.png",
"Pack_3.png",
"nature_pic_4.png"];
override func viewDidLoad() {
super.viewDidLoad()
createPageViewController()
setupPageControl()
}
private func createPageViewController() {
let pageController = self.storyboard!.instantiateViewControllerWithIdentifier("PageController") as! UIPageViewController
pageController.dataSource = self
if contentImages.count > 0 {
let firstController = getItemController(0)!
let startingViewControllers: NSArray = [firstController]
pageController.setViewControllers(startingViewControllers as? [UIViewController], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
}
pageViewController = pageController
addChildViewController(pageViewController!)
self.view.addSubview(pageViewController!.view)
pageViewController!.didMoveToParentViewController(self)
}
private func setupPageControl() {
let appearance = UIPageControl.appearance()
appearance.pageIndicatorTintColor = UIColor.grayColor()
appearance.currentPageIndicatorTintColor = UIColor.whiteColor()
appearance.backgroundColor = UIColor.darkGrayColor()
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let itemController = viewController as! PageItemController
if itemController.itemIndex > 0 {
return getItemController(itemController.itemIndex-1)
}
return nil
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let itemController = viewController as! PageItemController
if itemController.itemIndex+1 < contentImages.count {
return getItemController(itemController.itemIndex+1)
}
return nil
}
private func getItemController(itemIndex: Int) -> PageItemController? {
if itemIndex < contentImages.count {
let pageItemController = self.storyboard!.instantiateViewControllerWithIdentifier("ItemController") as! PageItemController
pageItemController.itemIndex = itemIndex
pageItemController.imageName = contentImages[itemIndex]
return pageItemController
}
return nil
}
}
and this code is in my pageItemController:
var itemIndex: Int = 0
var imageName: String = "" {
didSet {
if let imageView = contentImageView {
imageView.image = UIImage(named: imageName)
}
}
}
#IBOutlet var contentImageView: UIImageView?
override func viewDidLoad() {
super.viewDidLoad()
contentImageView!.image = UIImage(named: imageName)
self.view.backgroundColor = UIColor (red: 100, green: 100, blue: 100, alpha: 0)
}
}

As per this version of the quesion:
"I'm creating a UIPageControllerView that shows 4 images. is there any way to make this images clickable? each image should present a dedicate page. this is my code in viewController:"
SOLUTION:
Use UIGestureRecognizer.
1) Click on your Main.Storyboard.
2) Select UIGestureRecognizer.
3) Drag it on your Image of choice.
3.5) Use Cmd+Alt+Enter to open the Assistant Editor
4) Create an IBAction by Ctrl-dragging from your UITapGestureRecogniser to the Assistant Editor.
5) Put this code in your ViewController.
class ViewController {
let itemIndex: Int!
func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool)
{
if (!completed)
{
return
}
self.pageControl.currentPageIndex = pageViewController.viewControllers!.first!.view.tag //Page Index
self.itemIndex = self.pageControl.currentPageIndex
}
#IBAction func presentDedicatedPage(sender: UIImageView) {
//pseudo-code here, for example:
switch self.itemIndex {
case 0:
// present these 10 levels
break
case 1:
//present these other 10 levels
break
case 2:
//present these other 10 levels
break
case 3:
//present these other 10 levels
break
}
}

On your ItemPageController:
var itemIndex:Int?
var imageName:String?
Add UITapGesture To ImageView.
override func viewDidLoad() {
super.viewDidLoad()
let tapGestureRecognizer = UITapGestureRecognizer(target:self, action:Selector("imageTapped:"))
targetImageView.userInteractionEnabled = true
targetImageView.addGestureRecognizer(tapGestureRecognizer)
targetImageView.image = UIImage(named: imageName!)
}
On its triggered method:
func imageTapped(img: AnyObject)
{
print(imageName)
print(itemIndex)
//Using a switch statement
let targetImageIndex = itemIndex! as Int
switch (targetImageIndex) {
case 0:
print("case 0")
break;
case 1:
print("case 1")
break;
case 2:
print("case 2")
break;
default:
break;
}
}

Related

Capture snapshot of unselected UITabBarItem?

I am writing some tutorial code for app, and would like to make screen shot of unselected tab bar item. Here is the code I have written so far:
extension UIView {
var globalFrame: CGRect {
superview?.convert(frame, to: nil) ?? .zero
}
}
extension UIView {
var snapshot: UIImage {
UIGraphicsImageRenderer(size: bounds.size).image { _ in
drawHierarchy(in: frame, afterScreenUpdates: false)
}
}
}
extension UITabBar {
func snapshotDataForTab(atIndex index: Int) -> (UIImage, CGRect) {
var tabs = subviews.compactMap { (view: UIView) -> UIControl? in
if let view = view as? UIControl {
return view
}
return nil
}
tabs.sort(by: { $0.frame.origin.x < $1.frame.origin.x })
return (tabs[index].snapshot, tabs[index].globalFrame)
}
}
Main controller:
class MainTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
selectedIndex = 0
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.presentTooltip(forTabAtIndex: 0)
}
}
private func presentTooltip(forTabAtIndex index: Int) {
let dimView = UIView(frame: view.frame)
dimView.backgroundColor = .red
view.addSubview(dimView)
let (image, frame) = tabBar.snapshotDataForTab(atIndex: index)
let imageView = UIImageView(image: image)
imageView.frame = frame
dimView.addSubview(imageView)
}
}
Interestingly enough everything works as expected when selectedIndex is 0 and I call presentTooltip for value 0. However if I call presentTooltip with 1, nothing is rendered. If I switch selectedIndex to 1, then it's reversed, and nothing gets rendered for presentTooltip with 0.
It seems I am unable to capture snapshot of inactive tab?
The snapshot function is buggy. I'm able to take snapshot of the unselected UITabbar item.
Below is the correct snapshot function:
var snapshot: UIImage {
let renderer = UIGraphicsImageRenderer(bounds: self.bounds)
return renderer.image { (context) in
self.layer.render(in: context.cgContext)
}
}
Check the project here Github Repo
This is the screenshot showing a snapshot of unselected UITabbaritem.

iOS 14 UIColorPicker eyedropper tool not returning selected color

I am currently trying to implement the new iOS 14 UIColorPicker. Everything works great, except the eye dropper functionality of the UIColorPicker. After selecting the the eye dropper and sampling a color, the default behavior should be to re-open the UIColorPicker with your selected color as the active one. For some reason, this does not happen. Here is my implementation, its pretty standard, so I'm not sure why the eyedropper isnt behaving as expected.
I have these functions that are passed as the selectors for when I have some UI elements pressed
#objc func pickColorSky(sender: UIControl){
presentColorPicker(tag: 1, sender: sender)
}
#objc func pickColorBackground(sender: UIControl){
presentColorPicker(tag: 2, sender: sender)
}
#objc func pickColorGround(sender: UIControl){
presentColorPicker(tag: 3, sender: sender)
}
Here is the function that presents the UIColorPickerView itself
#objc private func presentColorPicker(tag: Int, sender: UIControl){
let vc = UIColorPickerViewController()
vc.supportsAlpha = false
vc.delegate = self
vc.view.tag = tag
vc.modalPresentationStyle = .popover
vc.popoverPresentationController?.sourceView = sender
vc.popoverPresentationController?.sourceRect = sender.bounds
self.present(vc, animated: true)
}
And the delegate methods to handle the interacting with the color picker
extension myViewController: UIColorPickerViewControllerDelegate {
func colorPickerViewControllerDidFinish(_ viewController: UIColorPickerViewController) {
guard let options = editor?.apiView?.getRenderingOptions() else { return }
if viewController.view.tag == 1 {
let newColor = getMobileApiColor(color: viewController.selectedColor)
options.skyColor = newColor
skyRow.color.backgroundColor = newColor.uiColor
}
else if viewController.view.tag == 2 {
let newColor = getMobileApiColor(color: viewController.selectedColor)
options.backgroundColor = newColor
backgroundRow.color.backgroundColor = newColor.uiColor
}
else if viewController.view.tag == 3 {
let newColor = getMobileApiColor(color: viewController.selectedColor)
options.groundColor = newColor
groundRow.color.backgroundColor = newColor.uiColor
}
editor?.modelView?.setNeedsDisplay()
}
Try this method colorPickerViewControllerDidSelectColor
extension ViewController: UIColorPickerViewControllerDelegate {
// Called once you have finished picking the color.
func colorPickerViewControllerDidFinish(_ viewController: UIColorPickerViewController) {
self.view.backgroundColor = viewController.selectedColor
}
// Called on every color selection done in the picker.
func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
self.view.backgroundColor = viewController.selectedColor
}
}
You need to hold on to the picker object as a class member like this:
private lazy var colorPicker = makeColorPicker()
private func makeColorPicker() -> UIColorPickerViewController {
let vc = UIColorPickerViewController()
vc.delegate = self
vc.supportsAlpha = false
return vc
}
Otherwise, it is removed from memory before you complete the eye-dropper step.

UIPageViewController + firebase

I'm using UIPageViewController to make book pages and the pages are images that will be fetched from the firebase. the problem is I got this error
(Cannot convert value of type 'books' to expected element type 'Array.ArrayLiteralElement' (aka 'UIViewController')
'books' is a struct I made for firebase
import Foundation
import Firebase
struct books {
let bookId: String
let imageURL: String
}
extension booksC {
init(_ dictionary: [String: Any]) {
self.bookId = dictionary["bookId"] as? String ?? "no book id"
self.imageURL = dictionary["imageURL"] as? String ?? "no image url"
}
}
I'm using this code, what I understand is I can't use an array of images what I should use is an array of controllers and I don't know how to do that in this case. help is appreciated
import UIKit
import FirebaseFirestore
class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
let pageViewController = UIPageViewController(transitionStyle: .pageCurl, navigationOrientation: .horizontal, options: nil)
private var pages = [books]()
private var listener: ListenerRegistration?
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
delegate = self
// index
guard let pagesFirst = pages.last else { return }
setViewControllers([pagesFirst], direction: .reverse, animated: true)
//TODO: add listener
}
func pageViewController(_ pageViewController: UIPageViewController, spineLocationFor orientation: UIInterfaceOrientation) -> UIPageViewController.SpineLocation {
var location = SpineLocation.max
if orientation == .landscapeLeft || orientation == .landscapeRight {
self.pageViewController.isDoubleSided = true
location = .mid
}
return location
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let index = self.pages.firstIndex(where: {$0 == viewController}) ?? 0
if index == 0 { return nil }
return pages[index - 1]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let index = self.pages.firstIndex(where: {$0 == viewController}) ?? 0
if index == pages.count - 1 { return nil }
return pages[index + 1]
}
}
class ImageViewController: UIViewController {
let imageView = UIImageView()
init(image: UIImage) {
imageView.image = image
super.init(nibName: nil, bundle: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(imageView)
imageView.fillSuperview()
imageView.contentMode = .scaleAspectFit
imageView.clipsToBounds = true
imageView.backgroundColor = .white
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func setupImage(for book: books){
imageView.kf.setImage(with: URL(string: book.imageURL))
}
}
enter code hereyou are using your array private var pages = [books]() in setViewControllers which expect a UIViewController
This is how setViewControllers is declared:
func setViewControllers(_ viewControllers: [UIViewController]?,
direction: UIPageViewController.NavigationDirection,
animated: Bool,
completion: ((Bool) -> Void)? = nil)
Parameters
viewControllers
The view controller or view controllers to be displayed.
direction
The navigation direction.
animated
A Boolean value that indicates whether the transition is to be animated.
I think you should create an instance of ImageViewController then set the image using setupImage(for book: books) (which you can access since is a public method and finally assign that view controller your the page controller:
guard let pagesFirst = pages.last else { return }
let imageViewController = ImageViewController()
imageViewController.setupImage(for book: pagesFirst)
setViewControllers([imageViewController], direction: .reverse, animated: true)
EDITED:
Sorry, as far as the second error you get, it should be
imageViewController.setupImage(for:pagesFirst)
as for is the name available outside the class.
For the first error, what init options does it give you. It should be correct.
Try also to change your code declaring imageView this way :
var imageView : UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false // required if you need to work with autolayout
return imageView
}()
removing:
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
lastly, you should name your struct book with a capital B.

How to change value of label from another UICollectionViewCell

What if the UILabel is in class A and the didTapRightutton that will animate it is in class B?
the percentDiscountLabel is in RandomizeDealsCollectionViewCell. This should animate into fade appear if I tap didTapRightutton which is in a different VC called RandomizeDealsViewController
How do I call the function that is inside RandomizeDealsCollectionViewCell to animate the percentDiscountLabel? Is there other way to do this?
class RandomizeDealsCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var percentDiscountLabel: UILabel!
func animatePercentDiscountLabel(deals: String) {
self.percentDiscountLabel.alpha = 0.6
self.percentDiscountLabel.isHidden = false
UIView.animate(withDuration: 0.6, delay: 0, options: .curveEaseInOut, animations: {
self.percentDiscountLabel.alpha = 1.0
}) { (isCompleted) in
}
percentDiscountLabel.text = deals
}
}
class RandomizeDealsViewController: UIViewController {
private var centeredCollectionViewFlowLayout: CenteredCollectionViewFlowLayout!
#IBAction func didTapRightButton(_ sender: Any) {
guard let indexCard = centeredCollectionViewFlowLayout.currentCenteredPage else { return }
if (indexCard > 0) {
centeredCollectionViewFlowLayout.scrollToPage(index: indexCard + 1, animated: true)
// should call the animation function here
}
}
}
If indexCard is indexPath of collectionViewCell which you want to animate,
You can call your cell like ->
in RandomizeDealsViewController
#IBAction func didTapRightButton(_ sender: Any) {
guard let indexCard = centeredCollectionViewFlowLayout.currentCenteredPage else { return }
if (indexCard > 0) {
centeredCollectionViewFlowLayout.scrollToPage(index: indexCard + 1, animated: true)
// should call the animation function here
let cell = collectionView!.cellForItemAtIndexPath(indexCard) as? RandomizeDealsCollectionViewCell
cell?.animatePercentDiscountLabel(deals: "deals")
}
}

my VC has no initializers

When I had XCode 6.1 everything worked well. After having XCOde 6.3 I am having problem with delegate methods.
Before:
protocol MainPageLoaderViewControllerDelegate{
func changeCategoryOfSingelTopicViewController(category: Int!)
}
class MainPageLoaderViewController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate, UIGestureRecognizerDelegate {
var delegate: MainPageLoaderViewControllerDelegate?
var categoryOfSingleTopic: Int! = 0 {
didSet{
delegate?.changeCategoryOfSingelTopicViewController(categoryOfSingleTopic!)
}
}
}
Now, Complier gives me error saying that MainPageLoaderViewController has no initializers. How should I declare delegate var?
The all code:
import UIKit
protocol MainPageLoaderViewControllerDelegate{
func changeCategoryOfSingelTopicViewController(category: Int!)
}
class MainPageLoaderViewController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate, UIGestureRecognizerDelegate {
var delegate: MainPageLoaderViewControllerDelegate?
var categoryOfSingleTopic: Int! = 0{
didSet{
// put to the right column on pageviewcontroller
movePageContentToViewControllerAtIndex(1)
println("here is single topic \(categoryOfSingleTopic)")
delegate?.changeCategoryOfSingelTopicViewController(categoryOfSingleTopic!)
changeADVControleItemsName(categoryOfSingleTopic)
}
}
let gestureRecognizerOfMainPageController: UIPanGestureRecognizer!
#IBOutlet var scrollContentView: UIView!
#IBOutlet var segmentControl: ADVSegmentedControl!
let transtionManger = TransitionManger()
var pageIndexTest: Int!
#IBOutlet var scrollView: UIScrollView!
var mainPageViewController : UIPageViewController!
var tableViewControllers = [UITableViewController]()
var newsLenta: UITableViewController!
var mainPage: SingleTopicTableViewController!
var onlinetranslation: UITableViewController!
var identifiers:NSArray = ["MainPageContentViewController", "MainPageTableViewController", "SingleTopicTableViewController"]
var pageContentViewController: UITableViewController!
override func viewDidLoad() {
super.viewDidLoad()
// self.scrollView.scrollEnabled = false
self.transtionManger.sourceViewController = self
CommonFunctions.setBackgroundImageToNavBar(self.navigationItem)
println("view did load of page controller loaded")
segmentControl.thumbColor = Design.setColorGrey20()
createArrayOfControllers()
resetToMainPage(1)
segmentControl.items = ["Лента", "Главная", "Онлайн"]
segmentControl.font = UIFont(name: "Avenir-Black", size: 12)
segmentControl.borderColor = UIColor(white: 1.0, alpha: 0.3)
segmentControl.selectedIndex = 1
segmentControl.selectedLabelColor = UIColor.whiteColor()
setGestureRecognizerToTableView()
self.transtionManger.segmentToSetInteraction = segmentControl
scrollContentView.addGestureRecognizer(transtionManger.exitPanGesture)
segmentControl.addTarget(self, action: "selectPageIndexBySegmentControl", forControlEvents: UIControlEvents.ValueChanged)
}
func changeADVControleItemsName(category:Int){
switch category{
case 0: segmentControl.items[1] = "Главная" // main
case 100: segmentControl.items[1] = "Избранные" // saved
case 1: segmentControl.items[1] = "Экономика" // economy
case 2: segmentControl.items[1] = "Политика" // politics
case 4: segmentControl.items[1] = "Общество" // community
case 5: segmentControl.items[1] = "Спорт" // sport
case 6: segmentControl.items[1] = "Культура" // culture
case 8: segmentControl.items[1] = "Проишествия" // events
case 10: segmentControl.items[1] = "Авто" // auto
case 11: segmentControl.items[1] = "Фото" // photo
case 12: segmentControl.items[1] = "Видео" // video
default: break
}
}
func changeCategoryOfSingelTopicViewController(category: Int!){
}
func setGestureRecognizerToTableView(){
self.transtionManger.tableViewFromSourceView = self.viewControllerAtIndex(segmentControl.selectedIndex) // we do it in order to disable table view until the menu is opened
}
func movePageContentToViewControllerAtIndex(index: Int){
switch index {
case 0:
println("zero index were selected")
pageContentViewController = self.viewControllerAtIndex(index)
mainPageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward , animated: true, completion: nil)
setGestureRecognizerToTableView()
setExitPaGestureAtViewControllerWithIndex(segmentControl.selectedIndex)
// segmentControl.selectedIndex = index
case 1:
println("first element were selected")
pageContentViewController = self.viewControllerAtIndex(index)
mainPageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
setGestureRecognizerToTableView()
setExitPaGestureAtViewControllerWithIndex(segmentControl.selectedIndex)
segmentControl.selectedIndex = index
case 2:
println("second element were selected")
pageContentViewController = self.viewControllerAtIndex(index)
mainPageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
setGestureRecognizerToTableView()
setExitPaGestureAtViewControllerWithIndex(segmentControl.selectedIndex)
default: break
}
}
func selectPageIndexBySegmentControl(){
switch segmentControl.selectedIndex {
case 0:
movePageContentToViewControllerAtIndex(0)
case 1:
movePageContentToViewControllerAtIndex(1)
case 2:
movePageContentToViewControllerAtIndex(2)
default:
break
}
}
#IBAction func showOrCloseMenu(sender: AnyObject) {
if transtionManger.isMenuVisible == true {
println("it is true")
transtionManger.isMenuVisible = false
transtionManger.menuViewController.performSegueWithIdentifier("dismisMenu", sender: nil)
}
else{
println("it is false")
performSegueWithIdentifier("showMenu", sender: nil)
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let menu = segue.destinationViewController as! SideBarMenuTableViewController
if transtionManger.isMenuVisible == true {
transtionManger.presentingP = false
}
menu.transitioningDelegate = self.transtionManger
// add in order to set menuviewcontroller in transformerManager
self.transtionManger.menuViewController = menu
}
#IBAction func unwindSegueToMainScreen(segue:UIStoryboardSegue) {
// bug? exit segue doesn't dismiss so we do it manually...
self.dismissViewControllerAnimated(true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func createArrayOfControllers(){
newsLenta = self.storyboard?.instantiateViewControllerWithIdentifier("NewsLentaTableViewController")as! NewsLentaTableViewController
mainPage = self.storyboard?.instantiateViewControllerWithIdentifier("SingleTopicTableViewController") as! SingleTopicTableViewController
self.delegate = mainPage
onlinetranslation = self.storyboard?.instantiateViewControllerWithIdentifier("MainPageTableViewController") as! MainPageTableViewController
tableViewControllers = [newsLenta, mainPage, onlinetranslation]
}
func resetToMainPage(index: Int!) {
/* Getting the page View controller */
mainPageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("MainPageViewController") as! UIPageViewController
self.mainPageViewController.dataSource = self
self.mainPageViewController.delegate = self
pageContentViewController = self.viewControllerAtIndex(index)
// pageContentViewController.view.addGestureRecognizer(transtionManger.exitPanGesture3)
// self.transtionManger.sourceViewController = pageContentViewController // adding swipe to the pageContentViewControlle in order to close menu
//self.transtionManger.sourceViewController = mainPageViewController
self.mainPageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
self.mainPageViewController.view.frame = CGRectMake(0, 102, self.view.frame.width, self.view.frame.height)
self.addChildViewController(mainPageViewController)
self.view.addSubview(mainPageViewController.view)
self.mainPageViewController.didMoveToParentViewController(self)
}
func viewControllerAtIndex(index : Int) -> UITableViewController? {
if index > 2 || index < 0 {
return nil
}
return tableViewControllers[index]
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
var index:Int!
if viewController.isKindOfClass(NewsLentaTableViewController) {
index = (viewController as! NewsLentaTableViewController).pageIndex
}else if viewController.isKindOfClass(MainPageTableViewController) {
index = (viewController as! MainPageTableViewController).pageIndex
}else if viewController.isKindOfClass(SingleTopicTableViewController) {
index = (viewController as! SingleTopicTableViewController).pageIndex
}else {return nil}
if index == 2 {
return nil
}
index = index + 1
return self.viewControllerAtIndex(index)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
var index:Int!
if viewController.isKindOfClass(NewsLentaTableViewController) {
index = (viewController as! NewsLentaTableViewController).pageIndex
}else if viewController.isKindOfClass(MainPageTableViewController) {
index = (viewController as! MainPageTableViewController).pageIndex
}else if viewController.isKindOfClass(SingleTopicTableViewController) {
index = (viewController as! SingleTopicTableViewController).pageIndex
}else {return nil}
if index == 0 {
return nil
}
index = index - 1
return self.viewControllerAtIndex(index)
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int
{
return 2
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int
{
return thePageIndex
}
func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [AnyObject], transitionCompleted completed: Bool) {
if completed && finished {
var index = previousViewControllers.startIndex
segmentControl.selectedIndex = thePageIndex
// add exit3 gesture recognizer to the current index
setExitPaGestureAtViewControllerWithIndex(segmentControl.selectedIndex)
setGestureRecognizerToTableView()
//selectedLabelFrame
//setContentOffSetOfUIScrollView()
}
}
override func viewDidAppear(animated: Bool) {
//setContentOffSetOfUIScrollView() // in the first load of view you need to set segment scroll
setExitPaGestureAtViewControllerWithIndex(segmentControl.selectedIndex)
}
func setExitPaGestureAtViewControllerWithIndex(index: Int!){
self.viewControllerAtIndex(index)?.tableView.addGestureRecognizer(transtionManger.exitPanGesture3)
}
func setContentOffSetOfUIScrollView(){
println(segmentControl.items.count - 1)
if thePageIndex == 0 {
scrollView.setContentOffset(CGPointMake(0, 0), animated: true)
return
}else if thePageIndex == segmentControl.items.count - 1{
if selectedLabelFrame.frame.origin.x + selectedLabelFrame.frame.width > self.view.frame.width {
var sum = selectedLabelFrame.frame.origin.x + selectedLabelFrame.frame.width
var scroll = sum - self.view.frame.width
scrollView.setContentOffset(CGPointMake(scroll, 0), animated: true)
return
}else {
var sum = selectedLabelFrame.frame.origin.x + selectedLabelFrame.frame.width
var scroll = self.view.frame.width - sum
scrollView.setContentOffset(CGPointMake(scroll, 0), animated: true)
return
}
}
if selectedLabelFrame.frame.origin.x + selectedLabelFrame.frame.width > self.view.frame.width / 2 {
println(selectedLabelFrame.frame.origin.x)
println(selectedLabelFrame.frame.width)
println(self.view.frame.width)
println("more")
if thePageIndex == 1 {
var averageWidth = selectedLabelFrame.frame.width/2
var sum = selectedLabelFrame.frame.origin.x + averageWidth
var scroll = sum - self.view.frame.width/2
println("scroll is \(scroll)")
scrollView.setContentOffset(CGPointMake(scroll, 0), animated: true)
}
}else{
println(selectedLabelFrame.frame.origin.x)
println(selectedLabelFrame.frame.width)
println(self.view.frame.width)
println("less")
if thePageIndex == 1 {
var averageWidth = selectedLabelFrame.frame.width/2
var sum = selectedLabelFrame.frame.origin.x + averageWidth
var scroll = self.view.frame.width/2 - sum
println("scroll is \(scroll)")
scrollView.setContentOffset(CGPointMake(scroll, 0), animated: true)
}
}
}
}
In Swift, all instance variables have to be initialized at init (see the documentation) . Before you added the delegate, your superview's initializer was being called (because you hadn't overridden it) and you hadn't added any new instance variables, so this was fine. Now, however, your superview's implementation is being called but it is not initializing your variable, which is a compiler error.
Two options:
1) just initialize in your declaration: var delegate: MainPageLoaderViewControllerDelegate? = nil
2) override init and initialize your variable there.
I solved the problem but still dont understand how it is related to the problem "VC has not initilizers"
I changed the code:
var gestureRecognizerOfMainPageController: UIPanGestureRecognizer!
to
var gestureRecognizerOfMainPageController: UIPanGestureRecognizer?
You need to have a setter method for your variable
var delegate: MainPageLoaderViewControllerDelegate? {
didSet {
// Do whatever changes you wish to do
}
}
or have an init which instantiates the variable with an initial value, or initialize the variable with a value where you declare it.