Ionic / iOS - ion-list won't scroll - html

I am trying to run my ionic app with xcode by doing:
ionic package build ios
ionic cordova prepare
Then I open up xcode and do Clean and Run. When on the device the scrolling acts like this:
My HTML looks like this:
...
<ion-content no-padding>
<div (touchstart)="swipe($event, 'start')" (touchend)="swipe($event, 'end')">
<div class ='contentone' [#moveList]='moveState'>
<ion-list class="marginstatus" no-padding>
<ion-item class="changepadding" *ngFor="let z of items ; let i = index" (click)='expandItem(i)' id='{{i}}' #feedstyle text-wrap>
<div class="flex" #flex>
<div class="nonzoomimage">
<img class="imagepost" src="{{z.pic}}">
</div>
<div class="descholder">
<div class='description'>{{z.description}}</div>
<div class='link'>{{z.link}}</div>
</div>
</div>
<div class="feedtoptextcontainer" #feedtop>
<div class="imageparent">
<img class="postprofilepic" src="{{z.pic}}">
</div>
<div class="usernamecontainer">
<h4 class="postusername">Ed Bundy</h4><br>
<h4 class="poststudio">Ed's Studio</h4>
</div>
<div class="postprofilelink">
<div class="book">Book</div> #edbundyhair
</div>
</div>
<img class="imageposttwo" #imagepost src="{{z.pic}}">
</ion-item>
</ion-list>
<ion-infinite-scroll (ionInfinite)="$event.waitFor(doInfinite())">
<ion-infinite-scroll-content
loadingSpinner="bubbles"
loadingText="Loading more data...">
</ion-infinite-scroll-content>
</ion-infinite-scroll>
</div>
</div>
</ion-content>
...
My doInfinite function, of ion-infinite-scroll looks like this, it is empty, just a placeholder right now - it does nothing:
doInfinite(): Promise<any> {
console.log('Begin async operation');
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, 500);
})
}
It just glitches when you try to scroll - and doesn't scroll at all, doInfinite fires because I can see the log message.

