PDFKit: How to move current page in PDFView to a specific offset - ios

Assuming there is only one page in the PDF.
What I am trying to achieve: Save Zoom and offset of a PDFPage currently being viewed and show the page at exact same offset and zoom level when user comes back to that page.
What I have achieved: Calculated the offset and zoom and on page reload, successfully shown saved zoom level of page. Iam unable to set the offset.
Tried using following methods, but no effect.
1)
[_pdfView goToRect:rect onPage:[_pdfView.document pageAtIndex: page.unsignedLongValue ]];
2)
PDFDestination *destination = [_pdfView.currentDestination initWithPage:[_pdfView.document pageAtIndex: page.unsignedLongValue ] atPoint:viewPoint];
[_pdfView goToDestination:destination];

I was able to accomplish this using goToRect. I think there are issues with goToDestination. It always navigates to a different location than I pass into it.
Here's what I do to save the location when exiting the pdf (please note that I translated this code from Swift and haven't tested in Objective C):
CGFloat savedScaleFactor = _pdfView.scaleFactor;
//I use this to find the first page shown in my view. If you only have one page,
//you can just use currentPage
PDFPage *page = [_pdfView pageForPoint:CGPointZero nearest:YES];
CGRect savedRect = [_pdfView convertRect:_pdfView.bounds toPage:page];
NSInteger savedIndex = [_pdfView.document indexForPage:page];
Then to restore the location:
_pdfView.scaleFactor = savedScaleFactor;
PDFPage *page = [_pdfView.document pageAtIndex:savedIndex];
[_pdfView goToRect:savedRect onPage:page];

Related

MapBox get visibleCoordinateBounds in a CGRect

I'm working on an iOS app with a MapBox map.
I'm displaying MGLAnnotations but I only want to create the annotations that can be seen on the screen at a current moment.
Problem is : I have a UIView on the bottom of my screen so the bounds I get with mapView.visibleCoordinateBounds function is not really accurate because I can't see the bottom of my map.
I can't just resize my map because the bottom view I talked about doesn't cover the entire map, we still see parts of the map behind the bottom view.
So my question is, how can I get the visibleCoordinateBounds for a CGRect over my MapView ?
My current solution works only for the entire map view bounds and not the bounds of the CGRect area I want to display the annotations :
if ((mapView.visibleCoordinateBounds.sw).latitude...(mapView.visibleCoordinateBounds.ne).latitude ~= latX && (mapView.visibleCoordinateBounds.sw).longitude...(mapView.visibleCoordinateBounds.ne).longitude ~= lngY) {
print("VISIBLE")
}
Thanks
I finally found a way to do it.
I just calculate the percentage of my mapview hidden by the bottom view and I minus this number to the south latitude :
var valueToRemoveBottom = (mapView.visibleCoordinateBounds.ne).latitude - (mapView.visibleCoordinateBounds.sw).latitude
let percentageUsedByBottom = (bottomView.frame.height * 100 / mapView.frame.height) / 100
valueToRemoveBottom = valueToRemoveBottom * Double(percentageUsedByBottom)
if (((mapView.visibleCoordinateBounds.sw).latitude + valueToRemoveBottom)...((mapView.visibleCoordinateBounds.ne).latitude) ~= latX && (mapView.visibleCoordinateBounds.sw).longitude...(mapView.visibleCoordinateBounds.ne).longitude ~= lngY) {
// visible
}

Detecting Page Changes in pdf using WebView in iOS Swift

I'm displaying a pdf stored in a Document directory in a WebView, i want to detect the changes of the pages within the pdf. I searched about it and got to know about the methods goBack() and goForward() but it didn't work for me, i think they are for switching between the files in webView but i want to detect the page switching within a current loaded pdf file. i didn't have a code for this to show as i'm still trying to figure it out. any sample code with an explanation will be really helpful. Thanks.
For this you have to scrollView to navigate particular position of page, like below.
let selectedPage: CGFloat = 2; // i.e. Go to page 5
let pageHeight: CGFloat = 1000.0; // i.e. Height of PDF page = 1000 px;
let y: CGFloat = pageHeight * selectedPage;
let pageOffset = CGPoint(x: 0, y: y)
self.webView.scrollView.setContentOffset(pageOffset, animated: true)

Moving a view in viewDidAppear?

I've got a view that I'm wanting to have in a specific area of the screen based on a value.
I'm trying to keep the view's location the same when a user comes back to the screen after leaving, so I'm passing around a variable of "currentSearch" , and in viewDidAppear I'm checking that value and trying to set the location accordingly.
if currentSearch == "new" {
self.menuBar.center.x = self.new.center.x
} else ...... //checking my other variables and doing relative location moves.
I set a breakpoint and it's going into this code and getting to the center.x bit, but the view isn't moving.
I tried animating it with a duration of 0 or .1, the view didn't move. I also tried something I saw someone else mention that looked like
let f = menuBar.frame
let menubar.center.x = self.new.center.x
let menuBar.frame = f
that also did not work.
Any ideas why the view is just staying at where it's set in the storyboard?

