Ionic There is a Bug? ion-refresher and ion-infinite-scroll - ionic-framework

I found an compatibility issue using the two mentioned components on same list, my html and js code below:
HTML:
<ion-content ng-controller="homeCtrl">
<ion-refresher on-refresh="loadNewContent()" pulling-text="LoadMore..." spinner="android"></ion-refresher>
<div ng-repeat="item in items">
<img ng-src="{{pathUrl+item['path']}}" style="height: auto;width:100%;">
</div>
<ion-infinite-scroll ng-if="hasMore" on-infinite="loadMoreContent()" spinner="spiral" distance="5" immediate-check="false"></ion-infinite-scroll>
</ion-content>
JavaScript:
JiCtrls.controller('homeCtrl', ['$scope', '$timeout', 'DbService', 'JsonService',
function ($scope, $timeout, DbService, JsonService) {
$scope.items = [];
$scope.hasMore = true;
var run = false;
loadData(0);
//下拉更新
$scope.loadNewContent = function () {
loadData(2);
// Stop the ion-refresher from spinning
$scope.$broadcast("scroll.refreshComplete");
};
//上拉更新
$scope.loadMoreContent = function () {
loadData(1);
$scope.$broadcast('scroll.infiniteScrollComplete');
};
function loadData(stateType) {
if (!run) {
run = true;
if ($scope.sql == undefined) {
$scope.sql = "select top 5 * from information ";
}
DbService.getData($scope.sql, '').success(function (data, status, headers, config) {
var convertData = JsonService.convertData(data);
if (stateType == 1 || stateType == 0) {
// $scope.items = $scope.items.concat(convertData);
for (var i = 0; i < convertData.length; i++) {
$scope.items.push(convertData[i]);
}
}
else {
for (var i = 0; i < convertData.length; i++) {
$scope.items.unshift(convertData[i]);
}
}
if (convertData == null || convertData.length <= 0) {
$scope.hasmore = false;
;
}
$timeout(function () {
run = false;
}, 500);
}).error(function (errorData, errorStatus, errorHeaders, errorConfig) {
console.log(errorData);
});
}
}
}
]);
Everything is normal in Chrome browser and Iphone, but in a part of the Android phone there is a big problem.When ion-refresher trigger on-refresh function,the on-infinite="loadMoreContent()" function will run indefinitely. So,What is the problem?

