HomeiOS DevelopmentInexplicable white background under SwiftUI Webview

Inexplicable white background under SwiftUI Webview


I am engaged on a pair of Swift tasks, and one in all them, working on an iPad, refuses to cooperate with this webview. The picture under reveals the whitespace under the editor. This solely seems when the consumer scrolls right down to the underside of the editor’s content material. For context, the editor locks the physique peak to 100vh when in panorama mode so this may show an editor in a side-by-side scrollable container, and this whitespace would not seem when the iPad is in portrait mode with the editor hidden.

Inexplicable white background under SwiftUI Webview

Additionally, I’ve enabled vim mode within the editor, and this appears to happen extra regularly, virtually solely when the editor is in vim mode and the consumer jumps to the underside of the observe’s content material.

That is my webview:

struct MarkdownTabView: View {
  @Binding var editingNote: NoteModel?
  @Binding var fullScreenCover: MainFullScreenCover?
  var onNavigateToNote: (NoteModel) -> Void = { _ in }
  @AppStorage(AppStorageKeys.editorThemeDark.rawValue) personal
    var editorThemeDark: CodeSyntaxTheme = .dracula
  @AppStorage(AppStorageKeys.editorThemeLight.rawValue) personal
    var editorThemeLight: CodeSyntaxTheme = .githubLight
  @AppStorage(AppStorageKeys.theme.rawValue) personal var theme: WebViewTheme =
    .fluster
  @AppStorage(AppStorageKeys.editorKeymap.rawValue) personal var editorKeymap: EditorKeymap = .base
  @AppStorage(AppStorageKeys.hasLaunchedPreviously.rawValue) personal
    var hasPreviouslyLaunched: Bool = false
  @Atmosphere(ThemeManager.self) personal var themeManager: ThemeManager
  var editorContainer: MdxEditorWebviewContainer
  init(
    editingNote: Binding<NoteModel?>, editorContainer: MdxEditorWebviewContainer,
    onNavigateToNote: ((NoteModel) -> Void)?,
    fullScreenCover: Binding<MainFullScreenCover?>
  ) {
    self._editingNote = editingNote
    self._fullScreenCover = fullScreenCover
    self.editorContainer = editorContainer
    if onNavigateToNote != nil {
      self.onNavigateToNote = onNavigateToNote!
    }
  }
  var physique: some View {
    if let editingNoteBinding = Binding($editingNote) {
      NavigationStack {
        MdxEditorWebview(
          url:
            Bundle.foremost.url(
              forResource: "index",
              withExtension: "html",
              subdirectory: "splitview_mdx_editor"
            )!,
          theme: $theme,
          editorThemeDark: $editorThemeDark,
          editorThemeLight: $editorThemeLight,
          editingNote: editingNoteBinding,
          editorKeymap: $editorKeymap,
          container: editorContainer,
          onNavigateToNote: onNavigateToNote,
          fullScreenCover: $fullScreenCover
        )
        .body(maxWidth: .infinity, maxHeight: .infinity)
        //                .body(width: geo.measurement.width, peak: geo.measurement.peak, alignment: .topLeading)
        // TODO: Take away this. That is only for straightforward growth.
        .onAppear {
          if let parsedMdx = editingNote?.markdown
            .preParsedBody
          {
            editorContainer.setParsedEditorContentString(
              content material: parsedMdx
            )
          }
          UIScrollView.look().bounces = false
          UIScrollView.look().isScrollEnabled =
            false
        }
        .onDisappear {
          UIScrollView.look().bounces = true
          UIScrollView.look().isScrollEnabled = true
        }
      }
    } else {
      if hasPreviouslyLaunched {
        SelectNoteToContinueView()
      } else {
        ProgressView()
          .progressViewStyle(.round)
          .scaleEffect(1.5)
          .tint(themeManager.theme.main)
      }
    }
  }
}

