I am writing an app in xCode 6.2 using storyboards and there is a need to present 2 different lists within a page view type setup (similar to Beat - Music Player).
The PageView controller is something I have never used before, so, I have looked at several examples and all deal with an Image View and changing the content of that based on an array. Whereas, what I am essentially trying to achieve is two separate ViewControllers being swiped between using the PageView controller. Is this even possible? If so, would anybody be able to point me in the right direction please?
the magic does by the two delegate methods viewControllerBeforeViewController and viewControllerAfterViewController ...
when you load the first viewcontroller to your pageviewcontroller with setViewControllers:#[theFirstViewController] the pageviewcontroller will ask the two delegates for the next and the previous vcs... you are responsible that the delegates returns the vcs you want to display, no matter what kind of vc you want to display...
Related
So I am trying to set up a UIPageViewController, and I have several UIViewControllers, but I want to set it up so I can animate(translate) a subview of my first view controller into the second view controller as it is transitioning. I have the UIPageViewController transition set to scroll. So that is what makes me believe this should be possible correct me if I am wrong. My google searches came up empty, but perhaps I am searching for the wrong thing.
Please point me in the right direction here in the form of a tut or how to conceptually think about this. My current thought is that I could have two identical views in different controllers, and as the user swipes the first view travels from left to right and then when I know it is at the edge I could have the other view take over perhaps using the prepareForSegue method.
Have a look at the Hero library (https://github.com/lkzhao/Hero) for custom animations between UIViewControllers.
Since a PageViewController doesn't really allow custom animation have a look at the AppleHomePageExample to see a example.
More viewcontroller images are showing up in default blue background instead on original images. I want to change them to original images and also want to increase UITableViewCell's height.
I have tried implementing tableview delegate methods on UITabbarController, but nothing working out.
Even moreNavigationController is also not changing.
1) Where do i have to write these custom methods viewDidLoad or viewWillAppear. Also shouldSelectViewController is not getting called. First time when i select a tabbar item it is being called and when i select the more item it is not getting called.
2) Where should i implement UITableView delegate methods.
My screen -
required screen -
A solution using swift is helpful. Thanks in advance.
I got the requirement working. The step wise procedure I followed is
Take a ViewController which extends UITabbarController.
Take an array with five elements exactly.(If more than five then default More functionality gets enabled).
First four tabs as required and fifth should be 'More' tab. With required tab images.
For 'More' tab create a View Controller which extends UITableView delegates and datasources. And implement respective methods of delegate and datasources.
Take an array of the Cells you want to display and display them.
Link this 'More' View Controller to the 'More' tab.
Change the images in tableview in cellForRowAtIndexPath method.
Run the application and check by selecting 'More' tab. This time it should show the changed UI.
When each cell should show different View Controllers on selecting the cells, then segue to different view controllers using the segues from ViewController (Not segue from the tablecell). Define a unique segue id for each segue and show the viewcontrollers based on switch or ifelse conditions in shouldSelectViewController using performSegueWithIdentifier.
Thanks #KKRocks for the valuable links.
There's some content to be unpacked here. I am not entirely certain I fully understand the question but I'll go ahead and reply partially as best I can.
ViewDidLoad and ViewWillAppear
You add code in viewDidLoad for initialization. This method will run when your view is originally loaded and unless you're instantiating the controller every time it will only run once ( in this case you dont because you're using the prebuilt tabbar system which takes care of that for you)
So I would add the styling code in viewDidLoad()
When a viewController is to be displayed, viewWillAppear() will be called. This will happen every time so if you need to perform repetitive tasks like network calls, restyling based on some other data, refreshing your tables, you should do it here.
Table methods
For doing whatever you need to do with a table you will most likely need both UITableViewDelegate and UITableViewDataSource to your view controller. Look up any UITableView tutorial online they're many very comprehensive and will explain how to add all the table methods you need in your viewController.
Sorry for the long and possibly confusing question. In this I have 2 main problems with my code, those being: 1- When I embed my viewControllers in a UINavigationController and add a bar button item, nothing appears, yet it appears when I add it to the pageViewController. Secondly, I am wondering if there is a way to do this differently and use one button on the pageView (which appears on all viewcontrollers in it) and just determine what the user was looking at when they pressed the button and are taken to another viewcontroller.
I am trying to build a page-based application, and I have set up the application with 7 view controllers (One for each day of the week). I then have an AddViewController, where users can add data to a certain day. I was wondering if there is a way to only use 1 addView linked to the NavBar on the PageViewController, as when I embed all other viewControllers and add a bar button, it does not show up.
With the pageViewController being embedded, this is what it looks like with a bar button on it.
This then leads to:
Which works well, however I am wanting to pass data to various arrays (one for each viewController), and I want to know which ViewController the user wishes to add to (based off what day they were on). Is there a way to determine this and then unwind to the viewController and append the right data to the right array or should I have one addView per dayViewController? If that is the case, I am coming across the issue whereby the bar button items do not appear on the viewControllers when they are embedded in a navigationController. It looks like this:
StoryBoard: (Example: MondayViewController)
The outcome is a missing barButton: (Keep in mind I changed the tint Colour to white so it would be visible)
I was wondering if anyone has the answer to either of my problems, and once again, thanks for taking the time to look at this array of questions in one problem.
Any suggestions are welcome !
Rowan,
You can do this:
Create an UINavigationViewController and then embed an UIPageViewController in it.
In the data source for the UIPageViewController implement these two methods:
- pageViewController:viewControllerBeforeViewController:
- pageViewController:viewControllerAfterViewController:
Here you will return the correct instance of your DayViewController for each position (or nil if you are on the first/last page). Your data model would also be set here.
Add your "Add" bar button to the navigation bar of the UIPageViewController and let it push your AddViewController. When pushing the AddViewController provide to it the info on which day is currently visible. You will probably need to keep track of this your self. Use the - pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted: method of the UIPageViewController delegate.
I am coming from a C# wpf background where you can have one ViewModel handling multiple Views. This is a great way to share data amongst unrelated views. However I can't figure out how to do the same thing in iOS, as you seem to need a Controller for each View.
What I am trying to achieve is to have a sign up sequence where the user populates 5 screens of data one by one. I was going to use a PageViewController for this and each click on Next would transfer them to the next page in the sequence. All the while, adding all their input data to a parent model object which stayed around for all five screens, at the end you can submit the whole lot to the database to sign up.
The only way I can see so far to do this is to create five separate ViewControllers, one for each screen of the sign up, and create the navigation logic to display them as you click through. However this a) seems overkill and b) means each subsequent screen and viewcontroller doesn't know about the information the user entered in the previous steps.
What is the correct way to do this in iOS?
You can do it in many ways. If you like to use UIPageViewController, you can actually have one view controller for all steps of the sign up process.
A main view controller would implement protocol UIPageViewControllerDataSource. It has two required methods, which return an instance of a content view controller. These instances can be of any UIViewController subclass, so you could have five separate view controller classes or you could have five instances of the same class.
Xcode has a project template "Page-Based Application". It might be a good sample code for you. There is one class DataViewController and it is instantiated for each page. If your case is really simple then this might be the best solution.
If you use multiple view controllers, you can pass data between them by overriding the method prepareForSegue(segue:sender:). The UIStoryboardSegue object has access to the destination view controller, you can cast it and set up the properties. (I am assuming you are using storyboards and segues.)
Another approach would be not to use UIPageViewController and implement the whole process within one view controller. There could be one view with five container subviews. Initially the first one would be shown, then the second one, and so on. This requires manual implementation of navigation between those steps, but gives a lot of flexibility. It's also more aligned with MVVM, because there is one-to-one mapping between a ViewModel and ViewController.
In general, iOS apps have lots of view controllers. It doesn't seem an overkill for me to use five in your case. It might be more code, but it's less complexity.
I have a little question, related to a UIPageViewController. I use Swift as language, but if someone is unfamiliar with this new language, I understand Obj-C code too. My problem is relatively simple to describe, but not so simple to solve. I have a UIPageViewController set up. At some point, if the user pushes the current page of the page controller to the bottom, the page should disappear (the current view controller removed). I've tried a couple of things already. Before I continue, I'll explain some of the mechanics of my UIPageViewController that may help for an easier answer:
the page controller does not swipe trough an array of pre-configured view controllers. At the beginning, it takes in just one view controller. The rest of view controllers are calculated while the user swipes, trough the data source methods:
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
...
}
and
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
...
}
Each of the view controllers added, is an instance of a custom view controller that takes in a index, which indicates the data that this view controller should load. The limit of the pages in the page controller is defined by a count of the items available for the custom view controllers to load.
I've tried just one thing, and it almost worked. I'm describing it now that you know my page controller mechanics:
I swipe the current page down and it (graphically) disappears
I'm removing the data element linked to the current (and recently "deleted") view controller from the folder where all the others are stored
I'm updating the count of the elements inside the folder
The only problem with this solution is that after all this I still need the user to swipe to see the updates... Let me explain: after the current view controller disappears , I still have a white canvas in front of me... Only after the user swipes to get to a new page, the two data source methods are executed and the updates go live. After the swipe, the blank canvas is not there anymore (if I swipe back) and all other controllers are shown correctly. I just need to do one simple thing: after the view controller disappears, I should automatically (programatically) swipe back to the view controller before, so that the two data source methods are called and everything is updated...
So at the end, maybe my question should me more like: "How do I programatically swipe back to the previous UIPageViewController page?"
Any help will be appreciated!!
You can use the setViewControllers:direction:animated:completion: method of your UIPageViewController. You can do this right after step 3 above. It's your choice as to whether to use the viewController for the data element before the one removed, or the one after.
You can use setViewControllers:direction:animated:completion: as documented here.