Ionic by default uses the Ionic scroll, which simulates the Momentum Scrolling as seen on the iOS devices, by adding the overflow-scroll=true attribute, it will basically use this particular ion-content to use the native scrolling (if you want a global effect check out the following link.
http://ionicframework.com/docs/v1/api/provider/$ionicConfigProvider/
Please also check if css classes are affecting the style of the element!

Is it only doing the bug when you scroll upwards? If yes, try to check this:
ion-infinite-scroll fires when scrolling up - Ionic
Can you try to start with and build something simple like this?
<ion-infinite-scroll (ionInfinite)="fetchMore($event)">
<ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>
and on your .ts
fetchMore(event) {
console.log('Begin fetching more data');
setTimeout(() => {
console.log('Async operation has ended');
event.complete();
}, 500);
}
Not sure why your code would cause that glitch but if you happen to make something simple as this work, you'll find out what causes the bug as you build it back up to what you have.
Could be that the $event.waitFor() still has its issues. If you need to wait for a promise like when you're fetching more data. you can have something like this.
fetchMore(event) {
this.fetchingDataService.fetchPromise().then(
(moreData) => {
//append moreData
event.complete();
},
(err) => {
//do something with error
event.complete();
}
);
}

Found the problem. After upgrading to Ionic 3, at least in my case, the swipe event on an ion-list in an ion-scroll freeze my scroll.
<ion-scroll scrollY="true">
<ion-list padding (swipe)="someThing($event)"> <!-- There, swipe, removing it make my ion-scroll scrollable again -->
<ion-item>
<p>1</p>
</ion-item>
....
<ion-item>
<p>9999</p>
</ion-item>
</ion-list>
</ion-scroll>

Related

ion-infinite-scroll not working inside ion-scroll

I'm trying to implement load more functionality in the half portion of the page.
So I put that code inside the ion-scroll but somehow current implementation is not working i.g. the method is
(ionInfinite)="doInfinite($event)"
is not triggered and loader UI is not rendered. However, the same implementation is working if the content placed in ion-content instead of ion-scroll.
<ion-content padding>
<ion-scroll scrollY="true" id="accountList" class="list-box">
<ion-list >
<ion-item *ngFor="let item of [1,2,3,4,5,6,7,8,9]">
<ion-icon ios="ios-add-circle" md="ios-add-circle" item-start color="secondary"></ion-icon>
Item1
<ion-buttons item-end>
<button ion-button clear icon-only color="orange">
<ion-icon ios="md-create" md="md-create" item-end ></ion-icon>
</button>
<button ion-button clear icon-only color="danger">
<ion-icon ios="md-close" md="md-close" item-end></ion-icon>
</button>
</ion-buttons>
</ion-item>
</ion-list>
<ion-infinite-scroll (ionInfinite)="doInfinite($event)">
<ion-infinite-scroll-content
loadingSpinner="bubbles"
loadingText="Loading more data...">
</ion-infinite-scroll-content>
</ion-infinite-scroll>
</ion-scroll>
</ion-content>
Sorry for my bad english, but I resolved this problem by using below code:
<ion-scroll #scrollWeb scrollY="true" class="scroll-y">
<ion-grid>
<ion-row>
<ion-col col-4 col-sm-6 col-md-4 col-lg-4 col-xl-4 *ngFor="let item of items">
<item-card [item]="item"></item-card>
</ion-col>
</ion-row>
</ion-grid>
</ion-scroll>
And on my component:
#ViewChild('scrollWeb') scrollWeb: Scroll;
Added listener on DOM Element to discover if the scroll arrived in the end as follows:
ngAfterViewInit() {
if (this.scrollWeb) {
this.scrollWeb.addScrollEventListener((ev) => {
if ((ev.target.offsetHeight + ev.target.scrollTop) >= ev.target.scrollHeight) {
this.doInfinite(null);
}
});
}
}
In doInfinite function you can omit or show a loader as follows:
if (infiniteScroll !== null) {
infiniteScroll.complete();
}
Ionic-version: 3.9.2
I have a similar problem in the component. My solution was:
Replace <ion-scroll> with <ion-content>
Add overflow: auto; style for <ion-content>
Enjoy virtual scrolling
You need call the $event.complete() method. From the Ionic documentation page of InifniteScroll:
"The expression assigned to the infinite event is called when the user
scrolls to the specified distance. When this expression has finished
its tasks, it should call the complete() method on the infinite scroll
instance."
ion-Scroll doesn't fire scroll events right now, thus ion-infinite-scroll subscription to scroll events is not fired.
You can try to find some workarounds like firing similar event yourself. I just desided to emulate visual similarity in regular ion-content using css for now (not perfect solution).
Link to issue on Ionic Github: https://github.com/ionic-team/ionic/issues/13904
Link to issue on forum: https://forum.ionicframework.com/t/ionscroll-event-doesnt-fire-on-ion-scroll/96188/3

Ionic 2 tabs and sidebar - How do I maintain tabs with setRoot?

I have an Ionic 2 app that uses both a sidebar and tabs.
I have managed to create a link in the sidebar that sends the user back to the root page, but this kills the tabs. I would like the tabs to be persistent.
Here is what I have:
app.html
`<ion-menu [content]="content">
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
<ion-content>
<ion-list>
<ion-item (click)="openPage(page)" *ngFor="let page of pages">
<span>{{page.title}}</span>
</ion-item>
</ion-list>
</ion-content>
<ion-nav id="nav" [root]="rootPage" #content swipe-back-enabled="false"></ion-nav>
Then in my app.ts I have this function:
openPage(page) {
this.menu.close();
this.nav.setRoot(page.component);
}
So this does actually work, but I lose my tabs. Is there a better way to do this?
this.nav.setRoot(TabsPage);
TabsPage is the class name of your tabs page's component.
You could reference the ionic-conference-app. It works for me.
openPage(page){
this.menu.close();
let params = {};
if (page.index) {
params = { tabIndex: page.index };
}
if (this.nav.getActiveChildNavs().length && page.index != undefined) {
this.nav.getActiveChildNavs()[0].select(page.index);
} else {
this.nav.setRoot(page.name, params).catch((err: any) => {
console.log(`Didn't set nav root: ${err}`);
});
}
}

CSS : Transition list to left when clicked on delete icon

