IOS UIWebView in QML
-
I suspect I am trying to do something that is not possible. However I am hopeful I am wrong.
I know that the QML WebView is not supported on iOS so I have created a QML plugin using the native UIWebView control.
This part is easy. It just replaces the main View Controller with a new one that has the UIWebView applied.The issue is that, because it replaces the main view controller, it takes over the entire app.
I was hoping that I could either send it size and positioning properties, then overlay it over the top of the main view. However it seems that I end up with a black background over the top of the QML elements, then on top of the black area I have the resized UIWebView.
I suspect this is because the entire root web view has been swapped over, so there is really actually nothing 'behind it'.
Ideally, I would like to draw the view to the area to the defined on the QML object, but I don't think this is possible.
I have included all the code below, but I think the issue is with this section in how I apply it to the view.
@
UIView *view = static_cast<UIView *>(
QGuiApplication::platformNativeInterface()
->nativeResourceForWindow("uiview",window()));
UIViewController *qtController = [[view window] rootViewController];WebViewController *wView = [[[WebViewController alloc] init] autorelease];
[qtController presentViewController:wView animated:YES completion:nil];
@
Does anyone know if what I am after is possible, or any alternatives?
@
#include <UIKit/UIKit.h>
#include <QtGui/5.2.0/QtGui/qpa/qplatformnativeinterface.h>
#include <QtGui>
#include <QtQuick>#include "ViewController.h"
@interface WebViewController : UIViewController {
}
@end@implementation WebViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//self.view.frame = CGRectMake(0,0,100,100);UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:webView];NSString *urlAddress = @"http://www.google.com";
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];}
@end
IOSWebView::IOSWebView(QQuickItem *parent) :
QQuickItem(parent)
{}
void IOSWebView::open()
{
UIView *view = static_cast<UIView *>(
QGuiApplication::platformNativeInterface()
->nativeResourceForWindow("uiview",window()));
UIViewController *qtController = [[view window] rootViewController];WebViewController *wView = [[[WebViewController alloc] init] autorelease];
[qtController presentViewController:wView animated:YES completion:nil];
}
@
ViewController.h
@
#ifndef VIEWCONTROLLER_H
#define VIEWCONTROLLER_H#endif // VIEWCONTROLLER_H
#include <QQuickItem>
#include<QtQuick>class IOSWebView : public QQuickItem
{Q_OBJECT
public:
explicit IOSWebView(QQuickItem *parent = 0);public slots:
void open();};
@
Edit
A friend has come up with a method that is much more simple
@
UIView *view = static_cast<UIView *>(
QGuiApplication::platformNativeInterface()
->nativeResourceForWindow("uiview",window()));int x = 0;
int y = 80;
int width = 300;
int height = 200;UIWebView* webView =[[UIWebView alloc] initWithFrame:CGRectMake(x,y,width,height)];
[view addSubview:webView];NSString *urlAddress = @"http://www.google.com";
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];@
This appends it to the view rather than creating a new one. There is more needed to get it finished but it seems to work. I am still open to any other ideas or comments people have though.
- (void)viewDidLoad
-
Hi
Thanks a lot for sharing your work !
I'm beginner with implementing my own QQuickItem and use it on QML side.
I compiled your ViewController and here is what I did to expose the IOSWebView type on QML side:
@int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);qmlRegisterType<IOSWebView>("IOSWebView", 1, 0, "IOSWebView"); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:///qml/testwebview.qml"))); return app.exec();
}@
testwebview.qml:
@import QtQuick 2.0
import IOSWebView 1.0Rectangle {
IOSWebView { id:webv Component.onCompleted: { console.log("loaded web view") //webv.open() } }
}@
However the application screen remains black at runtime. Calling webv.open() doesn't change anything.
I probably didn't understand how the IOSWebView is supposed to be used. Could you tell me what I've done wrong please ?
-
Hello, many thanks for sharing the code. I'm not quite sure that I've understood your problem fully, though.
The problem was about positioning this component according to QML x, y, width, height and anchors properties, right? If so, I was able to do it, you can check it "here":https://github.com/g00dnight/IOSWebView.
-
[quote author="g00dnight" date="1408446341"]Hello, many thanks for sharing the code. I'm not quite sure that I've understood your problem fully, though.
The problem was about positioning this component according to QML x, y, width, height and anchors properties, right? If so, I was able to do it, you can check it "here":https://github.com/g00dnight/IOSWebView.[/quote]
Thanks a lot for the github g00dnight ! I'll give it a try in a few hours as soon as possible. And I'll edit this post to give a feedback.
-
Hi again g00dnight and thank you so much and thanks to johnc's original post also. I tried your IOSWebView. First the issue was remaining : IOSWebView wasn't appearing in my the QML Window on my iPad 2.
So I compared with another Qt sample (https://github.com/richardmg/qtdd13_qmlapp) which exposes the iOS Camera component (UIImagePickerController & ) as a QML Component. I noticed that this sample uses:
@import QtQuick.Window 2.0@As my IOSWebView project was using:
@import QtQuick.Window 2.1@So I changed for "QtQuick.Window 2.0" and it works! The root cause of my issue was really about the 2.1 version of QtQuick.Window element. Also my first post on this thread was a try with a Rectangle as the root QML element of my main.qml and this had no chance to work. All this is probably related to the following line in ioswebview.mm:
@UIView pMainView = static_cast<UIView>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow("uiview", (QWindow*)window()));@So I was doing a wrong usage of the QML IOSWebView although it should probably work with "QtQuick.Window 2.1" and I don't know why it doesn't.
I'm actually using Qt 5.3.1 on OSX 10.8.5.
my main.cpp:
@#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "ioswebview.h"int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<IOSWebView>("IOSWebView", 1, 0, "IOSWebView");
QQmlApplicationEngine engine;engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); return app.exec();
}@
my main.qml:
@import QtQuick 2.2
import QtQuick.Window 2.0
import IOSWebView 1.0Window {
visible: trueIOSWebView { id:webview url: "http://www.google.fr" anchors.fill: parent }
}@
-
This is a great solution for the missing WebKit on IOS.
Khelkun can you share the IOSWebView source in Git or similar?
-
Hi,
There's now the "QtWebView":https://qt.gitorious.org/qt/qtwebview/ module that provides this
-
[quote author="SGaist" date="1411945295"]Hi,
There's now the "QtWebView":https://qt.gitorious.org/qt/qtwebview/ module that provides this[/quote]
Cool thanks!
-
Hi, I wanted to give QtWebView a try on iOS.
I'm using the precompiled Qt 5.4 beta for iOS. Do you know how could I compile it and make it available for my app?Thanks!
Robert. -
git clone the repo, and then
qmake
make install
after that you should be able to build the example and deploy it via QtCreator. -
Thanks, I did exactly that and I'm getting a compile error:
In file included from qwebview_ios.mm:37:
./qwebview_p.h:51:10: fatal error: 'QtWebView/qwebview_global.h' file not found
#include <QtWebView/qwebview_global.h>Any ideas?
Thanks,
Robert. -
Are you on the dev branch ?
How did you proceed to compile it ? Did you install it ?
-
[quote author="SGaist" date="1413751591"]Are you on the dev branch ?[/quote]
Yes, that's the only branch in the repo.[quote author="SGaist" date="1413751591"]How did you proceed to compile it ? Did you install it ?[/quote]
I followed the same steps that Vincent007 suggested:
- clone the git repo
- cd to the repo path
- run qmake
- run make install (got the compile error)
Thanks,
Robert. -
Personally I don't build in the sources since you might also want to build for e.g. Android and if something fails it's easier to just delete the faulty build and start from scratch.
Just tested an out of source build and got not problem. However you should rather do:
qmake
# make
# make install -
Hi, I finally got it working.
I'm using the last 5.4 beta and I did an in source build. One for each platform (iOS/Android/OSX).
Thanks for your help!
Robert.