Skip to content

HtmlView on iOS resets font on binding change #1268

Closed

Description

@sitefinitysteve

Okay so use this example:
https://gist.github.com/N3ll/f6c939539b6c0e0ae0e5

So basically any time you change the content bound to the html property, the font assigned gets reset...so need to keep re-calling this. I mean the UIFont is still there but what's in the view is reset to Times, and you need to re-call the .ios.font on it.

        var contentHtmlView = page.getViewById("contentHtmlView");
        contentHtmlView.ios.font = UIFont.fontWithNameSize(fontName,fontSize);

When I change the property bound to viewModel

<HtmlView id="contentHtmlView" html="{{ Content }}"  />

Video: http://www.screencast.com/t/0muA1wA5

Code in the click of the video is just this

exports.onChangeContent = function(args){
    var contentHtmlView = page.getViewById("contentHtmlView");

    viewModel.Content = "Changed: ios.font is " + contentHtmlView.ios.font;
}

by default on page load contentHtmlView.ios.font is null


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Activity

  1. self-assigned this
    on Jan 6, 2016
  2. enchev commented on Aug 8, 2016

    @enchev
    Contributor

    Hey @sitefinitysteve,

    Do you still have problems with this?

  3. sitefinitysteve commented on Aug 17, 2016

    @sitefinitysteve
    ContributorAuthor

    I'm sorry, I've been stuck in windows, I havent validated this since... however would it not still be an issue unless you guys fixed it?

  4. sitefinitysteve commented on Aug 23, 2016

    @sitefinitysteve
    ContributorAuthor

    @enchev Totally still an issue, can this re-open?

    Very simply just bind some value to the html property <HtmlView html="{{ property }}" shows as just plain unformatted content.

  5. reopened this on Aug 26, 2016
  6. enricodeleo commented on Nov 27, 2016

    @enricodeleo

    I use HtmlView since I didn't find a convenient/fast way to render strings with html entities. I encountered the same issue where dynamically laded texts are shown with times (or similar) on iOS.

    At the moment I'm using a simple hack that I would like to share here for anyone that needs an immediate fix:

    <HtmlView [html]="'<span style=font-family:-apple-system,BlinkMacSystemFont,Roboto,Oxygen,Ubuntu,Cantarell,Helvetica,sans-serif;>' + item.title + '</span>'">
    </HtmlView>

    please note that:

    • I'm leveraging the fact that html doesn't force the use of " character.
    • I'm avoiding both single and double quotes because if used the nativescript parser fails.
    • I also avoiding mapping my collection within the component/controller because I really hate mixing styles with data and I also hope to remove soon this little hack from my view :)
  7. added this to the milestone on Dec 5, 2016
  8. modified the milestones: 2.5.0, on Dec 5, 2016
  9. added this to the milestone on Jan 4, 2017
  10. 7 remaining items

  11. tsonevn commented on Feb 22, 2018

    @tsonevn
    Contributor

    Hi @sitefinitysteve,
    We checked the provided scenario again with replacing the font family in the HtmlView. However, it seems that the behaviour, how text is set to the view has changed. After reviewing the code in the modules, I found that at this time we are using NSAttributedString and changing the font as it is shown in the gist above is not supported on the initial time as well. Regarding that, I consider that technic is no longer supported and we could close this issue.

    @sitefinitysteve in case you think that this functionality should be supported, please provide more info about the use cases, and I will reopen the issue.

    For a more flexible way to modify a style in the HTML, I would suggest using WebView component.

  12. ghost removed on Feb 22, 2018
  13. sitefinitysteve commented on Feb 22, 2018

    @sitefinitysteve
    ContributorAuthor

    Can we re-evaluate or solicite some extra input on this? Like @enricodeleo I feel like multiple webview to just render some markup send from my service is just going to slow the app down, and is beyond overkill.

    The usecase is we store mixed content in Sitefinity, served out to our apps so like the detail views need to show multiple Html content fields in the single view. So it all works just fine until the bound content changes, then its like the HtmlView is just reset. Like Effectively this is our "Label" for most content. If the styling on a Label was reset on content change it would be just as problematic.

    We have thumbs-up on the issue, more than just me have encountered this :/

    Steve

  14. tsonevn commented on Mar 6, 2018

    @tsonevn
    Contributor

    Hi @sitefinitysteve,

    We rechecked the case and have to agree that using the multiple WebViews can slow the app down. Regarding that, I am opening this issue again. Also, any PR, which provides a fix for this behaviour will be highly appreciated.

    Regards,
    @tsonevn

  15. reopened this on Mar 6, 2018
  16. sitefinitysteve commented on Mar 6, 2018

    @sitefinitysteve
    ContributorAuthor
  17. added this to the 4.3 (TBD) milestone on Jul 30, 2018
  18. removed this from the 5.0 milestone on Oct 4, 2018
  19. sebj54 commented on May 25, 2020

    @sebj54
    Contributor

    The issue is still here in version 6.5.

    Is there any workaround for this bug? It feels very weird in any app to have Times New Roman on a well-designed page. I even tried to set custom styles directly in the HTML (with style attributes) and it doesn't work either.

  20. souriscloud commented on Nov 25, 2020

    @souriscloud

    @sebj54 did u resolve this out? I am facing the same problem with WebView on iOS in NativeScript 7, on Android it works well, but in iOS there is Times New Roman 😢 .. I tried to set the font almost everywhere ...

  21. sebj54 commented on Nov 26, 2020

    @sebj54
    Contributor

    Hi @souriscloud I finally made it work, yes! I made a custom component for that in my app. It's been a while since I made and used it so I don't remember why all that was needed so feel free to comment some things and try if it works without them.

    Here is the component (I was using NativeScript 6 at that time so maybe you'll have to adjust the component):

    HtmlContent.vue

    <template>
        <web-view
            v-if="isMounted"
            :src="src"
            :height="height"
            @loaded="webViewLoaded"
            @loadFinished="webviewLoadFinished"
        />
    </template>
    
    <script>
    /* global API_URL */
    import { knownFolders } from 'tns-core-modules/file-system'
    import { isIOS } from 'tns-core-modules/platform'
    
    export default {
        props: {
            autoMount: {
                type: Boolean,
                default: false,
            },
            html: {
                type: String,
                required: true,
            },
        },
        data() {
            return {
                height: 'auto',
                isMounted: false,
                webview: null,
            }
        },
        computed: {
            fullHtml() {
                const { path } = knownFolders.currentApp()
                // Font is loaded from API because it doesn't work when load locally
                const fontDirectory = isIOS ? `${API_URL}` : `file://${path}`
    
                return `
                    <html>
                        <head>
                            <style>
                                @font-face {
                                    font-family: "Gotham";
                                    src: url('${fontDirectory}/fonts/GothamMedium.ttf');
                                }
    
                                body {
                                    font-family: "Gotham", "GothamMedium", "Gotham-Medium", sans-serif;
                                }
                            </style>
                        </head>
                        <body>
                            ${this.html}
                        </body>
                    </html>
                `
            },
            src() {
                if (!isIOS) {
                    return ''
                }
    
                return this.fullHtml
            },
        },
        created() {
            if (this.autoMount) {
                this.isMounted = true
            }
        },
        mounted() {
            this.$root.$on('orientationChanged', this.updateHeightDelayed)
        },
        destroyed() {
            this.$root.$off('orientationChanged', this.updateHeightDelayed)
        },
        methods: {
            refreshHtmlView() {
                this.isMounted = true
    
                if (this.$el) {
                    setTimeout(() => {
                        this.$el.nativeView.requestLayout()
                    }, 50)
                }
            },
            /**
             * @see https://stackoverflow.com/questions/50338717/nativescript-ios-htmlview-in-scrollview-not-resizing
             */
            updateHeight() {
                if (isIOS) {
                    const jsStr = `var body = document.body;
                        var html = document.documentElement;
                        Math.max( body.scrollHeight, body.offsetHeight,
                        html.clientHeight, html.scrollHeight, html.offsetHeight);`
    
                    this.webview.ios.evaluateJavaScriptCompletionHandler(jsStr,
                        (
                            result,
                            error
                        ) => {
                            if (error) {
                                console.error(error)
                            } else if (result) {
                                this.height = result
                            }
                        })
                }
            },
            updateHeightDelayed() {
                setTimeout(this.updateHeight, 1000)
            },
            webViewLoaded({ object }) {
                this.webview = object
    
                if (!isIOS) {
                    this.webview.android.loadDataWithBaseURL(null, this.fullHtml, 'text/html', 'utf-8', 'about:blank')
                    this.webview.android.getSettings().setBuiltInZoomControls(false)
                }
            },
            webviewLoadFinished({ object }) {
                this.webview = object
    
                if (isIOS) {
                    this.webview.ios.scrollView.scrollEnabled = false
                    this.updateHeight()
                }
            },
        },
    }
    </script>
  22. NathanWalker commented on Oct 23, 2026

    @NathanWalker
    Contributor

    HtmlView on iOS now re-applies the view's CSS font-family, font-size and color to the rendered HTML on every html change (#8207), so there's no need to reset ios.font. Closing — if you still see the font reset on current @nativescript/core, please open a new issue with a repro.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions