how to get current controllers in UIPageViewController - ipad

I am creating a book like iBook. I load data on UIWebView placed on contentviewcontroller. My problem is that user can go to any page through table of contents also can increase or decrase size or can highlight the text. My problem is to recognize on which UIWebView this is doing. or if user jump to page other page get populated with data automatically with next page. or On increase or decrease font size the data should be populated automatically. Main problem is I am not getting to retrieve the contents of different page programmatically an reload them.

I have created the pdf book reader from the leaves tutorial series. check out the link Leaves and leaves with mode also check the good one tutorial http://www.vfr.org/. the app loads pdf file at once and you can set your event of jump to page book mark page

I think ,You use dataSouce of pageViewController... and solve your Problem
- (UIViewController *)pageViewController:
(UIPageViewController *)pageViewController viewControllerBeforeViewController:
(UIViewController *)viewController
- (UIViewController *)pageViewController:
(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
how to use dataSouce of pageViewController ,for help see tutorial

Related

How to implement ViewController with CollectionView inside?

I am trying to implement a "profile" page in my app which is similar to Instagram profile page
But the problem I have is the Cell from UICollectionView below get loaded by -collectionView:cellForItemAtIndexPath
But it load every cells at once ,it does not just load the visible cell as it should. And this is because it is inside scroll view ,the make every cell loads immediately.
The image for cell will be sent from server via API and I want to do a loading when user scroll to 2/3 of page. And this can be done easily in UICollectionViewController.But I want to know how to do that in ViewController that contain collectionView in lower path.
Please help. I think using Header of CollectionView as an upper part of page might solve the problem. But I also want to implement that when user tap the button and then the display below change ( just like instagram page). So I am not sure what direction should I go . Should it be a custom container VC or something else ?
TIA
UICollectionView is very versatile. It can handle the entire view, including the upper part that pertains to the user's profile.The trick is to make use of a "supplementary view" in collection view terms (like a header view in table view terms).
I suggest that you throw away the scroll view and make the collection view do all the work for you. Just like you register classes for cells, register a view for the user profile portion of your UI using:
- (void)registerClass:(Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier
And respond to the datasource method:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
By answering the that user profile view.

UIPageViewController waiting for computing pages in webView

My project is an eBook-reader (ePub) with UIPageViewController holding webViews to show the pages. The pages are computed by loading a webView with a chapterFile and counting the pages the webView needs to display in webViewDidFinishLoad. This will be done for all chapterFiles in a delegate called trough webViewDidFinishLoad, where the next chapter will be loaded in a webView to compute the pages. On certain conditions, like turning from portrait to landscape with new textSize in portrait, the pageViewController is demanding a second page faster than the paging needs to finish.
PageViewController is calling
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
In this method I am calling another method "goToNextPage" to look if the next Page is a shift of the webViews viewPort or an new chapterFile to load. What I want is "goToNextPage" to wait for the paging to be done.
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController{
...
//paging is already in progress at this point (if needed )
//I want goToNextPage to wait for paging to be finished
[self goToNextPage];`
...
//loading newViewController with right page
return newViewController;
}
I don't know how to achieve this because of the delegate calls to wait for.
I have worked on a similar project. We found that it was necessary to calculate pages behind the scenes for performance. We have a web view sized the same as it would be in the UIPageViewController placed behind the UIPageViewController so that it is not visible (setting the view to hidden causes it to not lay out the web page). Then we cycle through each spine item calculating the page count and save the spine item index, current font size, and the page count for use later. In our case it was possible to provide some amount of navigation as pages are calculated (similar to iBooks) without preventing all navigation.
Once page counts are calculated, you have all of the information necessary to display any page at any point even if the current page is not yet complete in loading.
If font size or view size changes, page counts will need to be recalculated.
Another option could be to prevent page changes until the current spine item has finished calculating pages. You can accomplish that by returning nil from pageViewController:viewControllerAfterViewController: and pageViewController:viewControllerBeforeViewController: until your page count comes back. Pages will likely calculate fast enough that it will just appear that the page turn is rate limited.
One of the benefits to calculating the size of all spine items before-hand is that navigation by more than one page at a time becomes possible.
Either way you go, I do recommend rate limiting the page turn -- I have run into some issues with the web view crashing in setDeviceScaleFactor if pages are turned too quickly when in a UIPageViewController. The UIPageViewController will attempt to ask for new view controllers much faster than the device can keep up with creating and rendering UIWebViews if a user continually turns pages as fast as possible.

Images not loading FIRST time a UIWebView is used

My original plan was to use a split view controller to have a table view and a generic view beside it for an iPad app. Then I realized I could not use a split view controller as a child controller. So, I've been experimenting with using a table view controller instead, and I've got pretty good results so far. Essentially, I'm using the tableview's header view as a container for the various views I'll be using depending on which row is selected. The only unresolved issue is that images for a website are not displayed in the UIWebView the first time it is presented. If I tap another table row that displays a web view, it displays fine. And if I tap the original one again, it displays fine, too.
It doesn't matter which one I tap first. It's always the first one that doesn't display images. Instead of displaying the images, it displays the names of the image files.
When I tried the analogous thing with a split view controller, I didn't have this problem.
Any ideas what I should be looking for? Or is there something I need to be doing that I must not be doing?
If it matters, the page being loaded is just a thumbnail page on a remote server, created with Irfanview's HTML thumbnail page generator.
P.S. After further testing, it is really the very first presentation only that doesn't work as expected. By very first, I mean the first per app session. The UIWebview is presented as a subview of the table header. The tableview controller is presented as a popover from a button of another controller that is presented when a user taps an image. Even if I dismiss all these layers of controllers, etc., if I instantiate them again, the UIWebView displays properly.
This suggests possibly loading a dummy UIWebView before starting, but that seems kludgy.
I'm getting exactly one call to webViewDidStartLoad: and exactly one call to webViewDidFinishLoad: and no calls to webView:didFailLoadWithError:.
KLUDGE:
The kludge works. Here it is:
In my table view controller, I create a boolean property URLHasBeenRequested and set it to NO in viewDidLoad. Then I ask for a reload thus:
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
if (!self.URLHasBeenRequested) {
//On first pass, try a second request.
[webView loadRequest:webView.request];
self.URLHasBeenRequested = YES;//Set this flag so a duplicate request happens only the first time.
}
}
I suspect this has more to do with the way the UITableView is loading the header and trying to allocate memory during that process, than with the UIWebView itself. For whatever reason, the UIWebView's loading seems to be getting interrupted while the rendering of the UITableView is still finishing ( just a guess ).
One thing you might try would be to go ahead and setup your table header by adding the UIWebView subview, but not calling "loadRequest" right away. You could, for example, wait until the rest of the visible cells of the table have been loaded, and then load the header view last. You can detect when that occurs like this:
-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if([indexPath row] == ((NSIndexPath*)[[tableView indexPathsForVisibleRows] lastObject]).row){
[webView loadRequest:webView.request];
}
}
This is, admittedly, also a somewhat kludgy workaround, but at least you're not having the UIWebView load the content twice. I also haven't tested this myself, and without seeing your actual table loading code, it's hard to say if the root of the problem lies somewhere else, but let me know if this works!

ios/iphone sdk form management best practices

I'm working on an iPhone app that will have involve a lot of forms. Currently I have a ViewController class for each settings page which has an UITableView loaded with possible settings. When someone clicks on a setting they are taken taken to a new view to enter the form value, or allowed to enter things in place.
What's the best way to keep things DRY? What pieces of this implementation could be implemented once and re-used?
When someone clicks on a settings option which goes to a new view how can I create this view and add a text field according to the data type (uitextfield or picker or something else) in code?
You can programmatically:
create view hierarchy
UIButton
UILabel
You get the idea.
However, I would recommend getting your logic working for a few of the cases, and then it should become obvious what parts are redundant as you find yourself typing in the same thing over and over. At that point, refactor to get the redundant code into a re-usable form.
HTH.
If you have a tableView, the flow is to create the viewController of the selected settings in the didSelectCell method of your tableView delegate and to push it through the current viewController's navigation controller.
here's a sample:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.navigationController pushViewController:[self settingsViewControllerAtIndexPath:indexPath] animated:YES];
}
so you'll have to implement the method:
- (UIViewController*)settingsViewControllerAtIndexPath:(NSIndexPath *)indexPath;
wich will return the viewController managing the settings associated with the selected row of your root tableView.
If your forms are pretty statics, you should consider using a xib in order to minimize the amount of code needed. it isn't a perfect answer to your "how to keep DRY" but it's neat enough ;)
Good luck.

Appallingly dim UITableView question

I'm sure this is a very dumb question (or one that reveals terrifying levels of ignorance), but as an iOS newbie I'm trying to lash an app together as a favour to a friend - and any help would be greatly appreciated.
I have a multi-tab app, which is running fine. On the last tab, I'd like have a table view giving access to a variety of pdf or html files, to be stored in the bundle (and added to in future updates). Basically I want it so that if the user selects "Story pdf" in the table view, it loads up NextView with a UIWebView showing said pdf. If they select "Info table" then that UIWebView loads up info.html instead. It'll only ever be those two file types.
I've got the table view running and a new view ready and waiting, I just can't work out the next bit. Should I store names/file types in a plist? Is NSFileManager my friend here? If anyone has any pointers or knows of a sample project or chunk of code that does something similar, it would be fantastic.
Thanks for listening :-)
Your UITableView will have a delegate (possibly your view controller) and you need to implement this method from the UITableViewDelegate protocol:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
you get the indexPath of the selected cell and then you work out what to do next.

Resources