And the MdxEditorWebview:

  @MainActor
  public struct MdxEditorWebviewInternal: UIViewRepresentable {
    @State personal var webView: WKWebView = WKWebView(
      body: .zero,
      configuration: getConfig()
    )
    @State personal var didSetInitialContent = false
    @State var haveSetInitialContent: Bool = false
    @Atmosphere(.openURL) var openURL
    @Atmosphere(.modelContext) var modelContext
    @Atmosphere(.colorScheme) var colorScheme
    @Atmosphere(.createDataHandler) var dataHandler
    @AppStorage(AppStorageKeys.webviewFontSize.rawValue) personal
      var webviewFontSize: WebviewFontSize = .base
    let url: URL
    @Binding var present: Bool
    @Binding var theme: WebViewTheme
    @Binding var editorThemeDark: CodeSyntaxTheme
    @Binding var editorThemeLight: CodeSyntaxTheme
    @Binding var editingNote: NoteModel
    @Binding var editorKeymap: EditorKeymap
    @Binding var fullScreenCover: MainFullScreenCover?
    var onNavigateToNote: (NoteModel) -> Void

    let container: MdxEditorWebviewContainer

    public init(
      url: URL,
      theme: Binding<WebViewTheme>,
      editorThemeDark: Binding<CodeSyntaxTheme>,
      editorThemeLight: Binding<CodeSyntaxTheme>,
      editingNote: Binding<NoteModel>,
      editorKeymap: Binding<EditorKeymap>,
      container: MdxEditorWebviewContainer,
      present: Binding<Bool>,
      onNavigateToNote: @escaping (NoteModel) -> Void,
      fullScreenCover: Binding<MainFullScreenCover?>
    ) {
      self.url = url
      self._theme = theme
      self._editorThemeDark = editorThemeDark
      self._editorThemeLight = editorThemeLight
      self._editingNote = editingNote
      self._editorKeymap = editorKeymap
      self._fullScreenCover = fullScreenCover
      self.container = container
      self._show = present
      self.onNavigateToNote = onNavigateToNote
    }

    public func makeUIView(context: Context) -> WKWebView {
      let webView = container.webView
      webView.isHidden = true

      webView.navigationDelegate = context.coordinator
      let editorContentControllers = [
        SplitviewEditorWebviewActions.setWebviewLoaded.rawValue,
        SplitviewEditorWebviewActions.onEditorChange.rawValue,
        SplitviewEditorWebviewActions.requestSplitviewEditorData.rawValue,
        SplitviewEditorWebviewActions.requestParsedMdxContent.rawValue,
        SplitviewEditorWebviewActions.onTagClick.rawValue,
        MdxPreviewWebviewActions.viewNoteByUserDefinedId.rawValue,
        MdxPreviewWebviewActions.requestNoteData.rawValue
      ]
      if colorScheme == .darkish {
        webView.evaluateJavaScript(
          """
          doc.physique.classList.add("darkish"); null;
          """
        )
      }
      for controllerName in editorContentControllers {
        addUserContentController(
          controller: webView.configuration.userContentController,
          coordinator: context.coordinator,
          title: controllerName
        )
      }

      // Loading the web page solely as soon as
      webView.loadFileURL(url, allowingReadAccessTo: url)

      if colorScheme == .darkish {
        webView.evaluateJavaScript(
          """
          doc.physique.classList.add("darkish"); null;
          """
        )
      }

      return webView
    }

    public func updateUIView(_ uiView: WKWebView, context: Context) {
      uiView.isHidden = !present
      //        uiView.scrollView.contentInset = .zero
      //        uiView.scrollView.scrollIndicatorInsets = .zero
    }
    public func makeCoordinator() -> Coordinator {
      Coordinator(self)
    }
    public func setInitialProperties() {
      container.setInitialProperties(
        editingNote: editingNote,
        codeEditorTheme: colorScheme == .darkish
          ? editorThemeDark : editorThemeLight,
        editorKeymap: editorKeymap,
        theme: theme,
        fontSize: webviewFontSize,
        editorThemeDark: editorThemeDark,
        editorThemeLight: editorThemeLight,
        darkMode: colorScheme == .darkish,
        modelContext: modelContext
      )
    }
    public func setInitialContent() {
      let s = editingNote.markdown.physique.toQuotedJavascriptString() ?? "''"
      container.runJavascript(
        """
        window.localStorage.setItem("(SplitviewEditorWebviewLocalStorageKeys.initialValue.rawValue)", (s))
        window.setEditorContent((s))
        """
      )
    }
    public func handleViewNoteByUserDefinedId(id: String) {
      print("Right here...")
      let fetchDescriptor = FetchDescriptor<NoteModel>(
        predicate: #Predicate { observe in
          observe.frontMatter.userDefinedId == id
        })
      if let notes = attempt? self.modelContext.fetch(fetchDescriptor) {
        if !notes.isEmpty {
          let observe = notes.first
          self.editingNote = observe!
          self.onNavigateToNote(observe!)
        }
      }
    }
    public func handleTagClick(tagBody: String) {
      let fetchDescriptor = FetchDescriptor<TagModel>(
        predicate: #Predicate<TagModel> { t in
          t.worth == tagBody
        })
      if let tags = attempt? modelContext.fetch(fetchDescriptor) {
        if !tags.isEmpty {
          fullScreenCover = .tagSearch(tag: tags.first!)
        }
      }
    }
  }

  public struct MdxEditorWebview: View {
    @State personal var present: Bool = false
    @State personal var showEditNoteTaggables: Bool = false
    @Atmosphere(ThemeManager.self) personal var themeManager: ThemeManager
    let url: URL
    @Binding var theme: WebViewTheme
    @Binding var editorThemeDark: CodeSyntaxTheme
    @Binding var editorThemeLight: CodeSyntaxTheme
    @Binding var editingNote: NoteModel
    @Binding var editorKeymap: EditorKeymap
    @Binding var fullScreenCover: MainFullScreenCover?
    var onNavigateToNote: (NoteModel) -> Void
    let container: MdxEditorWebviewContainer
    public init(
      url: URL,
      theme: Binding<WebViewTheme>,
      editorThemeDark: Binding<CodeSyntaxTheme>,
      editorThemeLight: Binding<CodeSyntaxTheme>,
      editingNote: Binding<NoteModel>,
      editorKeymap: Binding<EditorKeymap>,
      container: MdxEditorWebviewContainer,
      onNavigateToNote: @escaping (NoteModel) -> Void,
      fullScreenCover: Binding<MainFullScreenCover?>?
    ) {
      self.url = url
      self._theme = theme
      self._editorThemeDark = editorThemeDark
      self._editorThemeLight = editorThemeLight
      self._editingNote = editingNote
      self._editorKeymap = editorKeymap
      self.container = container
      self.onNavigateToNote = onNavigateToNote
      if let fs = fullScreenCover {
        self._fullScreenCover = fs
      } else {
        self._fullScreenCover = .fixed(nil)
      }
      self.onNavigateToNote = onNavigateToNote
    }

    public var physique: some View {
      ZStack(alignment: present ? .bottomTrailing : .middle) {
        MdxEditorWebviewInternal(
          url: url,
          theme: $theme,
          editorThemeDark: $editorThemeDark,
          editorThemeLight: $editorThemeLight,
          editingNote: $editingNote,
          editorKeymap: $editorKeymap,
          container: container,
          present: $present,
          onNavigateToNote: onNavigateToNote,
          fullScreenCover: $fullScreenCover,
        )
        .disableAnimations()
        .body(
          alignment: .backside
        )
        .scrollDisabled(true)
        if !present {
          ProgressView()
            .progressViewStyle(.round)
            .scaleEffect(1.5)
            .tint(themeManager.theme.main)
        } else {
          FloatingButtonView(
            buttons: [
              FloatingButtonItem(
                id: "addTaggable",
                systemImage: "tag.fill",
                action: {
                  withAnimation {
                    showEditNoteTaggables.toggle()
                  }
                }
              ),
              FloatingButtonItem(
                id: "toggleBookmarked",
                systemImage: editingNote.bookmarked ? "bookmark.fill" : "bookmark",
                action: {
                  editingNote.bookmarked.toggle()
                }
              )
            ]
          )
          .padding()
        }
      }
      .fullScreenCover(
        isPresented: $showEditNoteTaggables,
        content material: {
          EditNoteTaggablesView(
            editingNote: $editingNote,
            open: $showEditNoteTaggables
          )
        },
      )
    }
    
      func onLoad() async {
          
      }
  }
#endif

Thanks prematurely for any options. I’ve solely been working with Swift for a pair months so there’s nonetheless so much for me to study.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments