I am building a simple iOS application in Swift which is built with a webView inside the view. When load a Motion jpeg (mjpeg) in the webView and set
let reqObj = URLRequest(url: url! as URL)
vidView.delegate = self
vidView.scalesPageToFit = true
vidView.loadRequest(reqObj)
the pages load as I want in the right scale but after 1-2seconds the web view zooms in without any reason??? It seems to work but goes back and fourth between the scale I want and the zoomed in scale that i down want. I have read that one can set something to the html meta but don't understand how if this is the problem???
This is what I want it to be like
but this is what It goes to after a few seconds
This is what I don't want it to be like
The web view goes between these 2 content the whole time
Please if someone could help me with this matter and maybe knows what the problem is.
Related
I'm making a react-native based app, and I can partially use Swift code by react-native's NativeModule feature.
My app will be used as Split view / Slide over mode in iPad, and I want to know if my app is in the left-side, right-side, or Slide-over.
I could get width and height, also origin (CGPoint) by this code.
let window = UIApplication.shared.windows.first
// Then getting X, Y like this...
window.frame.origin.x
Now my app has only one webview, made by react-native-webview.
So I guess, since the webview is the whole content of the app, and it fills app 100%, so it always returns app.
I want to know, not in webView's perspective, but in app's perpective, the POSITION relative to the screen.
For example, if my iPad width is 1400, and if my app is on the half right side, x should be 700.
And if it is on left side, it should be 0.
I really struggled this, but couldn't find any solution.
FYI, I drawed a diagram for this question.
As I wrote on the above, I tried UIApplication.shared.windows.first.frame.
But it only show the CGPoint of webview, not app relative to the screen.
There is no API for getting 'X' or 'LEFT' in react-native-dimension too.
onLayout also not helpful.
(Please excuse the amount of text)
I'm trying to render a bunch of math questions in an app. Say there's 30 questions, and each question has about 7-8 fields (instructions, question, answer choices, and review).
I am able to do this successfully when I load them into containers with MathJax rendering (I also use a callback in the JS to make sure the content is loaded before being viewed).
The thing is, the process takes a few seconds each time, and I'd like to preload the entire set of questions, and the views, so that after the initial load, question loading will be instantaneous.
I think using a collection would be the best way to do this, and I've been trying two methods with no luck:
load the collection with all the content as cells/items, then jump to the cell (I was facing the issue that only the viewed cell would load, and then I figured if they did all load, I would face the issue that I am facing now with the next option)
load all the content into an invisible subview, then load the subview into a cell when it is selected (may offer more control over how things are loaded)
In either case, I run into the same issue (and this even happened in the initial one-by-one loading with multiple containers, where if I jumped around too quickly, the app would crash).
When loading a bunch of subviews, each with Mathjax, the app gets overwhelmed and crashes (I believe due to memory or cpu, it says "lost connection to iPad"). This doesn't seem to happen if there is a lot of Mathjax within one view. I think it's because the processes don't wait for each other to finish before beginning, and the app can't handle running multiple Mathjax rendering at the same time.
I think a possible solution is to make sure that the loop that loads the view does not reloop until the Mathjax is done rendering, but cannot figure out a way to make the loop wait (once it initiates the loading it keeps incrementing).
Hopefully someone can provide a good idea for:
how to structure the preloading mechanism in general
or
how to specifically make the loop wait for the view to render before relooping (I have a process that recognizes when the Mathjax has been fully rendered, but I can't figure out how to make the loop wait for it. This process is currently used to simply unhide the view once it's done).
for var i = 0; i < objectsKeyValues.count; i++ {
let iInput:String = cDParentVC.string1 + cDContentAbstraction.objectsKeyValues[i]["instructions"]! + cDParentVC.string2
let qInput:String = cDParentVC.string1 + cDContentAbstraction.objectsKeyValues[i]["question"]! + cDParentVC.string2
... for a few more of these
let iView = WKWebView.init(frame: CGRectMake(5,5,300,35), configuration: config)
...same
iView.loadHTMLString(iInput, baseURL: NSBundle.mainBundle().bundleURL)
..same
viewDictArray.append(["iView":iView,"qView":qView,"a1View":a1View,"a2View":a2View,"a3View":a3View,"a4View":a4View,"a5View":a5View,"rView":rView,"pView":pView])
cDLargeContent.invisiView.addSubview(viewDictArray[i]["iView"]!)
...same
}
I suspect NSOperations or GCD could also provide the necessary controls, but I am pretty green with programming and haven't been able to implement those concepts successfully, let alone verify if they would solve this issue.
I'm working on a book reader iOS application and using webview for displaying epub books. The 3rd party library I'm using for parsing epub book is "KFEpubKit".
I've to give option to user to adjust the font size (as in iBooks), and I've achieved that feature by updating the font of webview as:
let textSizeRule = "document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust= '\(fontPercentage)%'"
self.webView.stringByEvaluatingJavaScriptFromString(textSizeRule)
The problem I'm facing is that by increasing/decreasing font size, page number of book must also change. But I'm unable to do so.
How can I achieve this functionality in the way other book reading applications are doing it (i.e. kindle, iBook etc)?
You can create a second WebView object which is hidden. You do the same thing ("For time being, i'm reloading the book and computing page number.") in the background webview.
In your webViewDidFinishLoad method, check which webview is loaded
func webViewDidFinishLoad(webView: UIWebView) {
if webView == backgroundWebview {
//Compute number of pages
} else {
//Foreground webview
}
}
So the user is not disturbed by a reloading webview.
Hope this helps!
I'm using webViewDidFinishLoad a lot in my app and there's something about UIWebView that really bugs me, well, actually two things.
The first, when I load new content to a UIWebView I will see for half a second the last page that was loaded to the same UIWebView what will force me to "clean" the UIWebView using something like:
[_mainWebView stringByEvaluatingJavaScriptFromString:#"document.open();document.close();"];
before loading the new content.
The second issue I have and that's the main issue for this question is that if i'll load some new content to my UIWebView and do something like this:
[_mainWebView loadHTMLString:htmlString baseURL:nil];
...
- (void)webViewDidFinishLoad:(UIWebView *)webView {
_mainWebView.alpha = 1;
}
In some cases the UIWebView will show up white for half a second before showing up the content. I'm guessing that the content is already loaded into the UIWebView and that's why webViewDidFinishLoad:webView is firing but for small html pages showing to content takes loner than the actual load. Is there any workaround I can use to avoid the blank screen that is showing for a sec or so but still save that second?
I thought about animating the alpha from 0 to 1 but that solution feels kinda lame to me.
Try adding a javascript callback so you know when the web view contents have actually loaded: Javascript in UIWebView callback to C/Objective-C
im using a Default.png file for my iPad-app. It appears correctly but i could'nt find a way to modify the duration of the splash screen. Has somebody any suggestions? Google has many sites that show how to setup the startscreen but could'nt find a solution for my problem.
The first rule of Human Interface Guidelines for Splash Screens is: don't use splash screens. The second rule is: don't use splash screens!:
Supply a launch image to improve user experience.
Avoid using your launch image as an opportunity to provide:
An “application entry experience,” such as a splash screen
An About window
Branding elements, unless they are a static part of your application’s first screen
If you absolutely must include a long-duration splash screen, and have darn good reasons for doing so, the usual approach is to throw up a UIImageView containing a copy of you launch image in, e.g., application:didFinishLaunchingWithOptions: - which should provide the illusion of a lengthy splash screen.
But please don't.
Using a "splash screen" (Logo, etc) is not the idea of the Default.png!
Read the HIG from Apple.
The (splash) screen (named loading screen) is not for a Logo showing or something like this.
When having multitasking enabled, the "splash screen" shows up really rare.
The splash screen should, like the apple apps does, only show the interface coming up in the first application screen without any localized strings, etc.
Also keep in mind:
The faster the iOS Device get, the shorter you can see the Default.png. So avoid using it for any important CI/CD content.
The Default image is displayed while the app is loading and will be dismissed as soon as the app is ready. And there is no API to control that duration.
You can't technically modify the duration that the "Default" image stays there; it is designed to just be a temporary image "foreshadowing" the app actually starting up and isn't specifically designed as a splash screen.
I recommend that you keep the "splash screen effect" by adding an image view to the screen as the app starts in the -application:didFinishLaunchingWithOptions: method. You can then set a timer which calls a method to animate the splash off after the designated time you want it to be. It will be there for a little longer than you specify depending on how long it actually took the app to load up, but it will give the effect you're after.
You can set the image view's image to [UIImage imageNamed:#"Default"] and it will access that Default artwork for you.
You can't change the duration. If you want it be shown longer though, you can add the same image to a view that you show while you're loading your data!
There is a good blog post here on how to create a splash screen using a UIImageView with a timer:
http://nullpointr.wordpress.com/2012/02/19/iphone-dev-how-to-implement-a-splash-screen/
Useful for beginners, who are still learning the best way to do things in iOS.
As #Conrad Shultz answered, splash screen should be used only via the supplied LaunchScreen.storyboard file by Xcode.
However, in rare situations you do want to prolong the splash screen:
Download A LOT of files before the app starts since the app depends on them.
Other reason...
This is the way to do it:
Inside AppDelegate, under didFinishLaunchingWithOptions you should:
Create a VC that has the same splash image and the same constraints
Present it
Dismiss it after a given time
The code:
let splashVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "splash")
window?.makeKeyAndVisible()
if let root = window?.rootViewController
{
root.present(splashVC, animated: false, completion: nil)
let dispatchTime = DispatchTime.now() + 3
// didFinishLaunchingWithOptions will return and this block will be executed afterwards, hence, async..
DispatchQueue.main.asyncAfter(deadline: dispatchTime, execute: {
root.presentedViewController?.dismiss(animated: false, completion: nil)
})
}
}