Nativescript: ListView item removes backgroundColor when pressed

Created on 19 Jul 2015  路  13Comments  路  Source: NativeScript/NativeScript

I have a Page with a ListView and itemTemplate. The template contains a GridLayout (one row, one column) with Image and overlapping text (title). The overlapping text is contained innside a StackLayout and has a certian background-color applied.

When tapping on the ListView item, the background-color I set, is gone, and replaced by nothing (transparent), the text is still there.
If I press another item in the list, the previous item gets its bg-color back, and the newly pressed item looses its bg-color.

I also tested by removing the image from the template and only leaving StackLayout and labels. By tapping the item, the bg-color becomes grey.

I could not find a way to remove the pressed-color on the listview item.

Either way, tapping listview item should not remove any style set on elements innside the template.

Most helpful comment

Unfortunately this is the default behavior of the iOS native control (UITableView). It changes the background of controls when selected. An easy way to solve the issue is to set selectionStyle for every cell to UITableViewCellSelectionStyleNone. It will disable all background changes to list view item on selection. This can be done with the help of itemLoading event of the NativeScript ListView control. Your code should look like the following:

<ListView itemLoading="listViewItemLoading" ../>
function listViewItemLoading(args) {
    var cell = args.ios;
    cell.selectionStyle = UITableViewCellSelectionStyle.UITableViewCellSelectionStyleNone;
}
exports.listViewItemLoading = listViewItemLoading;

All 13 comments

Can you attach or somehow share a small sample project that reproduces this behavior. Thanks in advance.

No problem, download link included. Should mention that I use 1.1.0 with iOS.

Run it as is, to see how it behaves in full. Then you can comment out the Image tag to see what happens in the background. I think it just overrides all background colors when tapped.

Download listview-glitch

Unfortunately this is the default behavior of the iOS native control (UITableView). It changes the background of controls when selected. An easy way to solve the issue is to set selectionStyle for every cell to UITableViewCellSelectionStyleNone. It will disable all background changes to list view item on selection. This can be done with the help of itemLoading event of the NativeScript ListView control. Your code should look like the following:

<ListView itemLoading="listViewItemLoading" ../>
function listViewItemLoading(args) {
    var cell = args.ios;
    cell.selectionStyle = UITableViewCellSelectionStyle.UITableViewCellSelectionStyleNone;
}
exports.listViewItemLoading = listViewItemLoading;

Great stuff. Your example works perfectly! Just what I needed. I really did not like the default behaviour, especially when it removes all bg-color on other elements.

Thanks a log for looking into this. Could this become a xml property in the future?

Since this is a platform (ios) specific property we do not plan to provide a xml way to set it. Also there is another problem - this property should be set to ListView.item (cell) and we do not have access to item via xml.

Ok no problem. Your solution works anyways. Thanks again.

Can this solution work for Angular as well? It seems not to be working. @nsndeck

@rsaf You can listen for these events in the component. This is the event you want and below is example code of this working.

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'
import { isIOS } from 'tns-core-modules/platform';

// Declare the var so typescript doesn't complain
declare var UITableViewCellSelectionStyle;

@Component({
  moduleId: module.id,
  selector: 'ns-list-view-example',
  templateUrl: './list-view-example.component.html',
  styleUrls: ['./list-view-example.component.css']
})
export class ListViewExampleComponent implements OnInit {

  @ViewChild('listView') listView: ElementRef;

  constructor() {
  }

  ngOnInit() {

    this.listView.nativeElement.addEventListener('itemLoading', ( args ) => {

      // check that platform is iOS
      if ( isIOS ) {
        const cell = args.ios;
        cell.selectionStyle = UITableViewCellSelectionStyle.UITableViewCellSelectionStyleNone;
      }

    });

  }

}

@FranciZ I can't seem to get that code working. I'm getting the error:

[native code]: ERROR TypeError: undefined is not an object (evaluating 'this.listView.nativeElement')

I've also tried changing your code to use a capital letter L like it is in my XML <ListView>

@ViewChild('ListView') listView: ElementRef;

I got it working in angular without using ViewChild by attaching a handler to the event through the XML

<ListView [items]="items" (itemLoading)="onItemLoading($event)">
import { isIOS } from 'tns-core-modules/platform';
declare var UITableViewCellSelectionStyle;
// ...
onItemLoading(args) {
    if (isIOS) {
        const iosCell = args.ios;
        iosCell.selectionStyle = UITableViewCellSelectionStyle.None;
    }
}

found from stack overflow here

^^ That works on latest native script.

Combining @nsndeck's answer and @CoreyCole , here's for typescript (no angular)

<ListView itemLoading="listViewItemLoading" ... />
declare var UITableViewCellSelectionStyle

export function listViewItemLoading(args) {
    const cell = args.ios
    cell.selectionStyle = UITableViewCellSelectionStyle.UITableViewCellSelectionStyleNone
}

I'm Workting with Angular + Nativescprit, How to do that with Andorid?

Was this page helpful?
0 / 5 - 0 ratings