2

I’m trying to create a scrolling form for a mobile web app using a Famous ScrollView. However, iOS exhibits severe display bugs when scrolling while the keyboard is active. This occurs whether using an InputSurface or embedding an <input> directly in the Surface HTML.

What’s the best way to achieve a scrollable input form that supports Mobile Safari?

(JSFiddle code replicated below; to see the bug, tap on a text field and then attempt to scroll while keyboard is active.)

Famous.loaded(function () {
    var Engine = Famous.Core.Engine;
    var Surface = Famous.Core.Surface;
    var Scrollview = Famous.Views.Scrollview;
    var Transform = Famous.Core.Transform;

    var mainContext = Engine.createContext();

    var scrollview = new Scrollview();
    var surfaces = [];

    scrollview.sequenceFrom(surfaces);

    var inputhtml = '<div><input type="text" value="test: edit me" /></div>';

    for (var i = 0, temp; i < 40; i++) {
        temp = new Surface({
            content: inputhtml,
            size: [undefined, 200],
            properties: {
                backgroundColor: "hsl(" + (i * 360 / 40) + ", 100%, 50%)",
                lineHeight: "200px",
                textAlign: "center"
            },
            index: i
        });

        temp.pipe(scrollview);
        surfaces.push(temp);
    }
    mainContext.add(scrollview);
});
Luke Dennis
  • 14,212
  • 17
  • 56
  • 69
  • please let me know if you can re-produce the bug via simulator - go to browserstack.com - sign up an account - enter url test as : prollygeek.com/ios/ - try scrolling after keyboard shows up , if the issue appears please try to record behaviour , if not , let me know so i can get a real iphone and try to help you , cheers. – ProllyGeek Mar 25 '15 at 06:55
  • @ProllyGeek Tested, issue's still there. It will almost certainly need an actual device or the iOS Simulator to see the issue, since it's an interaction problem rather than a static rendering problem. – Luke Dennis Mar 25 '15 at 07:01
  • can you see the issue on the simulator ? if so i recommend using http://app.crossbrowsertesting.com/test-center , they have a tool to record videos , else if it doesnt show up , i will try getting an iphone by tonight to solve this issue. – ProllyGeek Mar 25 '15 at 07:03
  • tested the page on real iphone , the only issue i can see is the text cursor lag when you scroll , correct ? are there any other issues im not aware of ? – ProllyGeek Mar 26 '15 at 07:43
  • @ProllyGeek Are you looking at iOS7/8? The scrolling stutters and judders, the cursor jumps around, and the scroller permanently loses state, making certain portions of the scrollview unreachable. – Luke Dennis Mar 26 '15 at 15:49
  • iOS 8.1 , same what happens on emulator happens on real phone , have you tried any other phone with different version ? – ProllyGeek Mar 26 '15 at 15:56
  • Tried many different devices, real and simulated. Click into a text box and spend some time dragging back and forth, and you should see the problem. It gets worse when the finger drag starts in the text box, and/or drags over the keyboard. – Luke Dennis Mar 26 '15 at 17:15
  • Best solution is to record a video for exact bug. – ProllyGeek Mar 26 '15 at 17:22
  • Good idea: https://vid.me/Q86J – Luke Dennis Mar 26 '15 at 19:19

2 Answers2

2

This code seems to fix it by forcing a redraw of the text areas.

<style>
    input.force-redraw {
      text-shadow: rgba(0,0,0,0) 0px 0px 0px;
    }
</style>
<script>
    setInterval(function(){ 
        $('input').toggleClass('force-redraw');
    }, 10);
</script>

Updated fiddles: http://jsfiddle.net/byC98/87/ http://jsfiddle.net/byC98/88/

