How to adjust webpage view using wkwebview - wkwebview

I am loading a url to wkwebview and i want to keep it from viewing a side of the webpage like this
https://drive.google.com/file/d/1qStJ1C_rrcjobSuorgPeLTkHZc82oUV4/view?usp=sharing
instead of
https://drive.google.com/file/d/1G05f6UVolmQCqdqKdJ0UFBBA6LVDI-BN/view?usp=sharing
Scrollview is already false and bounces are false too. Can someone help me
Thanks!
I have already tried using the scrollview and bounces parameters but the wkwebview still moves to the left exposing the blue part shown in the images. I want to display the webpage as shown in the first image so that its, for lack of a better word, view is locked as displayed. I'm not sure if I am explaining myself good, but let me know if I need to explain. I have added a video below showing what I want to know how to do.
https://drive.google.com/file/d/1uErGQlB1HKLU7px49UtGbsX9nOYqa3FN/view?usp=sharing
import Foundation
import UIKit
import WebKit
class ViewControllerWebKit: UIViewController, WKUIDelegate {
var webView: WKWebView!
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
webView.scrollView.bounces = false
let myURL = URL(string:"https://www.swpc.noaa.gov/communities/space-weather-enthusiasts")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}}
As shown in the photos and video, I don't know how to keep it from moving so it doesn't show the blue side which is part of the webpage.

If you want to stop the page from being scrolled to the side, the width in the html that you are showing should be equal to device-width. you can do so by defining the viewport. The thing is that your page has the blue bar in the right so either way I think you have to show it.
This solution will stop the scrolling behavior, but the bar will still be showing as it is part of the page.
override func viewDidLoad() {
super.viewDidLoad()
let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
let wkUController = WKUserContentController()
wkUController.addUserScript(userScript)
let webConfiguration = WKWebViewConfiguration()
webConfiguration.userContentController = wkUController
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
view = webView
webView.scrollView.bounces = false
let myURL = URL(string:"https://www.swpc.noaa.gov/communities/space-weather-enthusiasts")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}
Hope this could help.

Related

Kentico 12 MVC - Add a Forms selector inside a widget

How do I add a Forms widget inside another widget? I tried using FormZone() within the widget but nothing shows up.
It is not possible to render a Forms widget inside another widget in Kentico 12 MVC.
You will need to upgrade to Kentico Xperience 13 for this functionality - see https://docs.xperience.io/developing-websites/page-builder-development/rendering-widgets-in-code#Renderingwidgetsincode-Renderingwidgets
Technically, you can render a Form inside a Widget in Kentico 12, however it is not officially supported and requires a bit of custom development.
The key is to use IFormProvider and IFormComponentVisibilityEvaluator to get all the Form info so that you can render it manually (in a Controller):
var formInfo = BizFormInfoProvider
.GetBizFormInfo(formName, SiteContext.CurrentSiteName);
string className = DataClassInfoProvider
.GetClassName(formInfo.FormClassID);
var existingBizFormItem = className is null
? null
: BizFormItemProvider
.GetItems(className)?.GetExistingItemForContact(
formInfo, contactContext.ContactGuid);
var formComponents = formProvider
.GetFormComponents(formInfo)
.GetDisplayedComponents(
ContactManagementContext.CurrentContact,
formInfo, existingBizFormItem, visibilityEvaluator);
var settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
TypeNameHandling = TypeNameHandling.Auto,
StringEscapeHandling = StringEscapeHandling.EscapeHtml
};
var formConfiguration = JsonConvert.DeserializeObject<FormBuilderConfiguration>(
formInfo.FormBuilderLayout, settings);
var prefix = Guid.NewGuid().ToString();
ViewData.TemplateInfo.HtmlFieldPrefix = prefix;
return new FormWidgetViewModel
{
DisplayValidationErrors = true,
FormComponents = formComponents.ToList(),
FormConfiguration = formConfiguration,
FormName = formName,
FormPrefix = prefix,
IsFormSubmittable = true,
SiteForms = new List<SelectListItem>(),
SubmitButtonImage = formInfo.FormSubmitButtonImage,
SubmitButtonText = string.IsNullOrEmpty(formInfo.FormSubmitButtonText)
? ResHelper.GetString("general.submit")
: ResHelper.LocalizeString(formInfo.FormSubmitButtonText)
};
Then you would render the Form Model as an HTML Form using Kentico's Form rendering APIs:
<!-- ~/Views/Form/Form.cshtml -->
#using Kentico.Forms.Web.Mvc;
#using Kentico.Forms.Web.Mvc.Widgets;
#using Kentico.Forms.Web.Mvc.Widgets.Internal
#model FormWidgetViewModel
#{
var config = FormWidgetRenderingConfiguration.Default;
// #Html.Kentico().FormSubmitButton(Model) requires
// this ViewData value to be populated. Normally it
// executes as part of the Widget rendering, but since
// we aren't rendering a Widget, we have to do it manually
ViewData.AddFormWidgetRenderingConfiguration(config);
}
#using (Html.Kentico().BeginForm(Model))
{
#Html.Kentico().FormFields(Model)
#Html.Kentico().FormSubmitButton(Model)
}
You can read about the full configuration and setup in my blog post Kentico EMS: MVC Widget Experiments Part 3 - Rendering Form Builder Forms Without Widgets

