Transparent background for WKWebView - ios

In my app I wish to make the WKWebView with transparent background, so the view behind (an ImageView) can show through as background picture.
webView!.opaque = false
webView!.backgroundColor = UIColor.clearColor()
The code above works fine with UIWebView, but if webView is WKWebView, a white background will be shown.
Also tried putting transparent background color in CSS. The result is the same, only works in UIWebView but not WKWebView. Any suggestion?

For iOS 10+ using Swift:
self.webView = WKWebView()
self.webView!.isOpaque = false
self.webView!.backgroundColor = UIColor.clear
self.webView!.scrollView.backgroundColor = UIColor.clear

This code might help you. Updated for Swift 3+
self.webView = WKWebView()
self.webView.isOpaque = false
self.webView.backgroundColor = UIColor.clear
self.webView.scrollView.backgroundColor = UIColor.clear

using objective c.
wkWebView.backgroundColor = [UIColor clearColor];
wkWebView.scrollView.backgroundColor = [UIColor clearColor];
wkWebView.opaque = false;
It will remove the white background colour in wkwebView.

This bug seems to be fixed in Beta 5.

I know this is a very old question. But I've been struggling with this today. I don't know if it's just me, but webView.backgroundColor was undefined in WKWebView, and webView.opaque was read-only. The only way for me to fix this was to set the web views layer background color to the CGColor clear
webview.wantsLayer = true
webView.layer?.backgroundColor = NSColor.clearColor().CGColor
and the containing NSView the same way
webViewParent.layer?.backgroundColor = NSColor.clearColor().CGColor
That's the only thing that worked for me, I hope it could help someone else as well.