Unfortunately this is more of a hack then a fix :(

CPU utilization on an old laptop: enter image description here

This is a modified version of rooby's code from https://github.com/cubiq/iscroll/issues/178#issuecomment-11941817

Chris Gunawardena
  • 6,246
  • 1
  • 29
  • 45
1

The issue is that famous scroll view is not truly scrollable , they animate the group so that it looks smooth , and to add the pull to refresh effect.

A solution for this : there is no really a direct and neat solution for this as the iOS keyboard animation will always focus into input and on the other hand famous uses a hidden indicator that works like a scroll bar , which conflicts with the iOS focus algorithm , so the only possible solution is that famous changes the way they animate scrollable view.

Workaround:

  • Fortunately there is workaround , if user will scroll away from input it means they may be not interested in inputting text anymore , so we can blur the target input once the view is scrolled.
  • after lot of searching I didnt really find a rigid event for famous to indicate scroll start event, however mutation observer worked well to achieve the required result.

Famo.us ScrollView MouseOver - jsFiddle demo

  <link rel="stylesheet" type="text/css" href="/css/result-light.css">


      <link rel="stylesheet" type="text/css" href="https://rawgit.com/jperl/famous-compiled/e9c12b1fa657820d3f9bad093ea72e8ee2dfec46/dist/lib/famous/core/famous.css">



      <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"></script>
      <script type="text/javascript" src="http://rawgit.com/jperl/famous-compiled/e9c12b1fa657820d3f9bad093ea72e8ee2dfec46/dist/src/4f231991.polyfills.js"></script>

      <script type="text/javascript" src="https://rawgit.com/jperl/famous-compiled/97f85aaa64af255adfe0407c941e0e859b0759bc/dist/src/804b0adb.main.js"></script>


  <style>
    input { font-size: 40px; }
  </style>



<script type="text/javascript">
var observer;
window.onload=function(){
Famous.loaded(function () {
    var Engine = Famous.Core.Engine;
    var Surface = Famous.Core.Surface;
    var Modifier = Famous.Core.Modifier;
    var Scrollview = Famous.Views.Scrollview;
    var Transform = Famous.Core.Transform;

    var mainContext = Engine.createContext();

    var scrollview = new Scrollview();
    var surfaces = [];

    scrollview.sequenceFrom(surfaces);

    var inputhtml = '<div><input type="text" value="test: edit me" /></div>';

    for (var i = 0, temp; i < 40; i++) {
        temp = new Surface({
            content: inputhtml,
            size: [undefined, 200],
            properties: {
                backgroundColor: "hsl(" + (i * 360 / 40) + ", 100%, 50%)",
                lineHeight: "200px",
                textAlign: "center"
            },
            index: i
        });

        temp.pipe(scrollview);
        surfaces.push(temp);
    }
    mainContext.add(scrollview);

});
$("body").on("focus","input",function(){Observe($(this));});
$("body").on("blur","input",function(){endObserver();})
}


function Observe(event_input)
{
  var target = document.querySelector('.famous-group');

// create an observer instance
observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    event_input.blur();
    console.log(mutation.oldValue);
  });    
});

// configuration of the observer:
var config = { attributes: true, attributeOldValue: true, characterData: true };

// pass in the target node, as well as the observer options
observer.observe(target, config);
}
function endObserver()
{
  observer.disconnect();
}

</script>


</head>
<body>
</body>

</html>

The live example can be found on my page

ProllyGeek
  • 15,517
  • 9
  • 53
  • 72
  • It's not the fix I was hoping for, but it's the best I'm gonna be able to get until Famo.us fixes the root problem. :/ Thanks! – Luke Dennis Mar 27 '15 at 07:18
  • @Luke Dennis maybe if you tell me why you are using famous after all , then we can find a better solution , or maybe we can replace this part in your app to be pure native , cheers – ProllyGeek Mar 27 '15 at 07:46
  • At this point, it's to avoid having to re-do the app from scratch. ;) It's a cool platform in general, but it still has a ways to go before I'd use it in production again. – Luke Dennis Mar 28 '15 at 00:11