Display PDF in Vaadin version 14+

What is the best way to display PDF file in Vaadin 14? i want to display a pdf file in a dialog, but i'm not sure how to render the pdf files. I saw some post about embedded pdf view,pdf browser and EmbeddedPdfDocument, but i can't tell if they are compatible with 14 or not.Is there a new method to do this?
There is a third party addon to render a PDF in Vaadin 14.
Your can find it here: https://vaadin.com/directory/component/pdf-browser/
That gives you the possibility to render a pdf with this code:
StreamResource streamResource = new StreamResource(
"report.pdf", () -> getClass().getResourceAsStream("/report.pdf")); // file in src/main/resources/
PdfBrowserViewer viewer = new PdfBrowserViewer(streamResource);
viewer.setHeight("100%");
layout.add(viewer);
Alternatively you can do it in same way as it was commonly done in previous Vaadin framework versions, embedding in IFrame (see Show PDF in a Vaadin View ), which could look something like this
StreamResource streamResource = new StreamResource(
getPresenter().createPdfStreamSource(), report.getName() + ".pdf");
StreamRegistration registration = VaadinSession.getCurrent().getResourceRegistry().registerResource(resource);
IFrame iframe = new IFrame(registration.getResourceUri().toString());
iframe.setHEight("100%");
layout.add(iframe);
To do it in Vaadin Flow (without an addon) and in a dialog as requested, I'd like to present the following code for your dialog which can be called like any other class. I had to tweak Jean-Christophe his answer a bit.
public class ManualDialog extends Dialog {
private IFrame iFrame;
private final String fileName = "fileNameAsFoundUnderYourResourceMap";
public ManualDialog() {
this.setHeight("calc(100vh - (2*var(--lumo-space-m)))");
this.setWidth("calc(100vw - (4*var(--lumo-space-m)))");
buildLayout();
}
private void buildLayout() {
// HEADER
HorizontalLayout header = new HorizontalLayout();
header.setMaxHeight("1em");
header.setAlignItems(FlexComponent.Alignment.CENTER);
header.setJustifyContentMode(FlexComponent.JustifyContentMode.BETWEEN);
header.getStyle().set("margin-top", "-1em");
Span caption = new Span(getTranslation("main.download.manual"));
caption.getStyle().set("color", "black");
caption.getStyle().set("font-weight", "bold");
Icon closeIcon = new Icon(VaadinIcon.CLOSE);
closeIcon.setColor(GENERIC_BUTTON_COLOR.getDescription());
Button closeButton = new Button();
closeButton.setIcon(closeIcon);
closeButton.getStyle().set("border", "none");
closeButton.getStyle().set("background", "transparent");
closeButton.addClickListener(click -> this.close());
header.add(caption, closeButton);
this.add(header);
// PDF-VIEW
iFrame = new IFrame();
iFrame.setSizeFull();
StreamResource resource = new StreamResource(fileName, () -> new BufferedInputStream(getClass().getClassLoader().getResourceAsStream(fileName)));
StreamRegistration registration = VaadinSession.getCurrent().getResourceRegistry().registerResource(resource);
iFrame.setSrc(registration.getResourceUri().toString());
this.add(iFrame);
this.open();
}
}

