How to implement OnDrawAll and how to enable/disable ondraw method for pdfviewer by barteksc / AndroidPdfViewer or any other pdfviwer
Related
I am using a nsurlssesion based wrapper class written in objective-c in my swift project. Everthing is working except I am not able to undertand how the closure works in swift.
In my swift viewcontroller:
DownloadManager().downloadFile(forURL: url, progressBlock: { (progress) -> () in
print("current progress is \(progress)")
}, completionBlock: { (completion) in
print("is completed : \(completion)")
}, enableBackgroundMode: false)
In my Downloadmanager class (which is objc based) whenever nsurlssession delegate is called this happens:
dispatch_async(dispatch_get_main_queue(), ^(void) {
if(download.progressBlock){
download.progressBlock(progress); //exception when progressblock is nil
}
});
Download object have a block type property called progressBlock :
typedef void(^TWRDownloadProgressBlock)(CGFloat progress);
Output:
current progress is 0.0908259372799894
current progress is 0.272477811839968
current progress is 0.363303749119957
current progress is 0.454129686399947
current progress is 0.544955623679936
current progress is 0.635781560959925
current progress is 0.726607498239915
current progress is 0.817433435519904
current progress is 1.0
Flow of the code:
NSURlsession calls it's delegate method.
DowloadManager updates Download object's progress variable.
Somehow in my viewcontroller I can see the updated value of the progress variable inside the closure.
Question:
How is point-3 happening?
Is this the standard way closure behaves in swift? Specifically, I would like to know if the closure is automatically called everytime Dowload object changes?
According to The Swift Guide:
Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages.
Closures can capture and store references to any constants and variables from the context in which they are defined.
In this case, a closure is defined within the view controller, then passed
around and called later.
The flow would be as follows:
Make a new instance of TWRDownloadManager() and call its downloadFile method.
In this call, pass the progressBlock: ((CGFloat) -> Swift.Void) closure (it takes CGFloat as a parameter and returns nothing).
Down the line, this block is what gets assigned to TWRDownloadObject().progressBlock
Further down the line, NSURLSession Delegate method calls download.progressBlock(progress), which simply calls the closure from #2 and passes the CGFloat value as its parameter.
Here is quick Playground example:
import Foundation
import PlaygroundSupport
import TWRDownloadManager
PlaygroundPage.current.needsIndefiniteExecution = true
let downloadManager = TWRDownloadManager()
let url = "http://download.thinkbroadband.com/200MB.zip"
let progressClosure: (CGFloat) -> () = { (progress) in
print("current progress is \(progress)")
}
let completionClosure: (Bool) -> () = { (completion) in
print("is completed : \(completion)")
}
downloadManager.downloadFile(
forURL: url,
progressBlock: progressClosure,
completionBlock: completionClosure,
enableBackgroundMode: false
)
In my code it is dependent on Page.SizeChanged being called but when I use ApplicationView.GetForCurrentView().TryEnterFullScreenMode it does not call Page.SizeChanged if there is any way to call Page.SizeChanged and BTW I need to have both oldSize and newSize in the eventArgs variable
ApplicationView.GetForCurrentView().TryEnterFullScreenMode
I have made a subclass #Mosaic1 of #SystemWindow and I would like to control the initial position of the window. How do I do that? Class #RealEstateAgent is involved but how? The class comment says
Responsible for real-estate management on the screen,
which is to say, controlling where new windows appear,
with what sizes, etc. 5/20/96 sw
So I am asking for an explanation how to configure and use the class #RealEstateAgent.
Notes:
#RealEstateAgent is a singleton. It only has class side methods
It is only referenced by #SystemWindow
A new SystemWindow gets its initial extent from RealEstateAgent class>> standardWindowExtent
One solution is to bypass the class #RealEstateAgent and write your own code to handle the initial size and position of a new instance of SystemWindow.
This may be done by overriding SystemWindow>>openInWorld:extent:
openInWorld: aWorld extent: extent
"This msg and its callees result in the window being activeOnlyOnTop"
aWorld addMorph: self.
self morphPosition:
(RealEstateAgent initialFrameFor: self world: aWorld) topLeft;
morphExtent: extent.
aWorld startSteppingSubmorphsOf: self.
"Do it deferred. Was needed for text cursor to start blinking
if (Preferences disable: #focusFollowsMouse) "
WorldState addDeferredUIMessage: [ self activate ]
Replace
self morphPosition:
(RealEstateAgent initialFrameFor: self world: aWorld) topLeft;
morphExtent: extent.
Calculate
thePositionOfTheWindow
theExtentOfTheWindow
Then do
self morphPosition: thePositionOfTheWindow morphExtent: theExtentOfTheWindow.
How do I translate the following method call from ObjectiveC to RubyMotion syntax:
[self.faceView addGestureRecognizer:[
[UIPinchGestureRecognizer alloc] initWithTarget:self.faceView
action:#selector(pinch:)]];
I got this far:
self.faceView.addGestureRecognizer(
UIPinchGestureRecognizer.alloc.initWithTarget(
self.faceView, action:???))
I understand the #selector(pinch:) indicates a delegation to the receiver object pinch method, but how would I do this in RubyMotion? Maybe using a block?
You should be able to just use a string to specify the selector:
self.faceView.addGestureRecognizer(
UIPinchGestureRecognizer.alloc.initWithTarget(
self.faceView, action:'pinch'))
#gesture = UIPinchGestureRecognizer.alloc.initWithTarget(self.faceView,action:'pinch:')
self.faceView.addGestureRecognizer(#gesture)
def pinch(foo)
end
If you don't want the method handler to take an argument, use action:'pinch' instead. It will then look for a method like this:
def pinch
end
Using an instance var (#gesture = ...) is a good idea here because sometimes gesture recognizers and the GC don't play well together if you don't make the gesture var an instance var of a UIViewController. (In my experience)
One of the many benefits of implementing any pattern is to have a separation of concerns between the different layers in an application. In the case of Silverlight and MVVM it is my opinion that the NavigationService belongs to the UI.
If the NavigationService belongs to the UI then it should be used in the XAML code behind, but the commands happens on the ViewModel. Should I raise an event on the Command in the ViewModel and let the View handle the event and call the Navigation? That sounds a little absurd if all I'm doing is simply navigating to another page. Shouldn't I just handle the UI event directly and navigate from there?
View Control Event -> ViewModel Command -> Raise Event -> View
Handled Event -> Navigation
or
View Control Event -> View Handled Event -> Navigation
There are two documented approaches to this problem
Implementing the navigation using MVVM Light's messaging functionality This approach was put forward by Jesse Liberty in Part 3 his MVVM Ligtht soup to nuts series. His approach is to send a message from the command to the view indicating that a navigation operation should take place.
Implementing a ViewService that handles the navigationThis approach was Laurent Bugnion's response to Jesse's post. This implements a service that handles all navigation operations triggered by the view models.
Both approaches deal only with navigation in WP7 applications. However, they can be adapted to Silverligt applications too.
Jesse's approach is easier to use in SL as it does not require access to the root visual. However, the navigation code gets distributed in several places and requires code behind to do the actual navigation.
Laurent's approach requires access to the root visual - which is used for accessing the built-in navigation functionality. Getting access to this, as shown in Laurent's code, is no big deal in WP7 applications. In SL applications, however, it is slightly more complicated as there is no sourrounding frame. However, I alreay implented the pattern for SL in one of my projects using an attached property do do the required wiring - so although requires more work, it is usable for SL as well.
So concluding - although, Jesse's approach is easier to implement, personally I prefer Laurent's approach for it is cleaner architecture - there is no code behind required, and the functioality is encapsulated into a separate component and thus located at a single point.
A bit late to this question, but it is relevant and will hopefully be of benefit to someone. I had to create a SL4 application with MvvmLight and wanted to use a navigation service wrapper that was mock-able and could be injected into the ViewModel. I found a good starting point here: Laurent Bugnion's SL4 sample code samples from Mix11 which includes a navigation service demo: Deep Dive MVVM Mix11
Here are the essential parts for implementing a mock-able navigation service that can be used with Silverlight 4. The key issue is getting a reference to the main navigation frame to be used in the custom NavigationService class.
1) In MainPage.xaml, the navigation frame is given a unique name, for this example it will be ContentFrame:
<navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}"
Source="/Home" Navigated="ContentFrame_Navigated"
NavigationFailed="ContentFrame_NavigationFailed">
<!-- UriMappers here -->
</navigation:Frame>
2) In MainPage.xaml.cs, the navigation frame is exposed as a property:
public Frame NavigationFrame
{
get { return ContentFrame; }
}
3) The navigation service class implements the INavigationService interface and relies on the NavigationFrame property of MainPage.xaml.cs to get a reference to the navigation frame:
public interface INavigationService
{
event NavigatingCancelEventHandler Navigating;
void NavigateTo(Uri uri);
void GoBack();
}
public class NavigationService : INavigationService
{
private Frame _mainFrame;
public event NavigatingCancelEventHandler Navigating;
public void NavigateTo(Uri pageUri)
{
if (EnsureMainFrame())
_mainFrame.Navigate(pageUri);
}
public void GoBack()
{
if (EnsureMainFrame() && _mainFrame.CanGoBack)
_mainFrame.GoBack();
}
private bool EnsureMainFrame()
{
if (_mainFrame != null)
return true;
var mainPage = (Application.Current.RootVisual as MainPage);
if (mainPage != null)
{
// **** Here is the reference to the navigation frame exposed earlier in steps 1,2
_mainFrame = mainPage.NavigationFrame;
if (_mainFrame != null)
{
// Could be null if the app runs inside a design tool
_mainFrame.Navigating += (s, e) =>
{
if (Navigating != null)
{
Navigating(s, e);
}
};
return true;
}
}
return false;
}
}