Try to put $scope.$broadcast("scroll.refreshComplete"); and $scope.$broadcast('scroll.infiniteScrollComplete'); into DbService.getData(...).success() callback, not in functions triggered by on-infinite and on-refresh.
Explanation:
When the user scrolls to the end of the screen, $scope.loadMoreContent which is registered with on-infinite is triggered. The spinner shows, and ion-infinite-scroll pauses checking whether the user has reached the end of the screen, until $scope.$broadcast('scroll.infiniteScrollComplete'); is broadcast, when it hides the spinner and resumes the checking.
In your code, imagine there's a 3s delay in network, no new item is added to the list in that 3s. As a result, the inner height of ion-content is never updated, so the check that determines whether the user has reached the end of the screen will always return true. And you effectively prevent ion-infinite-scroll from pausing this checking by broadcasting scroll.infiniteScrollComplete the moment on-infinite is triggered. That's why it will update indefinitely.
To improve your code quality and prevent future problems, you may need to call $scope.$apply in your DbService.getData().success() callback (depending on the implementation of getData) and manually notify ion-content to resize in the callback.
P.S. 来自中国的Ionic开发者你好 :-) 两个中国人讲英语真累啊
Update
I've made a codepen that combines both ion-refresher and ion-infinite-scroll, I think it's working pretty fine.
http://codepen.io/KevinWang15/pen/xVQLPP
HTML
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>ion-refresher + ion-infinite-scroll 2</title>
<link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
</head>
<body ng-controller="MyCtrl">
<ion-header-bar class="bar-positive">
<h1 class="title">ion-refresher + ion-infinite-scroll 2</h1>
</ion-header-bar>
<ion-content delegate-handle="mainScroll">
<ion-refresher on-refresh="doRefresh()">
</ion-refresher>
<ion-list>
<ion-item ng-repeat="item in list">{{item}}</ion-item>
</ion-list>
<ion-infinite-scroll
ng-if="hasMore"
on-infinite="loadMore()"
distance="1%">
</ion-infinite-scroll>
</ion-content>
</body>
</html>
JS
angular.module('ionicApp', ['ionic'])
.controller('MyCtrl', function($scope, $timeout, $q, $ionicScrollDelegate) {
/*
list of items, used by ng-repeat
*/
$scope.list = [];
var itemOffset = 0,
itemsPerPage = 5;
/*
used by ng-if on ion-infinite-scroll
*/
$scope.hasMore = true;
/*
isRefreshing flag.
When set to true, on data arrive
it first empties the list
then appends new data to the list.
*/
var isRefreshing = false;
/*
introduce a custom dataFetcher instance
so that the old fetch process can be aborted
when the user refreshes the page.
*/
var dataFetcher=null;
/*
returns a "dataFetcher" object
with a promise and an abort() method
when abort() is called, the promise will be rejected.
*/
function fetchData(itemOffset, itemsPerPage) {
var list = [];
//isAborted flag
var isAborted = false;
var deferred = $q.defer();
//simulate async response
$timeout(function() {
if (!isAborted) {
//if not aborted
//assume there are 22 items in all
for (var i = itemOffset; i < itemOffset + itemsPerPage && i < 22; i++) {
list.push("Item " + (i + 1) + "/22");
}
deferred.resolve(list);
} else {
//when aborted, reject, and don't append the out-dated new data to the list
deferred.reject();
}
}, 1000);
return {
promise: deferred.promise,
abort: function() {
//set isAborted flag to true so that the promise will be rejected, and no out-dated data will be appended to the list
isAborted = true;
}
};
}
$scope.doRefresh = function() {
//resets the flags and counters.
$scope.hasMore = true;
itemOffset = 0;
isRefreshing = true;
//aborts previous data fetcher
if(!!dataFetcher) dataFetcher.abort();
//triggers loadMore()
$scope.loadMore();
}
$scope.loadMore = function() {
//aborts previous data fetcher
if(!!dataFetcher) dataFetcher.abort();
//fetch new data
dataFetcher=fetchData(itemOffset, itemsPerPage);
dataFetcher.promise.then(function(list) {
if (isRefreshing) {
//clear isRefreshing flag
isRefreshing = false;
//empty the list (delete old data) before appending new data to the end of the list.
$scope.list.splice(0);
//hide the spin
$scope.$broadcast('scroll.refreshComplete');
}
//Check whether it has reached the end
if (list.length < itemsPerPage) $scope.hasMore = false;
//append new data to the list
$scope.list = $scope.list.concat(list);
//hides the spin
$scope.$broadcast('scroll.infiniteScrollComplete');
//notify ion-content to resize after inner height has changed.
//so that it will trigger infinite scroll again if needed.
$timeout(function(){
$ionicScrollDelegate.$getByHandle('mainScroll').resize();
});
});
//update itemOffset
itemOffset += itemsPerPage;
};
});

The correct Javscript is as follows:
JiCtrls.controller('homeCtrl', ['$scope', '$timeout', '$ionicScrollDelegate', 'DbService', 'JsonService',
function ($scope, $timeout, $ionicScrollDelegate, DbService, JsonService) {
$scope.items = [];
$scope.hasMore = true;
loadData(0);
//下拉更新
$scope.loadNewContent = function () {
loadData(2);
};
//上拉更新
$scope.loadMoreContent = function () {
loadData(1);
};
function loadData(stateType) {
if ($scope.sql == undefined) {
$scope.sql = "select top 5 * from information”;
}
DbService.getData($scope.sql, '').success(function (data, status, headers, config) {
var convertData = JsonService.convertData(data);
if (stateType == 0) {
for (var i = 0; i < convertData.length; i++) {
$scope.items.push(convertData[i]);
}
}
else if (stateType == 1) {
// $scope.items = $scope.items.concat(convertData);
for (var i = 0; i < convertData.length; i++) {
$scope.items.push(convertData[i]);
}
$timeout(function () {
$scope.$broadcast('scroll.infiniteScrollComplete');
}, 500);
}
else {
for (var i = 0; i < convertData.length; i++) {
$scope.items.unshift(convertData[i]);
}
// Stop the ion-refresher from spinning
$timeout(function () {
$scope.$broadcast("scroll.refreshComplete");
}, 500);
}
$ionicScrollDelegate.resize();
if (convertData == null || convertData.length <= 0) {
$scope.hasmore = false;
}
}).error(function (errorData, errorStatus, errorHeaders, errorConfig) {
console.log(errorData);
});
}
}
]);