Replaced UIWebView with WKWebView, but still same error from Apple

I have removed the UIWebView from my app. But when I uploaded the iOS app on iTunes I still got the same message "Re: ITMS-90809: Deprecated API Usage - Apple will stop accepting submissions of apps that use UIWebView APIs"
I have searched for UIWebView globally in the project and there are no search results. That simply means UIWebView is removed.
I have updated the pods too.
I have verified the presence of UIWebView in the app archive using below code:
grep -r "UIWebView" .
The response is
./BCSymbolMaps/F4DBB519-4BC9-3C29-B017-4C0BD603D250.bcsymbolmap:l_OBJC_PROTOCOL_$_UIWebViewDelegate
./BCSymbolMaps/F4DBB519-4BC9-3C29-B017-4C0BD603D250.bcsymbolmap:l_OBJC_LABEL_PROTOCOL_$_UIWebViewDelegate
./BCSymbolMaps/F4DBB519-4BC9-3C29-B017-4C0BD603D250.bcsymbolmap:-[Crashlytics monitorErrorsForUIWebView:]
./BCSymbolMaps/F4DBB519-4BC9-3C29-B017-4C0BD603D250.bcsymbolmap:CLSWebViewIsUIWebViewAlreadyMonitored
./BCSymbolMaps/63FADF77-FD8F-31A1-9B4E-2799F044786E.bcsymbolmap:l_OBJC_PROTOCOL_$_UIWebViewDelegate
./BCSymbolMaps/63FADF77-FD8F-31A1-9B4E-2799F044786E.bcsymbolmap:l_OBJC_LABEL_PROTOCOL_$_UIWebViewDelegate
./BCSymbolMaps/63FADF77-FD8F-31A1-9B4E-2799F044786E.bcsymbolmap:-[Crashlytics monitorErrorsForUIWebView:]
./BCSymbolMaps/63FADF77-FD8F-31A1-9B4E-2799F044786E.bcsymbolmap:CLSWebViewIsUIWebViewAlreadyMonitored
Binary file ./dSYMs/Eureka.framework.dSYM/Contents/Resources/DWARF/Eureka matches
How can I check the code that is still causing the error of UIWebView?
How can I check if the UIWebView is completely removed from the project or not?
Solution is:
Open terminal. Open your project root folder in terminal.
Run Command: grep -r "UIWebView" .
This command will list all the pods that contains “UIWebView”. No either update these pods or remove these pods and ren the step 2 command again. Repeat till all “UIWebView” matches are not removed.
Below are some steps that will guide you to update existing UIWebView to WKWebView.
Import the “WebKit” class to the Controller.
Suppose you are using a UIWebView named “webViewMain”. Then go to your storyboard and simply replace the UIWebView with UIView. Make sure that you have added the same constraints to UIView that were added to UIWebView. Draw #IBOutlet from the new UIView to existing #IBOutlet of UIWebView.
Here you need to change the class of #IBOutlet from UIWebView to UIView because you have replaced the UIWebView with UIView.
Older Code: #IBOutlet weak var webViewMain: UIWebView!
New Code: #IBOutlet weak var webViewMain: UIView!
Then create a new variable to create a new WKWebView.
CODE: var webView : WKWebView!
Add below code where you load request/html in the UIWebView:
// WKWebView
// init and load request in webview.
webView = WKWebView(frame: self.webViewMain.frame)
webView.navigationDelegate = self
self.webView.load(request)
self.webViewMain.addSubview(webView)
webView.translatesAutoresizingMaskIntoConstraints = false
// Adding constraints from webView(WKWebView) to webViewMain (UIView)
webView.leadingAnchor.constraint(equalTo: webViewMain.leadingAnchor, constant: 0).isActive = true
webView.trailingAnchor.constraint(equalTo: webViewMain.trailingAnchor, constant: 0).isActive = true
webView.topAnchor.constraint(equalTo: webViewMain.topAnchor, constant: 0).isActive = true
webView.bottomAnchor.constraint(equalTo: webViewMain.bottomAnchor, constant: 0).isActive = true
// WKWebView
Till now you have replaced UIWebView with WKWebView .
Now comes the delegate methods.
UIWebView has delegate class: UIWebViewDelegate
WKWebView has delegate class: WKNavigationDelegate
Replace UIWebViewDelegate with WKNavigationDelegate.
Now comes delegate method comparison for UIWebView vs WKWebView:
UIWebView: func webViewDidFinishLoad(_ webView: UIWebView)
WKWebView: func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)
UIWebView: func webViewDidStartLoad(_ webView: UIWebView)
WKWebView: func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!)
UIWebView: func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool
Here we return true/false to load/cancel the navigation.
WKWebView: func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void)
Here we returndecisionHandler(.allow)/decisionHandler(.cancel) to load/cancel the navigation.
To Scale aspect fit content of the webView (WKWebView).
var scriptContent = "var meta = document.createElement('meta');"
scriptContent += "meta.name='viewport';"
scriptContent += "meta.content='width=device-width';"
scriptContent += "document.getElementsByTagName('head')[0].appendChild(meta);"
webView.evaluateJavaScript(scriptContent, completionHandler: nil)
To set the height of the webView:
webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
if complete != nil {
self.webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, error) in
self.constraintWebViewProductDescriptionHeight.constant = height as! CGFloat
})
}
})