WKWebView for macOS with Objective-C
This is the magic line for transparent WKWebView views within macOS.
[webView setValue:[NSNumber numberWithBool: YES] forKey:#"drawsTransparentBackground"];

Uncheck Opaque checkbox in Interface Builder
Update July 2021, Xcode 13
Looks like the checkbox is still there

Code below works for me:
[wkWebView setValue:YES forKey:#"drawsTransparentBackground"];

Haven't worked with WKWebView yet but even UIWebView used to have this issue and the solution was to wrap the html content inside something like this:
<body style="background-color:transparent;"></body>
Hope it helps.

If you're loading a PDF and want a background color different than the standard gray, it seems that it is necessary to wait until the document is loaded, then clear the backgrounds of the subviews. The advantage of using a WKWebView over a PDFView (iOS 11+) is that WKWebViews have double-tap to zoom and a page count indicator built in, and are compatible with older versions of iOS.
It should be noted that it's not a great practice to dig into system views like this as Apple can change the implementation at any time, potentially breaking the solution.
Here is how I implemented a PDF preview controller with a black background in Swift 4:
class SomeViewController: UIViewController {
var observer: NSKeyValueObservation?
var url: URL
init(url: URL) {
self.url = url
super.init(nibName: nil, bundle: nil)
}
func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.black
let webView = WKWebView()
webView.translatesAutoResizingMaskIntoConstraints = false
self.view.addSubview(webView)
NSLayoutConstraint.activate([
webView.topAnchor.constraint(equalTo: self.view.topAnchor),
webView.leftAnchor.constraint(equalTo: self.view.leftAnchor),
webView.rightAnchor.constraint(equalTo: self.view.rightAnchor),
webView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
])
self.observer = webView.observe(\.isLoading, changeHandler: { (webView, change) in
webView.clearBackgrounds()
})
webView.loadFileURL(self.url, allowingReadAccessTo: self.url)
}
}
extension UIView {
func clearBackgrounds() {
self.backgroundColor = UIColor.clear
for subview in self.subviews {
subview.clearBackgrounds()
}
}
}

I don't know if it can help, but i used this solution below:
func setBackgroundWhite(subviews: [UIView]) {
for subview in subviews {
subview.backgroundColor = .white
setBackgroundWhite(subviews: subview.subviews)
}
}
This does recursive call inner in subviews, setting up the background to white, or another color.
I used this code when loading PDF files, WKWebView and iOS 10+

In my case I need to change background-color to transparent in Styles and delete an App from phone/simulator manualny - it looks that WKWebView Cache HTML / Styles

Related

Can I change the background color of the Chromecast navigation bar?

I've reviewed the custom styles available in the GoogleCast v3 SDK and unless I'm missing something I don't see a way to change the backgroundColor of the deviceChooser. See below:
Is there any way to change this gray color?
As per the documentation Google does not allow us to change the navigation bar style. So we might need to change the navigation bar appearance before pushing to the media control UI of SDK.
I tried it in didFinishLaunchingWithOptions
[UINavigationBar appearance].barTintColor = [UIColor whiteColor];
[UINavigationBar appearance].translucent = NO;
Hope it helps :)
There are different ways you can customize the style on Chromecast SDK for iOS by using:
GCKUIStyle.sharedInstance()
My contribution for style the navigation bar:
From DOCUMENTATION I can see the following diagram
The common thing between all the "Style class" is that all of them inherit from GCKUIStyleAttributes so:
func configureChromecast() {
let gckCriteria = GCKDiscoveryCriteria(applicationID: "ABC123")
let gckCastOptions = GCKCastOptions(discoveryCriteria: gckCriteria)
GCKCastContext.setSharedInstanceWith(gckCastOptions)
GCKLogger.sharedInstance().delegate = self
// General
let textColor: UIColor = UIColor.black
let backgroundColor: UIColor = UIColor.white
GCKUIStyle.sharedInstance().castViews.backgroundColor = backgroundColor
GCKUIStyle.sharedInstance().castViews.headingTextColor = textColor
GCKUIStyle.sharedInstance().castViews.headingTextFont = UIFont.textStyleRegular
GCKUIStyle.sharedInstance().castViews.bodyTextColor = textColor
GCKUIStyle.sharedInstance().castViews.bodyTextFont = UIFont.textStyleRegular
GCKUIStyle.sharedInstance().castViews.captionTextColor = textColor
GCKUIStyle.sharedInstance().castViews.captionTextFont = UIFont.textStyleRegular
GCKUIStyle.sharedInstance().castViews.buttonTextColor = textColor
GCKUIStyle.sharedInstance().castViews.buttonTextFont = UIFont.textStyleRegular
GCKUIStyle.sharedInstance().castViews.iconTintColor = textColor
// Navigation & Toolbar
let navigationBackgroundColor: UIColor = UIColor.blue
let navigationtintColor: UIColor = UIColor.white
GCKUIStyle.sharedInstance().castViews.deviceControl.connectionController.navigation.backgroundColor = navigationBackgroundColor
GCKUIStyle.sharedInstance().castViews.deviceControl.connectionController.toolbar.backgroundColor = navigationBackgroundColor
GCKUIStyle.sharedInstance().castViews.deviceControl.connectionController.navigation.headingTextColor = navigationtintColor
GCKUIStyle.sharedInstance().castViews.deviceControl.connectionController.toolbar.headingTextColor = navigationtintColor
GCKUIStyle.sharedInstance().castViews.deviceControl.connectionController.navigation.bodyTextColor = navigationtintColor
GCKUIStyle.sharedInstance().castViews.deviceControl.connectionController.toolbar.bodyTextColor = navigationtintColor
GCKUIStyle.sharedInstance().castViews.deviceControl.connectionController.navigation.captionTextColor = navigationtintColor
GCKUIStyle.sharedInstance().castViews.deviceControl.connectionController.toolbar.captionTextColor = navigationtintColor
GCKUIStyle.sharedInstance().castViews.deviceControl.connectionController.navigation.buttonTextColor = navigationtintColor
GCKUIStyle.sharedInstance().castViews.deviceControl.connectionController.toolbar.buttonTextColor = navigationtintColor
GCKUIStyle.sharedInstance().castViews.deviceControl.connectionController.navigation.iconTintColor = navigationtintColor
GCKUIStyle.sharedInstance().castViews.deviceControl.connectionController.toolbar.iconTintColor = navigationtintColor
GCKUIStyle.sharedInstance().apply()
}
And the result:
The Navigation Bar style in question doesn't come from GoogleCast SDK (at least for version 4.6.1 dynamic on iOS 15) but from your own app's appearance. A way to change the background and title text color of the Navigation Bar (on GoogleCast SDK View Controllers, but your own app's as well) is to add
UINavigationBar.appearance().backgroundColor = UIColor.darkGray
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
in your AppDelegate's didFinishLaunchingWithOptions function.
But, no matter what tint color field I try setting for either UINavigationBar or UIBarButtonItem appearance, I can't get the Cancel button text color to change. I noticed that behavior in my app as well, only the Navigation Bar Buttons that have the tint set as Default in the Storyboard are affected by this global change, specifically by setting
UIBarButtonItem.appearance().tintColor = UIColor.yellow
If on the other hand you set a color in the Storyboard yourself, it will not be changed by the line of code above. This conclusion leads me to believe that is the way the Device Chooser View Controller was created, with a tint color set explicitly.
But, I see in one of the comments to the main question that someone was able to change the Cancel button color (as seen in the screenshot as well), so if anyone can share that piece of code it would be extremely appreciated.
Thanks!
EDIT
And of course only after posting this I tried pasting the entire code snippet from Reimond Hill and it worked in changing the Cancel button color, specifically this
GCKUIStyle.sharedInstance().castViews.deviceControl.connectionController.navigation.buttonTextColor = navigationtintColor
The reason why I thought this wouldn't work first time around is the fact that we are setting the navigation property of the Connection Controller, not the Device Controller (which doesn't even have this property). So I hope this will help someone else not waste time on this like I did.
You can style all GCK views using GCKUIStyle,
for example:
GCKUIStyle.sharedInstance().castViews.mediaControl.miniController.buttonTextColor = .black
GCKUIStyle.sharedInstance().apply()
in your case, the navigation can be styled with this line
connectionController.navigation.backgroundColor = UIColor.black
Check this URL for more info:
https://developers.google.com/cast/docs/ios_sender/customize_ui

