Nativescript: HtmlView on iOS resets font on binding change

Created on 16 Dec 2015  Â·  12Comments  Â·  Source: NativeScript/NativeScript

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.

bug ios medium

Most helpful comment

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 :)

All 12 comments

Hey @sitefinitysteve,

Do you still have problems with this?

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?

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

Very simply just bind some value to the html property

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 :)

Ay chance this could be addressed? :/

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.

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

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

Thank you!

On Tue, Mar 6, 2018 at 7:07 AM, Nikolay Tsonev notifications@github.com
wrote:

Hi @sitefinitysteve https://github.com/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 https://github.com/tsonevn

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/NativeScript/NativeScript/issues/1268#issuecomment-370760942,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABeI6Dgz8BTcfS2l2EO2YGxZSkLxCTVYks5tbnwfgaJpZM4G23Oz
.

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.

@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 :cry: .. I tried to set the font almost everywhere ...

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>
Was this page helpful?
0 / 5 - 0 ratings