How to place svg icon in toolbar

I need to replace all of my png icons with with svg - it is my employee request. I am using FFImageLoading. Some of the icons displayed in Pages are displaying properly but the problem is that I can't display svg icon in toolbar (toolbar item and hamburger icon).
I am using Xamarin.Forms 4.3.0.908675 and Xamarin.FFImageLoading - all in version 2.4.11.982.
My logo.svg is placed in MyProject.EmbeddedFiles.Images.
Here are the code samples I tried:
ToolbarItems.Add(new ToolbarItem
{
IconImageSource = "logo.svg",
Order = ToolbarItemOrder.Primary
});
ToolbarItems.Add(new ToolbarItem
{
IconImageSource = "MyProject.EmbeddedFiles.Images.logo.svg",
Order = ToolbarItemOrder.Primary
});
ToolbarItems.Add(new ToolbarItem
{
IconImageSource = ImageSource.FromResource("MyProject.EmbeddedFiles.Images.test.svg", typeof(App).GetTypeInfo().Assembly),
Order = ToolbarItemOrder.Primary
});
ToolbarItems.Add(new ToolbarItem
{
IconImageSource = new SvgImageSource(ImageSource.FromResource("MyProject.EmbeddedFiles.Images.test.svg", typeof(App).GetTypeInfo().Assembly), 10,10,true),
Order = ToolbarItemOrder.Primary
});
Neither solution works. My solution based on https://github.com/luberda-molinet/FFImageLoading/issues/1105
What am I missing? Is this even possible?

Is it possible to XCTest text fields in a webview?

I have a webview in my app, but I need to do some UI Test, however I am unable to find the text field element to properly implement my test. Does anyone have any idea? Thank you.
You have to expose your HTML elements to the Accessibility. For the text field, you can do it this way.
<div id="text-input">Super</div>
<input type="text" aria-labelledby="text-input" value="empty" />
You should see something like this in the accessibility inspector
This is how your test may look like.
func testExample()
{
let
textField = app.webViews.textFields["Super"]
textField.tap()
let before = textField.value as? String
XCTAssertEqual(before, "empty")
// This is strange but without this sleep typeText method doesn't work
sleep(1)
textField.typeText("lorem ipsum")
let after = textField.value as? String
XCTAssertEqual(after, "emptylorem ipsum")
}
Generally, exposing HTML elements to the Accessibility is a difficult area. You can find a lot of examples here. You can also check the list of supported elements. Best of luck.
If you have placeholder or text value in the input's of WKWebview instance, you can simply do
let app = XCUIApplication()
...
let webViewsQuery = app.webViews
let textfield1 = webViewsQuery.textFields["account email"]
viewExists = textfield1(timeout: 1.0)
if viewExists {
textfield1.tap()
sleep(1) // wait for keyboard
textfield1.typeText("populated email value")
let textfield2 = webViewsQuery.secureTextFields["Password"] // for password input type
textfield2.tap()
sleep(1) // wait for keyboard
textfield2.typeText("populated password")
}

Resources