Related

Infinite scroll is not triggered framework7

I am using framework7.In AJAX success function I am loading first 20 people and remaining to be loaded by infinite scroll.
This is the div element
<div class="page-content infinite-scroll" data-distance="50">
<div class="searchbar-backdrop"></div>
<div class="entry_content">
<div class="members_list list searchbar-found list-block">
<ul class="row22">
</ul>
</div>
<div class="block searchbar-not-found">
<div class="block-inner">Nothing found</div>
</div>
</div>
Also this is the script
$on('pageInit', () => {
app.request({
url: base_url+api_path+'/members_directory.php',
method: "POST",
timeout: 0,
dataType: "json",
beforeSend: function () {
app.preloader.show();
},
success: function(data) {
app.preloader.hide();
console.log(data);
for(var i=0;i<20;++i){
// for(var i=0;i<data.getEmployees.length;++i){
var user_id = data.getEmployees[i].user_id;
var username = data.getEmployees[i].username;
var profile_photo = data.getEmployees[i].profile_photo;
var employee_name = data.getEmployees[i].employee_name;
var employee_id = data.getEmployees[i].employee_id;
$('.page_members_dir .members_list ul').append(
'<li class="item-content member_item"><div class="item-title member_name">'+employee_name+'</div></li>'
);
};
/*infinite*/
var loading = false;
// Last loaded index
var lastIndex = $('.list-block li').length;
// Max items to load
var maxItems = 60;
// Append items per load
var itemsPerLoad = 20;
// Attach 'infinite' event handler
$('.infinite-scroll').on('infinite', function () {
// app.attachInfiniteScroll($('.infinite-scroll'));
console.log("inside");
// Exit, if loading in progress
if (loading) return;
// Set loading flag
loading = true;
// Emulate 1s loading
setTimeout(function () {
// Reset loading flag
loading = false;
if (lastIndex >= maxItems) {
// Nothing more to load, detach infinite scroll events to prevent unnecessary loadings
app.detachInfiniteScroll($('.infinite-scroll'));
// Remove preloader
$('.infinite-scroll-preloader').remove();
return;
}
// Generate new items HTML
var html = '';
for (var i = lastIndex + 1; i <= data.getEmployees.length; i++) {
var user_id = data.getEmployees[i].user_id;
var username = data.getEmployees[i].username;
var profile_photo = data.getEmployees[i].profile_photo;
var employee_name = data.getEmployees[i].employee_name;
var employee_id = data.getEmployees[i].employee_id;
html += '<li class="item-content member_item"><div class="item-title member_name">'+employee_name+'</div></li>';
}
console.log(html);
// Append new items
$('.list-block ul').append(html);
// Update last loaded index
lastIndex = $('.list-block li').length;
}, 1000);
});
},
error: function(data) {
//console.log('error');
console.log(data);
}
});
});//pageInit
return $render;
}
I am not getting any errors in console.
The list data is getting from ajax page.
If I console after $('.infinite-scroll').on('infinite', function () nothing is displayed.
Is this right way to infinite scroll use in AJAX success function.
Please help

How to get rid of the loading progress in Facebook Instant Games with Phaser

I am developping a game for Facebook instant games with Phaser 2 CE, and i don't like the loading progress shown at the starting point, how can i get rid of it ?
I am using the default example given in the Quick Start page
FBInstant.initializeAsync()
.then(function() {
var images = ['phaser2'];
for (var i=0; i < images.length; i++) {
var assetName = images[i];
var progress = ((i+1)/images.length) * 100;
game.load.image('./assets/' + assetName + '.png');
// Informs the SDK of loading progress
FBInstant.setLoadingProgress(progress);
}
});
You can try something like given in this example like the code bellow then create your game, i know it's not clean but it works
FBInstant.initializeAsync()
.then(function() {
FBInstant.setLoadingProgress(50);
FBInstant.setLoadingProgress(100);
});
I have tryed something interesting but it doesn't answers the question according to this example
var sprite;
var PixelW = window.innerWidth;
var PixelH = window.innerHeight;
var game = new Phaser.Game(PixelW, PixelH, Phaser.AUTO, 'game', { preload: preload, create: create, update: update });
function preload() {
game.load.onLoadStart.add(loadStart, this);
game.load.onFileComplete.add(fileComplete, this);
startLoading();
}
function startLoading () {
game.load.image('logo1', 'assets/sprites/phaser1.png');
game.load.image('logo2', 'assets/sprites/phaser2.png');
game.load.image('dude', 'assets/sprites/phaser-dude.png');
game.load.image('ship', 'assets/sprites/phaser-ship.png');
game.load.image('mushroom', 'assets/sprites/mushroom.png');
game.load.image('mushroom2', 'assets/sprites/mushroom2.png');
game.load.image('diamond', 'assets/sprites/diamond.png');
game.load.image('bunny', 'assets/sprites/bunny.png');
game.load.start();
}
function create() {
game.stage.backgroundColor = 0x3b5998;
game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
sprite = game.add.sprite(game.world.centerX, game.world.centerY, 'dude');
sprite.inputEnabled = true;
sprite.events.onInputDown.add(myHandler, this);
var text = game.add.text(10, 10, PixelW + " " + " " + PixelH, { font: "65px Arial", fill: "#ffff00", align: "center" });
}
function loadStart() {
}
// This callback is sent the following parameters:
function fileComplete(progress, cacheKey, success, totalLoaded, totalFiles) {
FBInstant.setLoadingProgress(progress);
//console.log(cacheKey + " " + progress);
}
function myHandler() {
sprite.anchor.setTo(0.5, 0.5);
sprite.x = Math.floor(Math.random() * PixelW);
sprite.y = Math.floor(Math.random() * PixelH);
}
function update() {
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<script src="https://connect.facebook.net/en_US/fbinstant.6.0.js"></script>
<script src="phaser.min.js" type="text/javascript"></script>
<title></title>
</head>
<body>
<script type="text/javascript">
var p = 0;
FBInstant.initializeAsync()
.then(function() {
//FBInstant.setLoadingProgress(50);
//FBInstant.setLoadingProgress(100);
});
// Once all assets are loaded, tells the SDK
// to end loading view and start the game
FBInstant.startGameAsync()
.then(function() {
// Retrieving context and player information can only be done
// once startGameAsync() resolves
var contextId = FBInstant.context.getID();
var contextType = FBInstant.context.getType();
var playerName = FBInstant.player.getName();
var playerPic = FBInstant.player.getPhoto();
var playerId = FBInstant.player.getID();
// Once startGameAsync() resolves it also means the loading view has
// been removed and the user can see the game viewport
// game.start();
});
</script>
<div id="game"></div>
<script src="game.js" type="text/javascript"></script>
</body>
</html>
I use the methods below, I increase the loading percent after each file is loaded with Phaser. Also I include a try catch so that when testing local game play the game does not crash.
preload: function () {
try{
FBInstant.initializeAsync()
.then(function() {
});
}
catch(err) {
console.log('FB Instant Games Error: No Internet Connected');
}
this.load.image('gameItem1', 'assets/sprite/game_item1.png');
this.load.image('gameItem2', 'assets/sprite/game_item2.png');
}
And then...
startFacebookGame: function(){
try{
FBInstant.startGameAsync()
.then(function() {
// Retrieving context and player information can only be done
// once startGameAsync() resolves
var contextId = FBInstant.context.getID();
var contextType = FBInstant.context.getType();
var playerName = FBInstant.player.getName();
var playerPic = FBInstant.player.getPhoto();
var playerId = FBInstant.player.getID();
// Once startGameAsync() resolves it also means the loading view has
// been removed and the user can see the game viewport
});
}
catch(err) {
console.log('Analytics Connection Error');
}
},
fileComplete: function(progress, cacheKey, success, totalLoaded, totalFiles) {
try{
FBInstant.setLoadingProgress(progress);
}
catch(err) {
console.log('FB Instant Games progress Failed: No Internet Connected.');
}
//console.log("Progress: " + progress);
},
Here's how I do it. You can build out from there.
function preload() {
// Load some assets
FBInstant.setLoadingProgress(100)
}
function create() {
FBInstant
.startGameAsync()
.then(() => {
// Here you can now get users name etc.
console.log(this)
})
}
FBInstant.initializeAsync()
.then(() => {
new Phaser.Game({
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
scene: {
preload,
create
}
})
})

How to reload/refresh with infinite-scroll

I want to have a reload function but I found some difficulties.
My app should clear all data by using the reload function and grab the feed again. Event that works, but it shows me only the first 5 news (limit of my api/per page) and ignores completely the loadMore function.
factory
.factory('newsDataService', function($http) {
return {
GetPosts: function(page) {
return $http.get("http://newsapi.domain.tdl/");
},
GetMorePosts: function(page) {
return $http.get("http://newsapi.domain.tdl/?page=" + page);
}
};
})
controller
.controller('NewsCtrl', function($scope, newsDataService) {
$scope.page = 1;
$scope.noMoreItemsAvailable = false;
newsDataService.GetPosts().then(function(items){
$scope.items = [];
$scope.items = items.data.response;
});
$scope.Reload = function() {
console.log('reload');
newsDataService.GetPosts().then(function(items){
console.log(items);
$scope.items = items.data.response ;
$scope.noMoreItemsAvailable = false;
$scope.$broadcast('scroll.refreshComplete');
})
};
$scope.loadMore = function(argument) {
$scope.page++;
newsDataService.GetMorePosts($scope.page).then(function(items){
if (items.data.response) {
$scope.items = $scope.items.concat(items.data.response);
$scope.noMoreItemsAvailable = false;
} else {
$scope.noMoreItemsAvailable = true;
}
}).finally(function() {
$scope.$broadcast("scroll.infiniteScrollComplete");
});
};
})
template:
<ion-view view-title="News">
<ion-content>
<ion-refresher on-refresh="Reload()"></ion-refresher>
<div class="list">
<a collection-repeat="news in items" href="#/app/newsreader/{{news.id}}" class="item item-thumbnail-left">
<h2>{{news.headline}}</h2>
<div class="item-text-wrap" ng-bind-html="news.teaser"></div>
</a>
</div>
<ion-infinite-scroll ng-if="!noMoreItemsAvailable" on-infinite="loadMore()" distance="1%"></ion-infinite-scroll>
</ion-content>
</ion-view>
How can I resolve this?
Just found the solution on my own.
.controller('NewsCtrl', function($scope, newsDataService) {
$scope.items =[]
$scope.page = 1;
newsDataService.GetPosts().then(function(items){
$scope.items = items.data.response;
});
$scope.Reload = function() {
console.log('reload');
$scope.items =[];
$scope.page = 1;
$scope.loadMore();
};
$scope.loadMore = function(argument) {
$scope.page++;
newsDataService.GetMorePosts($scope.page).then(function(items){
if (items.data.response) {
$scope.items = $scope.items.concat(items.data.response);
$scope.noMoreItemsAvailable = false;
} else {
$scope.noMoreItemsAvailable = true;
}
}).finally(function() {
$scope.$broadcast("scroll.infiniteScrollComplete");
$scope.$broadcast('scroll.refreshComplete');
});
};
})

Ionic Local storage put information into array

Here is the code
Controller.js
$scope.addFavorite = function (index) {
$scope.temp = {
id: index
};
$scope.dish = $localStorage.getObject('favorites', '{}');
console.log($localStorage.get('favorites'));
$localStorage.storeObject('favorites', JSON.stringify($scope.temp));
var favorites = $localStorage.getObject('favorites');
console.log(favorites);
favoriteFactory.addToFavorites(index);
$ionicListDelegate.closeOptionButtons();
}
Service.js
.factory('favoriteFactory', ['$resource', 'baseURL', function ($resource, baseURL) {
var favFac = {};
var favorites = [];
favFac.addToFavorites = function (index) {
for (var i = 0; i < favorites.length; i++) {
if (favorites[i].id == index)
return;
}
favorites.push({id: index});
};
favFac.deleteFromFavorites = function (index) {
for (var i = 0; i < favorites.length; i++) {
if (favorites[i].id == index) {
favorites.splice(i, 1);
}
}
}
favFac.getFavorites = function () {
return favorites;
};
return favFac;
}])
.factory('$localStorage', ['$window', function($window) {
return {
store: function(key, value) {
$window.localStorage[key] = value;
},
get: function(key, defaultValue) {
return $window.localStorage[key] || defaultValue;
},
storeObject: function(key, value) {
$window.localStorage[key] = JSON.stringify(value);
},
getObject: function(key,defaultValue) {
return JSON.parse($window.localStorage[key] || defaultValue);
}
}
}])
I want to make a Favorites function, and I want to put every item's ID that marked into an array.
But, it couldn't expand the array and only change the value.
Did I make something wrong on here? Or maybe I put a wrong method on here?
Thank you in advance!
I just create logic for storing object, you have to made logic for remove object from localstorage.
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS</title>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script>document.write('<base href="' + document.location + '" />');</script>
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
</head>
<body ng-controller="MainCtrl">
<div ng-repeat="item in items">
{{item.item_name}}
<button ng-click="addFavorite(item.id)">Add to Favorite</button>
<br><hr>
</div>
</body>
</html>
<script type="text/javascript">
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope,$http)
{
$scope.items = [
{id:1,item_name:'Apple'},
{id:2,item_name:'Banana'},
{id:3,item_name:'Grapes'},
]
$scope.addFavorite = function (index)
{
if(localStorage.getItem('favorites')!=undefined)
{
var old_favorite = JSON.parse(localStorage.getItem('favorites'));
var obj = {index:index};
old_favorite.push(obj);
localStorage.setItem('favorites',JSON.stringify(old_favorite));
}
else
{
var obj = [{index:index}];
localStorage.setItem('favorites',JSON.stringify(obj));
}
}
});
</script>

