iPhone app views logic - iphone

I have an iPhone app in development that requires three slides (views). The problem is, since I'm kinda new to this, I'm not sure what's the most logical way to approach this situation.
I was going to use a UINavigationController, but then I noticed that the UINavigationController is meant for hierarchical content, which means that it starts with a root controller which has the lowest level, and then views go child to child. But in my scenario, I have the main/root controller/view in the middle; and you can go to the left or right one, which would represent the middle one's children.
I could set the left view to be the root one, and quickly jump to the second/middle one; but this would be sort of a "hack" since I'm lying myself. Should I do that, or use a UITabBarController (haven't read too much about it), or something else?
Note that none of them will have their nav bar displayed since I want the navigation to be made through swipes.
Thanks!

You might want to try using the UIScroll in a paged mode and laying your views out on that (similar to how Photos works on the phone).

Related

How to create a custom UIViewController transition animation?

This question seems to get asked a lot but I have never found a definitive answer as to whether or not it's possible to have custom transitions the same way UIKit does.
I know you can do tricks like take a screenshot of the current view and the upcoming view, and then animate those while you change view controllers under the animation. However, this takes quite a bit of memory, as you have basically 2 full extra screens worth of drawing (because of the screenshots).
I'm looking for a more elegant way of presenting view controllers with a custom animation. Or, is there a more memory-efficient way of doing the above approach?
There are several ways to accomplish this, depending on how you want to transition, whether your controllers are embedded in a container controller, etc. In the simplest case, where you have a single controller, and you want to transition to another controller, you can do it with the following steps:
instantiate the new controller (lets call it B, and the original one A)
add B's view as a subview of the window (gotten from self.view.window)
set B's frame to be off screen in which ever direction you want or make its alpha 0, or make it have zero size, depending on what kind of transition you want.
do what ever transition you want with animateWithDuration:animations:completion:
remove A's view (in the completion block)
in the completion block, make B the root view controller of the window
Essentially you're having the system automatically retain and release, along with do whatever is happening below the calls rdelmar's answer outlined. Transitioning a view controller is just animating a view while having the system keep your controller in memory.
But, to answer more of your questions, UIView animations create duplicates and cache the images, too. (Btw, the system cache doesn't unload its memory, so avoid UIImage imageNamed.
You will probably want to code it yourself using a timer if you want efficiency, and drum up all the graphics tricks you can think of.
And never, ever trust iOS to work the same way it did the last version. Everything I said is subject to being wrong the same way iOS 6 broke retain on annotating, and the manuals stated iOS 3 animations will become obsolete (and are now replaced instead?) gah, just saying be careful with efficiency, it may be broken or updated in the somewhat distant future if you try it.

Best way to show a small view/dialog over an existing screen?

All my views/pages in apps so far have been full screen UIViewControllers that i push and pop from the stack.
I see some apps create a new view/window that appears about the 1/3 the size of the full screen on an iPad, containing tables of items to select or other UI elements. They are commonly used to allow users to filter the current view they were on.
Seeing them in apps, I guess that they are just adding a UIView to there current screen and change its frame depending on where on the screen they want it to appear.
Or am I wrong? Is there another/better way to do this?
I guess you are talking about UIPopovercontroller. There are several tutorials to build the same.check this. Hope that helps you.
It's a little unclear from your question what the view looks like.
If the view is "attached" to a UI element (has a little triangular arrow connecting it to, e.g., a button) and goes away if you tap outside it, then it's a view presented from a UIPopoverController.
If the view overlays everything and dims the content behind it, is likely a model view controller presented with a presentation style of ether page sheet or form sheet.
Both are common and easy to set up. See the class documentation I have linked.
In most cases, these are probably normal modal view controllers whose modalPresentationStyle property is set to either UIModalPresentationPageSheet or UIModalPresentationFormSheet.
Yes you can make your own UIViews and just add them as subviews. Another option for iPads specifically is with the UIPopoverController class.

Code design question using UIViewControllers (drawing PDFs page by page) - best practice?

I have written a little PDF viewer which is supposed to show PDFs page by page to reduce memory usage.
It consists of a PdfViewController which shows a specific page of the PDF (using UIScrollView, CATiledLayer).
Now the (maybe stupid) question is: if I want to show the next page (using a swipe gesture ot whatever), how would I do that? Should my controller handle it and update its views (which is a horror becaue CATiledLayer seems to crash as soon as you look at it :-)), or should there be an "outer" controller which generates a new PdfViewController for every page flip (the more flexible aproach)?
What is the best practice in these situations? Looking at UINavigationController, you're supposed to push a new UIViewController for every level. But there, all controllers being pushed may be different. In my case, all pages are using the same controller.
You likely shouldn't use the UINavigationController for that. In general, the UINavController should be used for drill-down operations, where you have a limited set of items to be pushed.
In your case, I think the best option is to use a large UIScrollView which will take care of the pagination and then just create a new UIView with the CATiledlayer inside.
I created for my app Quicklytics a PagedViewController class that does most of that for you. You basically create a PageDataSource that creates the UIViews for each page, and handle it over to the control. You may not use this exactly as is on your code, but it'll give you a good idea on where to go:
https://github.com/escoz/monotouch-controls/blob/master/UICatalog/PagedViewController.cs
Hope this helps you.
Here are two useful resources
Fast and Lean PDF Viewer for iPhone / iPad / iOs - tips and hints? collects a whole lot of information on displaying pdfs.
https://github.com/vfr/Reader a basic pdf reader for ios that does what you are trying to do.
In terms of whether to use nested UIViewControllers I would recommend against it, however if you do you should be aware that they will not handle rotation very well (I don't think they receive orientation change events) as well as viewDidAppear and other view lifecycle events, also make sure only to display modal view controllers from the root view controller otherwise they won't show properly (I had issues with them appearing in the wrong orientation in landscape, or in the wrong position).
In the app I built I used one UIViewController to manage the display of the pdf and I subclassed NSObject for any other "sub" controllers to make it more manageable. For example I had vertical scrolling as well as horizontal scrolling of pdf pages. My first attempt used nested UIViewControllers however I had issues with orientation till I rebuilt using controllers subclassed from NSObject for managing vertical slides.

Tabbar App with Paging between tabs

I've been struggling for about four days now trying to figure out how to implement the functionality I need. Basically I want to make a tabbar app that you can swipe back and forth between the tabs. Say I have 4 tabs. Would it make any sense just to create a scrollview that's 4 times as wide as the device, and load up 4 individual views side by side? Then I could use the tabbar delegate to simple tell which page to make visible? I could also use itemSelected to update the tab itself if a user swipes to a new page.
does this make sense / is it a good idea? I just need a quick yes or no answer before I spend another whole day pursuing something doomed to failure. Thank you very much for your help...
A page control may help you. Or you can combine navigation controller with tab view. ie use navigate your page on tapping tab buttons.
Whether it's a good idea or not aside, one way you could achieve this is to register a UIGestureRecognizer on the UIViewController in each tab, that when a swipe is detected, changes the tab depending on the direction of the swipe.
My initial idea seemed to work. I made a UIScrollView with a contentsize width of the four views I needed. I turned paging on, and used the UITabBar delegate to switch the itemSelected when a new page comes up. When someone presses a tab, I use the delegate
-(void)tabBar:(UITabBar *)myTab didSelectItem:(UITabBarItem *)item { }
to change the contentOffset of my scrollview. This may not be the best solutions in many cases, however, my app is simple enough that it works quite splendidly for me.
The original question is, how do you enable side-swipe functionality in a tab-bar app implmented using the Storyboard feature.
This question remains unanswered in my opinion.
The way I see it, either the Storyboard tool addresses the problem domain fully, or else who needs it? If you're forced to do something ridiculous (no offense) like making a 4-page wide view to work around the lack of scrolling, then that it is an argument against the Storyboard. If you're forced to add code to do something that is in the middle of the Storyboard target feature set, then it's going to be confusing to anyone who comes to the project later - some things are done via Storyboard, some are done in seemingly unrelated code.
Storyboard is a great visual development idea, but it needs to have its capability heaving ramped up and soon. There is only one answer really to this question; it should be, just add another behavior element. The fact that that is not working is a bug or a defect.

What's the correct way to represent a linear process in CocoaTouch (UIKit)?

I need to represent a linear process (think wizard) in an iPad app.
In principle I could use a UINavigationController and just keep pushing new controllers for each step of the process. But this seems rather inefficient since the process I'm modeling has no notion of navigating backwards so all previous views would pointlessly stay around and use up resources.
At the moment I keep adding and removing a subview to one "master" viewcontroller and basically swapping out the contents. This works but feels rather clunky and I hope there is some nicer way to achieve this.
Additionally there needs to be an animated transition between the views. (I have this working at the moment via beginAnimations / commitAnimations)
UPDATE:
To clarify my question: I'm aware that wizards usually have a back button. That's not what I'm building here.
The process that has to be shown possibly has a lot of steps (up to around 30-40 in some cases probably) so I really don't want to have 39 obsolete view controllers taking up ram.
Could you set the backBarButtonItem of each view controller's navigationItem to nil so that you don't show a back button?
You can extend uinavigationcontrollerdelegate and check every push event the current stack size. Then you can replace with a new reduced array that contains only the desired view controllers. By the way, if you implement a good memory management and release every resource on viewDidDisappear, i'm quite sure that it's not a matter for the os to manage a huge number of "empty" view controllers.
Hope it helps