iOS Disable Initial Zoom in webview?

I need to Disable zooming for UIWebview iOS for swift 2.2.
I am trying like this:
self.webView.scrollView.maximumZoomScale = 1.0;
self.webView.scrollView.minimumZoomScale = 1.0;
But this is not helping. Is there any other way I can disable zoom while the page loads for the first time?
This works for me:
let scrollView = webView.subviews.objectAtIndex(0)
scrollView.delegate = self
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return someView
}
UPDATE: For iOS 5 or higher get scrollView like this:
webview.scrollView.delegate = self;
You can try this also:
use 'webView.scrollView.zoomScale' instead of 1.0, and do it inside the 'webViewDidFinishLoad' (remember to set the web view delegate)
Turn off scalesPageToFit for the webView and set the zoom level manually for the first time loading. SO Post
Hope this helps.

UIView Background Image not showing

I've defined a bg image in the Xcode Images.xcassets and want to use it as background for a view but the bg stays black. I'm using:
override func viewDidLoad()
{
super.viewDidLoad();
view.backgroundColor = UIColor(patternImage: UIImage(named: "background_ipad"));
}
this should work according to some other tickets on SO but for some reason the background stays black, not showing the image. Any ideas why this would happen?
Use this code:
SWIFT
view.layer.contents = UIImage(named:"Image_Name").CGImage
Objective-C
view.layer.contents = (__bridge id _Nullable)([UIImage imageNamed:#"Image_Name"].CGImage);
Click on the catalog image
and ensure target membership
For objective C
self.view.layer.contents = (__bridge id _Nullable)([UIImage imageNamed:#"Image_Name"].CGImage);
For Swift
self.view.layer.contents = UIImage(named:"Image_Name")!.CGImage

Turning off dimming by UIPopoverController

In iOS7, a popover causes the rest of the screen to be dimmed. As per the Apple docs:
The popover content is layered on top of your existing content and the background is dimmed automatically.
This is nice in most cases, but I have an app where the screen rearranges itself when the popover opens and stays responsive, so the dimming only causes confusion. Anyone knows if dimming can be disabled?
Doesn’t look like there’s anything in the API to support that—you can set the passthroughViews property to allow other views to be interacted with while the popover’s open, but that doesn’t affect the dimming. You may have to roll your own popover implementation or find a third-party version.
I can suggest you a custom control which is really nice work by its author. It do not dim the background. Further it has many customization.
Here is the github link for WYPopoverController
For me at works like this. I just work through all subviews if key window view, find _UIMirrorNinePatchView. _UIMirrorNinePatchView is apple class for that has four image views, these image views create the dimming background for 4 directions of PopOverPresentationController. More specifically you can look at this if you use view hierarchy debugger. So I walk through the array of these UIImageView and set UIImage to nil. This code paste in viewWillAppear of your destination controller(popOverContoller).
NSArray<UIView *> *arrayOfSubviews = [UIApplication sharedApplication].keyWindow.subviews.lastObject.subviews;
for (int i = 0; i < arrayOfSubviews.count; i++) {
if ([NSStringFromClass(arrayOfSubviews[i].class) isEqualToString:#"_UIMirrorNinePatchView"]) {
arrayOfSubviews[i].backgroundColor = [UIColor clearColor];
NSArray<UIImageView *> *arrayOfImageViews = arrayOfSubviews[i].subviews;
for (int j = 0; j < arrayOfImageViews.count; j++) {
arrayOfImageViews[j].image = nil;
}
}
}
In whole my UIPopOverController looks like this
And in view debugger, it looks so
So as you can understand, setting UIImage to nil will remove this dimming view.
This is the swift version to remove the dimming of UIPopoverController
let allSubViews: [UIView] = (UIApplication.shared.keyWindow?.subviews.last?.subviews)!
for index in 0...allSubViews.count - 1 {
allSubViews[index].removeFromSuperview()
if NSStringFromClass(allSubViews[index].classForCoder) == "_UIMirrorNinePatchView"
{
allSubViews[index].backgroundColor = UIColor.clear
let arrayofImages = allSubViews[index].subviews as! [UIImageView]
for imageIndex in 0...arrayofImages.count - 1 {
arrayofImages[imageIndex].image = nil
}
}
}
You can prevent the dimming by setting the UIPopoverBackgroundView for your popover and setting the background to be transparent for the background view.
You will need to re-implement how the popover draws the arrows, but you can find plenty of examples for that online.
Updated to work in iOS 13 with Swift 4
guard let transitionSubviews = UIApplication.shared.keyWindow?.subviews.last?.subviews else { return }
func findViews<T>(inView view: UIView, subclassOf targetType: T.Type) -> [T] {
return recursiveSubviews(inView: view).compactMap { $0 as? T }
}
func recursiveSubviews(inView view: UIView) -> [UIView] {
return view.subviews + view.subviews.flatMap { recursiveSubviews(inView: $0) }
}
for view in transitionSubviews {
view.backgroundColor = UIColor.clear
for imageView in findViews(inView: view, subclassOf: UIImageView.self) {
imageView.image = nil
}
}
If you choose to implement your custom UIPopoverBackgroundView, you can set the layer background to be clear - layer.shadowColor = UIColor.clearColor().CGColor.
However this will eliminate the dim and the shadow completely so you will have to put a border around the controller
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
This solved my problem with navigation bar dimming effect while transiting.

Disable UISearchBar

I have a -as I hope- very simple question: how to disable an UISearchBar in IOS5 to avoid user interaction? I can't find setEnabled or something like this...
Thanks!
Have you tried:
[searchBar setUserInteractionEnabled:NO];
?
In addition to setting user interaction, I also adjusted the alpha value as well, to make the appearance unique.
searchbar.alpha = .75;
Try this
// Normal
self.searchDisplayController.searchBar.userInteractionEnabled = YES;
self.searchDisplayController.searchBar.translucent = YES;
self.searchDisplayController.searchBar.searchBarStyle = UISearchBarStyleDefault;
self.searchDisplayController.searchBar.backgroundColor = [UIColor clearColor];
// Faded out
self.searchDisplayController.searchBar.userInteractionEnabled = NO;
self.searchDisplayController.searchBar.translucent = NO;
self.searchDisplayController.searchBar.searchBarStyle = UISearchBarStyleMinimal;
self.searchDisplayController.searchBar.backgroundColor = [UIColor lightGrayColor];
An extension for Swift 4 that provides functions to enable and disable the UISearchBar. Feel free to adjust the alpha value as you see fit, since color schemes in use can impact the result.
extension UISearchBar {
func enable() {
isUserInteractionEnabled = true
alpha = 1.0
}
func disable() {
isUserInteractionEnabled = false
alpha = 0.5
}
}
Then to disable the searchBar:
searchBar.disable()
To enable:
searchBar.enable()
For Swift 3:
self.searchController.searchBar.isUserInteractionEnabled = true
Or if you want to still detect user interaction you can do this to disable the UITextField inside the UISearchBar:
(self.searchController.searchBar.value(forKey: "searchField") as! UITextField).isEnabled = false
Really simply:
#IBOutlet weak var yourNameForSearchBar: UISearchBar!
viewDidLoad {
yourNameForSearchBar.isHidden = true
}
this makes it so the SearchBar just hides and user-touches in its spot do nothing. That way, when you want it shown, you just do the opposite (false). You can also save the space, but that's outside the scope of this answer.

Resources