youtube iframe API does not work on ipad and iphone

I was trying to recreate the multiple iframes example detailed here for a slideshow. It works flawlessly in all browsers, including desktop safari, except on iphone and ipad.
http://codepen.io/lakshminp/pen/mepIB
Js:
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var players = {}
var YT_ready = (function() {
var onReady_funcs = [],
api_isReady = false;
return function(func, b_before) {
if (func === true) {
api_isReady = true;
for (var i = 0; i < onReady_funcs.length; i++) {
// Removes the first func from the array, and execute func
onReady_funcs.shift()();
}
}
else if (typeof func == "function") {
if (api_isReady) func();
else onReady_funcs[b_before ? "unshift" : "push"](func);
}
}
})();
function onYouTubeIframeAPIReady() {
jQuery(window).bind("load", function() {
YT_ready(true);
});
}
YT_ready(function() {
var identifier = "v9d09JLBVRc";
players[identifier] = new YT.Player(identifier, {
events: {
'onReady': onPlayerReady,
"onStateChange": createYTEvent(identifier)
}
});
});
function onPlayerReady(event) {
event.target.playVideo();
}
// Returns a function to enable multiple events
function createYTEvent(identifier) {
var player = players[identifier]; // Get cached player instance
return function (event) {
console.log(event.data);
}
}
HTML:
<div id="yt-container">
<iframe width="640" height="480" id="v9d09JLBVRc" class="media-youtube-player" src="//www.youtube.com/embed/v9d09JLBVRc?enablejsapi=1&autoplay=0" frameborder="0" allowfullscreen></iframe>
</div>
According to this
functions and parameters such as autoplay, playVideo(), loadVideoById() won't work in all mobile environments
and in your YTReady function, you load dynamically a video and for the moment that's not possible on iOS.
You can also try the YouTubeDemoPage and try to load another id and you will see that it can't be done.
You should also check this.