Multiple UIViewControllers inside UIPageViewController in Swift - swift

can not find an explanation of how to develop an app that is developed with 3 ViewControllers within a PageView. Somebody know any tutorial?

Is this what you're looking for?
http://shrikar.com/blog/2015/01/17/ios-swift-tutorial-uipageviewcontroller-as-user-onboarding-tool/

I created a Swift tutorial on how to use UIPageViewController with three View Controllers.
It includes two sample projects -- a starter project on which to walk through the tutorial, and a final project to check your answer.
http://www.thorntech.com/2015/08/need-to-create-an-onboarding-flow-for-your-mobile-app-heres-how-to-do-it-using-uipageviewcontroller-in-swift/
But here's the gist of using UIPageViewController:
In viewDidLoad, use setViewControllers and pass in a single View Controller instantiated via Storyboard ID. It takes an array, but you will always pass in just one VC
You can't wire the DataSource using the Storyboard, so you have to do dataSource = self
Now that you're the DataSource, you need to implement viewControllerBeforeViewController and viewControllerAfterViewController.
For viewControllerAfterViewController, figure out which is the current page like so: if viewController.isKindOfClass(PageOneClassName) { }
Once you know the current page, return whatever comes next by instantiating a VC from the Storyboard. If it's the last page, just return nil
For viewControllerBeforeViewController, just return the previous page. Again, return nil if you're at the beginning.

Related

How to pass data from child to second parent view controller without using NotificationCenter in swift

My situation is, I have a navigation controller(nv) with root view controller(rootVC). And another view controller(firstChildVC) pushed to rootVC. And one more view controller(secondChildVC) pushed to firstChildVC. (In real case, I have more subsequence child view controllers) After API calls and some calculations in secondChildVC, I need to pass some data from secondChildVC back to rootVC and popToRootViewController to show some data.
I don't think delegate and closures are good choice in this case. The only thing I could come up with is using NotificationCenter. Just what to know is there any better way to do this?
Thank you in advance.
You can try this inside the SecondVC then pop to root
if let root = self.navigationController?.viewControllers.first as? RootVC {
root.sendData(data)
}
I think there are three valid ways to do this without overly tightly coupling things:
Notification Center
Closures
Delegate pattern
The right way is not a simple choice. It really depends on the details. You mention making an API call. Assuming this is all managed in a separate object and not coded into your view controller code, I would have the object making the API call post a notification and the view controllers can each listen and do whatever is appropriate.
There are two other ways to do this, one is using Delegates another one is Closures

swift - call code from another view controller

I'm using a library that manages the swiping between view controllers.
It seems like the only way that I can use a button in one of my view controller to navigate to the other is by calling a specific method from the view controller that manages the swiping feature.
It there any way to call a method in a different view controller?
Thank you
There are many ways to communicate between view controllers. One of the most common patterns for doing so on iOS is the delegate pattern. One view controller holds a reference to the other and the delegate conforms to a protocol. The protocol is a set of methods that the first view controller can call when specific events happen. I would try setting up a protocol and have one of your view controllers be a delegate to the other
If you take a look at the code that is hosted on GitHub you can see that the page controller is exposed from the EZSwipeController class. So given that you subclass EZSwipeController (or maintain a reference somewhere), you can now access the pageViewController property of it and scroll to a given page.
If you subclass:
class MyVC : EZSwipeController{
func buttonTapped(){ /* use self.pageViewController to "page" */ }
}
Weirdly, I have never personally worked with UIPageViewController, and as far as I can tell there is no easy way to scroll to a page in an easy fashion.
I haven't personally tried it (I usually validate my answers before posting), but you should be able to pull it off. If you don't have a reference to the view controller you need to get it (let me know if that is the core issue).
There is a question on SO that seems to enjoy some popularity regarding UIPageViewController paging:
UIPageViewController, how do I correctly jump to a specific page without messing up the order specified by the data source?
And from Apple docs:
I would also encourage you to look at the code inside of the EZSwipeController repo, where you can find a non-exposed method that does the scrolling:
#objc private func clickedLeftButton() {
let currentIndex = stackPageVC.indexOf(currentStackVC)!
datasource?.clickedLeftButtonFromPageIndex?(currentIndex)
let shouldDisableSwipe = datasource?.disableSwipingForLeftButtonAtPageIndex?(currentIndex) ?? false
if shouldDisableSwipe {
return
}
if currentStackVC == stackPageVC.first {
return
}
currentStackVC = stackPageVC[currentIndex - 1]
pageViewController.setViewControllers([currentStackVC], direction: UIPageViewControllerNavigationDirection.Reverse, animated: true, completion: nil)
}
The "key" line is this one:
pageViewController.setViewControllers([currentStackVC], direction: UIPageViewControllerNavigationDirection.Reverse, animated: true, completion: nil)
I think EZSwipeController also exposes the view controllers contained in the pageViewController which is a property called stackVC, which is an array of the view controllers contained in the page view controller.
I assume with this knowledge you should be able to page to a given page, despite seeming a little "hacky" (IMHO the developers should have exposed paging logic from the get-go).
My advice for you after all this is simple:
Try to roll it yourself. This is not a huge undertaking and you maintain full control over what's accessible and how you want to work with it. The EZSwipeController class is quite small, so there is not a whole lot of code you'd have to write for your own solution. You could also go ahead and fork the repo and modify/use it to your liking.
I hope that helps. If you have any further questions or if something is unclear, I'd be ready to help you out.

Connect action of a XIB loaded from a custom class to a storyboard

