Set a UIViewController inside a switch/case statement using Swift - swift

I am trying to load a view based on a button press. I thought I could do something like this below where I defined a generic UIViewController and then set it to a specific UIViewController inside a switch/case statement but it apparently doesn't work this way. What am I doing wrong?
#objc func menuButton(sender: UIButton) {
var view: UIViewController!
switch sender.tag {
case 0:
view = MenuViewController()
view.menuType = .Account
case 1:
view = MenuViewController()
view.menuType = .Sync
case 2:
view = AuthViewController()
view.menuType = .Auth
default: break
}
self.navigationController?.pushViewController(view, animated: true)
}

If I'm not mistaken, the compiler should give an error saying:
Value of type 'UIViewController' has no member 'menuType'
Here you have a couple of options to solve this:
Solution 1
Use casting
#objc func menuButton(sender: UIButton) {
var view: UIViewController!
switch sender.tag {
case 0:
view = MenuViewController()
(view as? MenuViewController())?.menuType = .Account
case 1:
view = MenuViewController()
(view as? MenuViewController())?.menuType = .Sync
case 2:
view = AuthViewController()
(view as? AuthViewController())?.menuType = .Auth
default: break
}
self.navigationController?.pushViewController(view, animated: true)
}
Solution 2
Create a protocol MenuProtocol
protocol MenuProtocol {
var menuType: MenuType { get set }
}
and make the MenuViewController and AuthViewController implement that protocol. Then you can do the following:
#objc func menuButton(sender: UIButton) {
var view: (UIViewController & MenuProtocol)!
switch sender.tag {
case 0:
view = MenuViewController()
view.menuType = .Account
case 1:
view = MenuViewController()
view.menuType = .Sync
case 2:
view = AuthViewController()
view.menuType = .Auth
default: break
}
self.navigationController?.pushViewController(view, animated: true)
}

Related

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.

Why is my UIViewController not showing up in my popup card?

I wanted to create a pop up for one of my UIViewController and found this repo on GitHub.
It is working fine with my InfoViewController which only has 4 UILabels (I think this might be the problem that it is not showing up when you use reusable cells)
But somehow it is not working with my StructureNavigationListViewController and I do not know why.
I call the didTapCategory method in my MainViewController where the StructureNavigationController should pop up but I only see the dimming view (which is weird cause the tap recognizer and pan gestures are working fine but no content is showing up)
In my MainViewController I set up the popup like before:
#IBAction func didTapCategory(_ sender: UIBarButtonItem) {
let popupContent = StructureNavigationListViewController.create()
let cardpopUp = SBCardPopupViewController(contentViewController: popupContent)
cardpopUp.show(onViewController: self)
}
In my StructureNavigationListViewController I set up the table view and the pop up:
public var popupViewController: SBCardPopupViewController?
public var allowsTapToDismissPopupCard: Bool = true
public var allowsSwipeToDismissPopupCard: Bool = true
static func create() -> UIViewController {
let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "StructureNavigationListViewController") as! StructureNavigationListViewController
return vc
}
#IBOutlet var tableView: UITableView!
var structures = Variable<[Structure]>([])
public var treeSource: StructureTreeSource?
let disposeBag = DisposeBag()
var depthDictionary : [String : Int] = [:]
public override func viewDidLoad() {
structures.asObservable()
.bind(to:tableView.rx.items) {(tableView, row, structure) in
let cell = tableView.dequeueReusableCell(withIdentifier: "StructureNavigationCell", for: IndexPath(row: row, section: 0)) as! StructureNavigationCell
cell.structureLabel.text = structure.name
cell.spacingViewWidthConstraint.constant = 20 * CGFloat(self.depthDictionary[structure.id]!)
return cell
}.disposed(by:disposeBag)
_ = tableView.rx.modelSelected(Structure.self).subscribe(onNext: { structure in
let storyBoard = UIStoryboard(name:"Main", bundle:nil)
let plansViewCtrl = storyBoard.instantiateViewController(withIdentifier: "PlansViewController2") as! PlansViewController2
self.treeSource?.select(structure)
plansViewCtrl.treeSource = self.treeSource
plansViewCtrl.navigationItem.title = structure.name
self.show(plansViewCtrl, sender: self)
if let mainVC = self.parent as? ProjectOverViewTabController2 {
mainVC.addChildView(viewController: plansViewCtrl, in: mainVC.scrollView)
}
})
showList()
}
func showList() {
if treeSource == nil {
treeSource = StructureTreeSource(projectId:GlobalState.selectedProjectId!)
}
//The following piece of code achieves the correct order of structures and their substructures.
//It is extremely bad designed and rather expensive with lots of structures and should
//therefore be refactored!
if let strctrs = getStructures() {
var sortedStructures : [Structure] = []
while(sortedStructures.count != strctrs.count) {
for strct in strctrs {
if let _ = sortedStructures.index(of: strct) {
continue
} else {
depthDictionary[strct.id] = getDepthOfNode(structure: strct, depth: 1)
if let structures = getStructures() {
if let parent = structures.first(where: {$0.id == strct.parentId}) {
if let index = sortedStructures.index(of: parent) {
sortedStructures.insert(strct, at: index+1)
}
} else {
sortedStructures.insert(strct, at: 0)
}
}
}
}
}
structures.value = sortedStructures
tableView.reloadData()
}
}
func getDepthOfNode(structure: Structure, depth: Int) -> Int {
if(structure.parentId == nil || structure.parentId == "") {
return depth
} else {
if let structures = getStructures() {
if let parent = structures.first(where: {$0.id == structure.parentId}) {
return getDepthOfNode(structure: parent, depth: depth + 1)
}
}
}
return -1
}
private func getStructures() -> Results<Structure>? {
do {
if let projectId = GlobalState.selectedProjectId {
return try Structure.db.by(projectId: projectId)
}
} catch { Log.db.error(error: error) }
return nil
}
}
Lot of code here. Sorry..
Is it because I call the create() method after the viewDidLoad() dequeues the cells?
It's hard to tell what is the problem, since you left no information about where didTapCategory is supposed to be called, but maybe it has something to do with your modelSelected subscription being prematurely released?
Edit:
As posted here: https://stackoverflow.com/a/28896452/11851832 if your custom cell is built with Interface Builder then you should register the Nib, not the class:
tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCellIdentifier")

