ios - UITableview: Cómo deshabilitar la selección para algunas filas pero no para otras
iphone objective-c (19)
A partir de iOS 6, puedes usar
-tableView:shouldHighLightRowAtIndexPath:
Si devuelve NO
, desactiva el resaltado de selección y los segmentos activados del guión gráfico conectados a esa celda.
El método se llama cuando un toque cae en una fila. Si se devuelve NO
a ese mensaje, se detiene el proceso de selección y no provoca que la fila actualmente seleccionada pierda su aspecto seleccionado mientras el toque está presionado.
Estoy mostrando en un grupo los contenidos de la vista de tableview
analizados desde XML. Quiero deshabilitar el evento click en él (no debería poder hacer clic en él) La tabla contiene dos grupos. Quiero deshabilitar la selección solo para el primer grupo, pero no para el segundo grupo. Al hacer clic en la primera fila del segundo grupo, navigates
a la player view
mi player view
tubos.
¿Cómo puedo hacer solo grupos específicos o filas seleccionables?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section!=0)
if(indexPath.row==0)
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:tubeUrl]];
}
Gracias.
Encontré esto útil ya que funciona con tablas tanto estáticas como dinámicas. Solo establezco el indicador de divulgación en las celdas que quiero permitir la selección.
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType != UITableViewCellAccessoryDisclosureIndicator) {
return nil;
}
return indexPath;
}
Implemente solo el método tableView:willSelectRowAtIndexPath:
en el origen de datos de su tabla. Si desea que se resalte la fila en la ruta, devuelva el indexPath dado. Si no lo haces, devuelve nil.
Ejemplo de mi aplicación:
- (NSIndexPath *)tableView:(UITableView *)tableView
willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MySelectableObj* obj = [self objectAtPath:indexPath];
if(obj==nil) return nil;
return indexPath;
}
Lo bueno de esto es que shouldPerformSegueWithIdentifier:sender:
no se llamará si el método anterior devuelve nulo, aunque repito la prueba anterior solo para completar.
Me gusta la respuesta de Brian Chapados arriba. Sin embargo, esto significa que puede tener la lógica duplicada en cellForRowAtIndexPath y luego en willSelectRowAtIndexPath que puede perder la sincronización fácilmente. En lugar de duplicar la lógica, simplemente marque el selectionStyle:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.selectionStyle == UITableViewCellSelectionStyleNone)
return nil;
else
return indexPath;
}
Mi solución basada en el modelo de datos:
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
let rowDetails = viewModel.rowDetails(forIndexPath: indexPath)
return rowDetails.enabled ? indexPath : nil
}
func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
let rowDetails = viewModel.rowDetails(forIndexPath: indexPath)
return rowDetails.enabled
}
Ninguna de las respuestas anteriores realmente aborda el problema correctamente. La razón es que queremos deshabilitar la selección de la celda pero no necesariamente las subvistas dentro de la celda.
En mi caso, estaba presentando un UISwitch en el medio de la fila y quería desactivar la selección para el resto de la fila (que está vacía) pero no para el interruptor. La forma correcta de hacerlo es por lo tanto en el método
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
donde una declaración de la forma
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
desactiva la selección para la celda específica mientras que al mismo tiempo permite al usuario manipular el interruptor y, por lo tanto, utilizar el selector apropiado. Esto no es cierto si alguien desactiva la interacción del usuario a través de
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Método que simplemente prepara la célula y no permite la interacción con el interruptor UIS.
Además, utilizando el método.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
con el fin de deseleccionar la celda con una declaración de la forma
[tableView deselectRowAtIndexPath:indexPath animated:NO];
aún muestra la fila que se está seleccionando mientras el usuario presiona en el contenido original Vista de la celda.
Sólo mis dos centavos. Estoy bastante seguro de que muchos encontrarán esto útil.
Para Swift 4.0 por ejemplo:
cell.isUserInteractionEnabled = false
cell.contentView.alpha = 0.5
Para Xcode 6.3:
cell.selectionStyle = UITableViewCellSelectionStyle.None;
Para detener solo algunas celdas seleccionadas use:
cell.userInteractionEnabled = NO;
Además de impedir la selección, esto también detiene tableView: didSelectRowAtIndexPath: se llama para las celdas que lo tienen establecido.
Para swift:
cell.selectionStyle = .None
cell.userInteractionEnabled = false
Puede utilizar el método tableView:willDisplayCell
para realizar todos los tipos de personalización de un tableViewCell.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell setUserInteractionEnabled:NO];
if (indexPath.section == 1 && indexPath.row == 0)
{
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
[cell setUserInteractionEnabled:YES];
}
}
En este código anterior, el usuario solo puede seleccionar la primera fila en la segunda sección de tableView. El resto de todas las filas no se pueden seleccionar. Gracias! ~
Se atrapan las selecciones con estos métodos de fuente de datos.
– tableView:willSelectRowAtIndexPath:
– tableView:didSelectRowAtIndexPath:
– tableView:willDeselectRowAtIndexPath:
– tableView:didDeselectRowAtIndexPath:
En estos métodos, verifica si la fila seleccionada es la que desea seleccionar. Si es así, realice una acción, si no, no haga nada.
Desafortunadamente, no puede desactivar la selección para una sola sección. Es toda la mesa o nada.
Sin embargo, puede establecer la propiedad selectionStyle
celdas de tabla en UITableViewCellSelectionStyleNone
. Creo que eso hará que la selección sea invisible. Combinado con los métodos anteriores que deberían hacer que las células se vean completamente inertes desde la perspectiva del usuario.
Edit01:
Si tiene una tabla en la que solo algunas de las filas son seleccionables, es importante que las celdas de las filas seleccionables sean visualmente distintas de las filas no seleccionables. El botón accesorio chevron es la forma predeterminada de hacer esto.
Como quiera que lo hagas, no quieres que tus usuarios intenten seleccionar filas y piensan que la aplicación ha funcionado mal porque la fila no hace nada.
Si desea que una fila (o un subconjunto de filas) no sea seleccionable , implemente el método -tableView:willSelectRowAtIndexPath:
(también mencionado por TechZen). Si no se puede seleccionar indexPath
, devuelva nil
, de lo contrario, devuelva indexPath
. Para obtener el comportamiento de selección predeterminado, simplemente devuelve el indexPath
pasado a su método de delegate
, pero también puede modificar la selección de la fila devolviendo un indexPath
diferente.
ejemplo:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// rows in section 0 should not be selectable
if ( indexPath.section == 0 ) return nil;
// first 3 rows in any section should not be selectable
if ( indexPath.row <= 2 ) return nil;
// By default, allow row to be selected
return indexPath;
}
Solo tienes que poner este código en cellForRowAtIndexPath
Para deshabilitar la propiedad de selección de la celda: (mientras toca la celda)
cell.selectionStyle = UITableViewCellSelectionStyleNone;
Para habilitar poder seleccionar (tocar) la celda: (tocando la celda)
// Default style
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
// Gray style
cell.selectionStyle = UITableViewCellSelectionStyleGray;
Tenga en cuenta que una celda con selectionStyle = UITableViewCellSelectionStyleNone;
seguirá causando que la IU llame a didSelectRowAtIndexPath
cuando sea tocada por el usuario. Para evitar esto, haga lo que se sugiere a continuación y establezca.
cell.userInteractionEnabled = NO;
en lugar. También tenga en cuenta que es posible que desee establecer cell.textLabel.enabled = NO;
para atenuar el elemento.
Use esto para hacer que la celda se vea como deshabilitada y no seleccionable:
cell.selectionStyle = UITableViewCellSelectionStyleNone;
Importante: tenga en cuenta que esto es solo una propiedad de estilo, y en realidad no deshabilita la celda. Para hacer eso, debes verificar la selectionStyle
en tu didSelectRowAtIndexPath:
implementación delegada:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.selectionStyle == UITableViewCellSelectionStyleNone) {
return;
}
// do your cell selection handling here
}
en Xcode 7 sin codificar simplemente puedes hacer lo siguiente:
En la vista de esquema, seleccione Celda de vista de tabla. (La celda está anidada en Vista de tabla Controlador Escena> Controlador de vista de tabla> Vista de tabla. Es posible que tenga que revelar esos objetos para ver la celda de vista de tabla)
En el inspector de atributos, busque el campo etiquetado Selección y seleccione Ninguno. inspector de atributos Con esta opción, la celda no tendrá un resaltado visual cuando un usuario la toque.
para Swift 3.0, puede usar el siguiente código para deshabilitar la interacción del usuario en la celda UITableView
cell.isUserInteractionEnabled = false
cellForRowAtIndexPath
hacer algo como lo siguiente para deshabilitar la selección de celdas dentro del método cellForRowAtIndexPath
:
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell setUserInteractionEnabled:NO];
Para mostrar la celda en gris, coloque lo siguiente dentro del tableView:WillDisplayCell:forRowAtIndexPath
:
[cell setAlpha:0.5];
Un método le permite controlar la interactividad, el otro le permite controlar la apariencia de la interfaz de usuario.
SENCILLO
Simplemente use cell.userInteractionEnabled = YES;
a la celda si puede navegar y cell.userInteractionEnabled = NO;
de otra manera