zoom in zoom out at levels in shinobicharts ios

I am using ShinobiCharts in my iOS app to plot a line chart. This requires a feature where in the default view will be in Days. When i pinch zoom, i will be getting Weeks data, and more pinch zooming will give me Months data. Same applies for zoom out in reverse order.
I am not able to find a way to show this data at different zoom levels.
Please help me with this.
Im using following delegate method to check zoom level
- (void)sChartIsZooming:(ShinobiChart *)chart withChartMovementInformation:
(const SChartMovementInformation *)information;
but i dont find any way to check zoom levels.
One way of checking this is to determine the number of days currently displayed within the axis' visible range.
First off you'll need a way to record the current granularity of data on display in the chart:
typedef NS_ENUM(NSUInteger, DataView)
{
DataViewDaily,
DataViewWeekly,
DataViewMonthly,
};
The initial view will be DataViewDaily and is assigned within viewDidLoad to the property currentDataView.
Then within sChartIsZooming:withChartMovementInformation: you could do:
- (void)sChartIsZooming:(ShinobiChart *)chart withChartMovementInformation:(const SChartMovementInformation *)information
{
// Assuming x is our independent axis
CGFloat span = [_chart.xAxis.axisRange.span doubleValue];
static NSUInteger dayInterval = 60 * 60 * 24;
NSUInteger numberOfDaysDisplayed = span / dayInterval;
DataView previousDataView = _currentDataView;
if (numberOfDaysDisplayed <= 7)
{
// Show daily data
_currentDataView = DataViewDaily;
}
else if (numberOfDaysDisplayed <= 30)
{
// Show weekly data
_currentDataView = DataViewWeekly;
}
else
{
// Show monthly data
_currentDataView = DataViewMonthly;
}
// Only reload if the granularity has changed
if (previousDataView != _currentDataView)
{
// Reload and redraw chart to show new data
[_chart reloadData];
[_chart redrawChart];
}
}
Now within your datasource method sChart:dataPointAtIndex:forSeriesAtIndex: you can return the appropriate data points by switching on the value of _currentDataView.
Note that you may need to also update sChart:numberOfDataPointsForSeriesAtIndex to return the number of points to display at the current view level.

Calling web service on Scrolling UITableView

Totally Confused !!!...
I have one web-service that accepts the pageNumber as Parameter and gives me some records as JSON response. (This service basically implements the functionality of Paging for Silverlight version.) I want to load these pages one by one when user scrolls the UITableView (means Load the next 20 entries (or second page) when user scrolls).
My Problem :
How and Where to call this service and How to calculate pageNumber ?
I searched about this but didn't get any Satisfied answer.
What I found is :
How to call web service after each certain number of data received and load it into table view
Load more data from a web service when the user scrolls the UITableView
how to add elements to tableview on scrolling iphone?
I would love to here your responses in Objective-C Language.
Any Suggestions ?
Take one integer set it to 0. Now Used Pull to refresh functionality (Pull To refresh exmaple).
Now in API side you have to set the two extra parameter like pagenumber and pageSize
At very first time you call API with pageNumber=0 and pageSize=20
Now when you pull the table then you have a particular method in which you have to call the API with pageNumber++ and pageSize=20 again and whatever you get in the response add into your NSMutableArray. If you found nothing then remove pull to refresh option
I solved my Question with this Code :
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGPoint offset = scrollView.contentOffset;
CGRect bounds = scrollView.bounds;
CGSize size = scrollView.contentSize;
UIEdgeInsets inset = scrollView.contentInset;
float y = offset.y + bounds.size.height - inset.bottom;
float h = size.height;
float reload_distance = 10;
if(y > h + reload_distance)
{
lastPageNumber++;
[[NSUserDefaults standardUserDefaults] setInteger:lastPageNumber forKey:#"PageNumber"];
// Call the method.
}
}
Hope, it will be helpful for future Visitors.
To make an infinite scroller, you need to know when to start fetching the new items. There are many ways to do this, but the best place is to hook into the UITableViewDelegate's methods. When cellForRowAtIndexPath: is called, check if the row is the last in your data store. If it is, make the call for the new data, then append it to the old data and refresh your view. You can also hook into the table views scroller to see when it it X percent scrolled to the bottom to make this call.
In .h :
int lastPageNumber;
In .m :
In cellForRowAtIndexPath delegate method
int rowNum =indexPath.row;
if(rowNum%20==0)
{
if(rowNum/20>lastPageNumber)
{
//call webService
lastPageNumber++;
}
}

Resources