I'm trying to create a reusable component to display some photo collection.
The basic flow is the following :
First view : View. It contains my so called library, designed programmatically and loaded from storyboard by assigning a custom class
I take a photo in a modal view, openend from the 'take picture' button
Once the photo is saved on disk, I ask PhotoLib to create a new PhotoCell from the photo path
I would like my PhotoCell to be touch enabled so when I tap it, it opens the second view in a modal way, but from what I read I cannot do this from my PhotoCell or the UIImageView inside (not a controller).
So how can I do ? View is embedded in a NavigationController, even if not shown in the screenshots below.
Thank you !
If you create Photocell in photolib, then photolib should implementing delegate methods from photocell. But photolib itself is not rootviewcontroller, so it should declare delegate methods itself, and the containing view should implement it.
Basically you pass Photocell from itself to Photolib (which implements delegate method
-(void) openPhotoCell:(Photocell*)cell
{
[self.delegate openPhotocell:(Photocell*)cell];
}
, then it passes it to View, which in its turn opens it.
It may seem like pulling a tooth from an ear, but actually it's quite working and if you write good self-explanatory code, it's not a problem. I'm currently working on some big project with tens views and controllers and it works pretty good and nobody has problem with that.
If you have more layers, then maybe you should look into NSNotification.
Hope it helped, I'd be glad to explain more.
UPD:
Links:
about delegates in cocoa fundamentals guide
delegation pattern in wikipedia

Xcode 4.2 & Storyboard, how to pass data between views? Existing code error

I'm trying to learn how to pass data between views. Say set a label in the second view from text entered into a text field on the first view. I basically have tried making a string in the second view and then when switching from the first view to the second I set a string in the second view. Then when the second view loads its sets the text of a label to the same string. I NSLog right before and after the transition, before its fine, but when the second view loads it string gets erased. I'm not sure why this isn't working. Here is my project: http://www.mediafire.com/?83s88z5d06hhqb5
Thanks!
-Shredder2794
From my book (http://www.apeth.com/iOSBook/ch19.html#_storyboards):
Before a segue is performed, the source view controller is sent prepareForSegue:sender:. The view controller can work out what segue is being triggered by examining the segue’s identifier and destinationViewController properties, and the sender is the interface object that was tapped to trigger to the segue (or, if performSegueWithIdentifier:sender: was called in code, whatever object was supplied as the sender: argument). This is the moment when the source view controller and the destination view controller meet; the source view controller can thus perform configurations on the destination view controller, hand it data, and so forth.
(Of course another solution is "don't use a storyboard". Then the first view controller creates the second and can hand it data then and there.)
The reverse problem is much trickier; look at the Utility Application template for an example of how to use the delegate pattern.
StoryBoards are ready made things where you can reduce a lot of code you write.So consider controller A & B on storyboard.
Now for passing data From A to B you can connect them with a segue name its identifier and then you can use delegate methods in A as:
//This method gets called before transition from A to B.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"THE IDENTIFIER YOU NAMED"])
{
id *objectOfController_B = [segue destinationViewController];.
objectOfController_B.lblTextDisplayOfA = //Something...
}
}
Now You can Explicitly transition it by using button in controller A.
- (IBAction)buttonPressed:(id)sender
{
[self performSegueWithIdentifier:#"THE IDENTIFIER YOU NAMED" sender:sender];
}
So I guess you can try experimenting on this and you will get it how and when transition occurs with segue.
Hope this helps.
There appear to be more than a few things to explain. I think working through a few tutorials will give you the answers you need. See http://www.raywenderlich.com/tutorials
i've asked more or less the same question a few weeks/month ago. there were some very good answers, especially the one from zoul, who built a demo project that will show you how to create a factory pattern application that will provide the views with the needed objects.
my question can be found here: iOS: Initialise object at start of application for all controllers to use and have a look at the answer from 'zoul'. it got me through this problem =)
good luck trying it out =)
sebastian
I spent "countless hours" my self trying to find a way to pass data and understand delegates with no comprehension and very little success. This video did something that all the other references I checked didn't do : keep it as simple as possible while clearly showing what was needed. Thank you so very much Mr Rob Smythe. http://www.youtube.com/watch?v=XZWT0IV8FrI
Have a look at this: http://iosdevelopertips.com/objective-c/the-basics-of-protocols-and-delegates.html
Delegate pattern is a common way to achieve what you are trying to do.

iphone - communicate with previous viewcontroller after segue

Is it possible to communicate with a viewcontroller after a segue switched to another viewcontroller?
I want to know, because I need data from a viewcontroller passed on to the next viewcontroller,
but I just can't figure out how to get data from one viewcontroller to another, as they have no unique names or something which I can use to communicate with.
So can someone tell me:
If it is possible to communicate between viewcontrollers, and if possible, how?
Usually you do it the other way around, pushing values from the source to the destination. If you implement prepareForSegue in the view controller that is going to be segue'd out, you can use
[segue destinationViewController]
to get a reference to the destination view controller.
Then you can set any values in that controller that are needed using properties on that controller before it segues in.
I have searched for tutorials about making a MVC based iPhone app, but without success
Goto ITunesU and look for Paul Hegartys "iPad and iPhone Application DEvelopment" from stanford university
very good!
try the views presentingViewController property.
A typical OOP pattern is to create yet another object, a Model object (MVC paradigm), connect all the view controllers that need to communicate with this Model object, and pass any shared state or variables by setting and getting properties in this Model object. A common shortcut for very small apps is to use the App Delegate as a Model object, as any other controller can get a reference to the app delegate. But this shortcut is not very extensible to larger or reusable code.