I'm developing an mobile application using ionic. In this I'm trying to implement the delete feature like this :
As we see there is icon on left-side of the every list item, when clicked on that icon, list transitions to left-side and delete button gets displayed on the screen.
I want to implement the same feature..But not able to write the right CSS. Please guide me how should I make this work.
Here is the link to my plunkr
You can use ionic list directive.
<ion-list ng-controller="MyCtrl"
show-delete="shouldShowDelete"
show-reorder="shouldShowReorder"
can-swipe="listCanSwipe">
<ion-item ng-repeat="item in items"
class="item-thumbnail-left">
<img ng-src="{{item.img}}">
<h2>{{item.title}}</h2>
<p>{{item.description}}</p>
<ion-option-button class="button-positive"
ng-click="share(item)">
Share
</ion-option-button>
<ion-option-button class="button-info"
ng-click="edit(item)">
Edit
</ion-option-button>
<ion-delete-button class="ion-minus-circled"
ng-click="items.splice($index, 1)">
</ion-delete-button>
<ion-reorder-button class="ion-navicon"
on-reorder="reorderItem(item, $fromIndex, $toIndex)">
</ion-reorder-button>
</ion-item>
</ion-list>
Controller:
app.controller('MyCtrl', function($scope) {
$scope.shouldShowDelete = false;
$scope.shouldShowReorder = false;
$scope.listCanSwipe = true
});

refreshing GoogleMap on Angular 2 which is on a hidden component

Here is my problem : Maps inside a hidden div are not shown
possible solution :
<div [hidden]="!showMap">
<sebm-google-map #myMap></sebm-google-map>
</div>
<button (click)="showMap = true; myMap.triggerResize()">resize</button>
This could work with a simple 1 variable, in my case I have dynamic creation of theses div, so i cannot point to #myMap so easily
This is for calling triggerResize() on all <sebm-google-map> elements:
<div *ngFor="let item of items"> <!-- just some ngFor for demo -->
<button #myMap (click)="showMap = true; doTriggerResize()">resize</button>
</div>
#ViewChildren('myMap') viewChildren:QueryList;
doTriggerResize() {
this.viewChildren.toArray().forEach((e) {
e.triggerResize();
});
}

Add button to ionic footer in specific controller

I want to add some command button in two side of my ionic footer in many of my controller.
For example in FirstController I want Add and Edit button and in SecondController I want Remove and Send Button.
I add this to my main layout but this is static:
<div class="bar bar-footer bar-balanced">
<div class="title">My Program</div>
<button class="button button-outline button-light" ng-click="add()"><i class="ion-arrow-left-c"></i></button>
<button class="button button-outline button-light" ng-click="edit()"><i class="ion-arrow-right-c"></i></button>
</div>
Please guide me how to do this in ionic framework and angular.
Thanks for your attention
My approach :
Move your code for Add and Edit Buttons, and Remove and Send Button to different Service [1st and 2nd Service].
Create a middle man service, containing references to both of the services declared above [3rd Service].
this service will contain two generic methods, i.e. method1 and method2.
Now in your controllers, add reference to the 3rd Service.
yourApp.controller("myController", function(thirdService) {
$scope.thirdService = thirdService;
$scope.textForButton1 = "Text Based on Controller";
$scope.textForButton2 = "Text Based on Controller";
});
now, in your html :
<div class="bar bar-footer bar-balanced">
<div class="title">My Program</div>
<button class="button button-outline button-light" ng-click="thirdService.handleFirstButton()"><i class="ion-arrow-left-c">{{textForButton1}}</i></button>
<button class="button button-outline button-light" ng-click="thirdService.handleSecondButton()"><i class="ion-arrow-right-c">{{textForButton2}}</i></button>
</div>
Assuming that each of your controllers are mapped to pages referenced in different routes,
you can decide which method to invoke based on the route.
i.e. in your third Service :
app.service('thirdService', function($http, $location, $state) {
this.handleFirstButton = function() {
switch ($state.current.name.toString().toLowerCase().trim()) {
}
};
this.handleSecondButton = function() {
switch ($state.current.name.toString().toLowerCase().trim()) {
}
};
});
Just add your headers and footers to the view associated with the controller. In home.html...
<ion-header-bar class="bar bar-subheader" >
<h1 class="left">Home</h1>
</ion-header-bar>
<ion-content>
<ion-list>
etc...
</ion-list>
</ion-content>
<div class="bar bar-footer footer">
Footer Content including buttons
</div>
In your index.html, you'll have something like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
... etc ....
</head>
<body ng-app="myapp">
<ion-pane ng-controller="HeaderController">
<ion-header-bar class="bar-stable">
header content
</ion-header-bar>
<ion-content>
<ion-nav-view>
</ion-nav-view>
</ion-content>
</ion-pane>
</body>
</html>
Of course, be sure to configure your routes. (This is boilerplate routing for Ionic apps). In app.js....
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/')
$stateProvider.state('home', {
url: '/',
templateUrl: 'views/home.html',
controller: 'HomeController'
})
})
Controllers can be defined in the normal way, possibly using Services to share functions between controllers.