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.
Related
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.
i'm new to the ios sdk and i'm developing my first app. i need to implement a curl transition between multiple views; giving the user the impression they are reading a book. the documentation only talks about doing it between two views in a single view controller. like i said i need to implement this with a stack of several views. do i need to use more than 1 view controller? if so how? or do i have to use 1 view controller but use say 10 views in a stack? again how would i go about doing this.
would greatly appreciate your help.
Ideally, you would use only two views for this: one for the view being animated (to an offscreen position), and one for the view underneath. To handle multiple flips, you would animate the top view to its offscreen position, then fill it with the data for the page underneath the current page and then insert it underneath the current page. For the subsequent flip, you would animate the current off the screen, etc.
You could alternatively use a number of views that matches the total number of pages you want to display. This might make your coding simpler, but it would eat up a lot more memory.
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.
I'm writing a simple iPhone app which lets a user access a series of calculators. It consists of the following:
UITableViewController (RootViewController), with the list of calculators.
UIViewController + UIScrollView (UniversalScroller), which represents an empty scroll view - and has a 'displayedViewController' property.
UIViewController (Calculators 1-9), each of which contains a view with controls that represents a particular calculator. Each calculator takes 3-5 values via UITextFields and UISliders, and has a 'calculate' button. They can potentially be taller than 460px(iPhone screen height).
The idea is:
User taps on a particular menu item in the RootViewController. This loads and inits UniversalScroller, ALSO loads and inits the UIViewcontroller for the particular calculator that was selected, sets the displayedViewController property of UniversalScroller to the newly loaded calculator UIViewcontroller, and pushes the UniversalScroller to the front.
When the UniversalScroller hits its 'viewDidLoad' event, it sets its contentSize to the view frame size of its 'displayedViewController' object. It then adds the displayedViewController's view as a subview to itself, and sets its own title to equal that of the displayedViewController. It now displays the calculator, along with the correct title, in a scrollable form.
Conceptually (and currently; this stuff has all been implemented already), this works great - I can design the calculators how I see fit, as tall as they end up being, and they will automatically be accommodated and displayed in an appropriately configured UIScrollView. However, there is one problem:
The main reason I wanted to display things in a UIScrollView was so that, when the on-screen-keyboard appeared, I could shift the view up to focus on the control that is currently being edited. To do this, I need access to the UniversalScroller object that is holding the current calculator's view. On the beganEditing: event of each control, I intended to use the [UniversalScroller.view scrollRectToVisible: animated:] method to move focus to the correct control. However, I am having trouble accessing the UniversalScroller. I tried assigning a reference to it as a property of each calculator UIViewController, but did't seem to have much luck. I've read about using Delegates but have had trouble working out exactly how they work.
I'm looking for one of three things:
Some explanation of how I can access the methods of a UIScrollView from a UIViewController whose view is contained within it.
or
Confirmation of my suspicions that making users scroll on a data entry form is bad, and I should just abandon scrollviews altogether and move the view up and down to the relevant position when the keyboard appears, then back when it disappears.
or
Some pointers on how I could go about redesigning the calculators (which are basically simple data entry forms using labels, sliders and textfields) to be contained within UITableViewCells (presumably in a UITableView, which I understand is a scrollview deep down) - I read a post on SO saying that that's a more pleasing way to make a data entry form, but I couldn't find any examples of that online. Screenshots would be nice. Anything to make my app more usable and naturally 'iPhone-like', since shuffling labels and textboxes around makes me feel like I am building a winforms app!
I've only recently started with this platform and language, and despite being largely an Apple skeptic I definitely see the beauty in the way that it works. Help me solve this problem and I might fall in love completely.
Dan
If you have the particular calculator view, you should be able to get to the scroll view via the superview property (though there might be more than one intermediate view, so you might need the superview of the superview).
I have been facing the same nested UIScrollView problem for long time.I tried some open source codes like Scrolling madness ,three-20 and others but all fails finaly.I am trying to make a photo Viewer application same as iPhone.For that I have created the structure like this:-
1)one View controller.
2)on view of view controller one UIScrollView (i.e inner/parent scroll view) as a child.
3)on inner/parent scroll view number of child scroll views(i.e. outer/child scroll views) ,each represents one page of photos application.
4)On each scroll view one image View on which i am displaying my image.
So what I want is when user scrolls the outer scroll view it should scroll horizontally with all the child views so I will get the look and feel of paging in photos application.Also when user is on one specific image(i.e. child/outer scroll view) he should be able to zoom in/out,swipes and perform single/double tapping.I was able to make it work in sdk 2.1,but it dosnt work since sdk 3.0.Please tell me the idea behind your project.Means which scroll view you are subclassing ,in which view to detect touches.How this completely child - parent relation should be.
If possible provide any sample code also.
There is a WWDC session from 2010 that deals with this very issue.
Here's the short of it:
You need a single scroll view that is paginated and scrolls horizontally. Each "page" of that scroll view is another scroll view containing a photo.
First, it looks like you want to subclass UIScrollView? Every interaction method you need is provided for you in either the delegate callbacks or the touch methods. (Many of Apple's more advanced classes, such as UIScrollView, react poorly to subclassing.)
Second, it sounds like you have a first responder problem. IOW, your innermost scrollview isn't getting the first crack at the touch events.
Andrew
I also struggled with this for a long time trying samples you mentioned. I could finally figure it out with the samples provided by apple (iphone dev center).
http://developer.apple.com/iphone/library/samplecode/Scrolling/Introduction/Intro.html
http://developer.apple.com/iphone/library/samplecode/ScrollViewSuite/Introduction/Intro.html
The first one is pretty basic and probably what u already have. The second one is all about zooming, etc. Just study these and the samples you already have, I think you will be able to figure it out. On specific topics just come back here search for answers or post another question.
EDIT: I forgot this one check out these examples by Andrey Tarantsov hosted on github. This is what you want... http://github.com/andreyvit/ScrollingMadness