I'm building an app that has two separate web views. When you click on a list of articles in a scrolling view, a corresponding web page is loaded into the first view. I'm trying to get it so that when I click on a link in that view, it loads that link into the second.
This is what I'm using to create a web view:
struct LogWebView: UIViewRepresentable {
typealias UIViewType = WKWebView
@ObservedObject var theLibraryComputer = ALibraryComputer.shared
let url: URL?
private let delegate = WVNavigationDelegate()
func makeUIView(context: Context) -> WKWebView {
let prefs = WKWebpagePreferences()
prefs.allowsContentJavaScript = true
let config = WKWebViewConfiguration()
config.defaultWebpagePreferences = prefs
let webView = WKWebView()
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
guard let myURL = url else {
return
}
let request = URLRequest(url: myURL)
uiView.load(request)
}
}
Right now, the first web view is driven by a variable stored in an Observable Object. That variable gets set when the user clicks on a link, and the web view loads just fine. To fix the "loading to a second view" problem I thought that a delegate could be used to intercept the link action. I'm using this delegate:
class WVNavigationDelegate: NSObject, WKNavigationDelegate {
@ObservedObject var theLibraryComputer = ALibraryComputer.shared
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
switch navigationAction.navigationType {
case WKNavigationType.linkActivated:
UIApplication.shared.open(navigationAction.request.url!, options: [:], completionHandler: nil)
decisionHandler(.cancel)
default:
decisionHandler(.allow)
}
}
}
But when I tie that delegate into my WebView, thusly, things break:
func makeUIView(context: Context) -> WKWebView {
let prefs = WKWebpagePreferences()
prefs.allowsContentJavaScript = true
let config = WKWebViewConfiguration()
config.defaultWebpagePreferences = prefs
let webView = WKWebView()
webView.navigationDelegate = delegate
return webView
}
Now the webview is no longer loading when I click on a link in my scrolling list. (And yes, I know that this delegate won't actually solve my navigation problem but I can't even see that problem until this is fixed.)
Thanks!
Post
Replies
Boosts
Views
Activity
I'm trying to load a local file from my Documents directory into a WebView. Works fine on the simulated but throws this "out of the sandbox" error when I run it on my iPad. It looks like this problem has been mentioned here before. Has there yet been a solution?
I've got a SwiftUI project where I'm displaying a local HTML file in a WebView. I'm using a CSS document that lives in the same folder as the HTML page. I would like to use a custom font that I've installed in my Xcode project but don't know what I should put in the CSS file for a source path to that font. Anyone have any ideas?
I'm trying to come out of a Preferences sheet and then immediately show a Share sheet (since it appears to be impossible to show a Share sheet from within another sheet.) I'm trying to call the Share sheet from the onDismiss handler of the Preferences sheet, like so:
Button("Prefs") {
theCurrentLog.prefsAreVisible.toggle()
}
.sheet(isPresented:$theCurrentLog.prefsAreVisible, onDismiss: {
guard let data = currentPrefs.exportURL else { return }
let av = UIActivityViewController(activityItems: [data], applicationActivities: nil)
UIApplication.shared.windows.first?.rootViewController?.present(av, animated: true, completion: nil)
}) {
Prefs(currentPrefs: $currentPrefs)
}
However, this causes a crash with the following error:
'UIPopoverPresentationController (<UIPopoverPresentationController: 0x15edddf10>) should have a non-nil sourceView or barButtonItem set before the presentation occurs.'
I have no idea how to specify a non-nil sourceView.
I've got some views that have background images, and I would like to switch those images to different images, when the orientation changes. I'm following this example to track when the orientation changes:
https://www.hackingwithswift.com/quick-start/swiftui/how-to-detect-device-rotation
So this gives me a way to track when orientation changes, but I can't find anywhere to use that information because the Views will already have drawn by the time I can execute any code.
I've got a Preferences system that I've implemented as a sheet. Within that I have an export command that bundles up some data and then offers a share sheet. Under iOS 14, I could trigger this share sheet from the onDismiss handler in the Preferences sheet call. Under iOS 15, it appears that onDismiss executes before the Preferences sheet goes away, so my Share Sheet never appears.
Here's the code that activates the Preferences sheet, which includes the onDismiss handler:
.sheet(isPresented: $theCurrentLog.prefsAreVisible, onDismiss: {
if currentPrefs.thePreferences.exportToShare {
let av = UIActivityViewController(activityItems: [currentPrefs.thePreferences.exportURL], applicationActivities: nil)
UIApplication.shared.windows.first?.rootViewController?.present(av, animated: true, completion: nil)
if UIDevice.current.userInterfaceIdiom == .pad {
av.popoverPresentationController?.sourceView = UIApplication.shared.windows.first
av.popoverPresentationController?.sourceRect = CGRect (
x: UIScreen.main.bounds.width / 2.1,
y: UIScreen.main.bounds.height / 2.3,
width: 200, height: 200)
}
currentPrefs.thePreferences.exportToShare = false
}
let prefsToSave:APreferenceSet = APreferenceSet()
prefsToSave.thePreferences = currentPrefs.thePreferences
prefsToSave.savePrefs()
}
) { Prefs()}
That exportToShare boolean in the if statement is set inside the the Preferences sheet.
Again, this all worked under iOS 14. Any ideas how to fix it for 15?
Thanks
I'm using this code to create a Share Sheet:
https://swiftui.gallery/uploads/code/ShareSheet.html
and I've got no problem bringing up a Share Sheet over another sheet. However, I'm having trouble getting it configured to share what I want. I'm trying to share a zip file out of my app. I've got an NSURL to the file I want to share, which I can pass with no problem, but it fails when I try to airdrop it. I assume this has something to do with applicationActivities?
iOS 15 has messed up the appearance of some of my lists. Try this code:
import SwiftUI
struct ContentView: View {
// let arrayOfStuff = ["Horse","Cow","Screwdriver","Blender","Pyramid","Scotch Tape","Baseball card","CD","Checkbook","Fountain pen","Pin cushion","Couch","Potatos","Protractor"]
let arrayOfStuff = ["Horse","Cow","Screwdriver","Blender"]
@State var currentlySelectedItem = ""
var body: some View {
ZStack {
Color(.red)
.ignoresSafeArea()
List {
ForEach(arrayOfStuff, id: \.self){ item in
Text(item)
.onTapGesture {
currentlySelectedItem = item
}
.listRowBackground(currentlySelectedItem == item ? Color.gray : Color(UIColor.systemGroupedBackground))
}
}
// .listStyle(GroupedListStyle())
.listStyle(PlainListStyle())
.frame(width: 500, height: 500, alignment: .leading)
}
}
}
When running with the plain list style, the area of the frame that doesn't include any rows becomes transparent. When running with the GroupedListStyle, the empty area stays white. That's the behavior I want, but I want the tighter margins of the plain list style. It was all working fine in iOS 14.
I've got a SwiftUI app that uses two separate web views to display html pages stored in a CoreData database. When the user clicks on a link in one web view, the linked file is shown in the second web view. To make this happen I'm using the following:
struct LibCompWebView: UIViewRepresentable {
let request: URLRequest
func makeCoordinator() -> Coordinator {
.init(self)
}
func makeUIView(context:Context) -> WKWebView {
let webView = WKWebView()
webView.navigationDelegate = context.coordinator
return webView
}
func updateUIView(_ webView: WKWebView, context: Context) {
webView.load(request)
}
class Coordinator: NSObject, WKNavigationDelegate {
var webView: LibCompWebView
init(_ webView:LibCompWebView) {
self.webView = webView
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == .linkActivated {
navigateLibCompTo(theURL:navigationAction.request.url!)
decisionHandler(.cancel)
} else {
print("not a user click")
decisionHandler(.allow)
}
}
}
}
In that NavigationDelegate is a call to a function called navigateLibCompTo, which passes the URL that the user clicked on to a function that is then supposed to look up the appropriate stuff from my coredata entity and load it into the appropriate web view.
I'm sharing my CoreData stuff as a StateObject accessed through an @environmentobject. The problem is that my navigateLibComp function is outside of my view hierarchy, so I have no way to access the CoreData stuff.
I'm completely stumped!