how to init() a swift view controller properly?

I'm attempting to initialize this ViewController class. I am not using the MVC design strategy so ignore the bad conventions used (if any).
How do I initialize this class properly?
Error: 'required' initializer 'init(coder:)' must be provided by subclass of 'UIViewController'
Context: This is a calculator app that when any of the buttons are pressed. It will go find the senders title and simply put if one of the three vars are nil, it will store it in that optional.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBOutlet weak var answerLabel: UILabel!
//global vars for all funcs
var selection1: Int? {
didSet { answerLabel.text = String(selection1!) }
}
var selection2: String? {
didSet { answerLabel.text = selection2! }
}
var selection3: Int? {
didSet { answerLabel.text = String(selection3!) }
}
var answer: Int {
didSet { answerLabel.text = String(answer) }
}
init() {
}
#IBAction func touchButton(_ sender: UIButton) {
if selection1 == nil {
selection1 = Int(sender.currentTitle!)
print("Selection set in first pos.")
} else if selection2 == nil {
selection2 = sender.currentTitle
} else if selection3 == nil {
selection3 = Int(sender.currentTitle!)
} else {
calculate(firstNum: selection1!, operation: selection2!, secondNum: selection3!)
}
}
func calculate(firstNum: Int, operation: String, secondNum: Int) {
switch operation {
case "+":
answer = firstNum + secondNum
case "-":
answer = firstNum - secondNum
case "x":
answer = firstNum * secondNum
case "/":
answer = firstNum / secondNum
default:
answerLabel.text = "Something went wrong!"
}
}
}
Initialization depends on a couple of condition.
If you are using storyboard, you can just remove the init and your VC will have default initializer. Make sure either all of your properties have default value or they are optional.
If you are using xib or just creating view programmatically you can have custom convenience initializer where you pass some extra data this way.
class MyViewController: ViewController {
var answer: Int
convenience init(answer: Int) {
self.init()
self.answer = answer
// Do other setup
}
}
Your controller is being instantiated from the storyboard. A safe place to configure initial views is during the controller's call to viewDidLoad, ie:
override func viewDidLoad() {
super.viewDidLoad()
// configure your views and subviews here
}

How to make Images clickable in a UIPageViewController?

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

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.