【问题标题】:ios - reorder items in uitableview and apply changes to sqlite databaseios - 重新排序 uitableview 中的项目并将更改应用于 sqlite 数据库
【发布时间】:2013-11-19 18:36:29
【问题描述】:

我正在尝试重新排序表格视图 - 已设置 canMoveRowAtIndexPath 和 moveRowAtIndexPath 以便在我处于编辑模式时可以拖动单元格,但我需要基本上在我的 sqlite 数据库中镜像这些更改有。我有一个名为“orderid”的列,我用它来跟踪单元格的顺序。我的方法是基本上将要移动的单元格设置为 orderid=9999,然后从其余受影响单元格的 orderid 中加或减 1,然后将新单元格设置为其目标 orderid。我认为这可能是一个 sql 错误,但我无法弄清楚。如果有人有任何建议,将不胜感激。

这些是我的方法:

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
 - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{

long source = (long)sourceIndexPath.row;
long dest = (long)destinationIndexPath.row;

source++;
dest++;

//reorder in db
NSString *sql;
if (source>dest) {
    sql = [NSString stringWithFormat:@"UPDATE entries SET orderid=9999 where orderid=%ld; update entries set orderid = orderid + 1 where orderid<%ld AND orderid>=%ld update entries set orderid=%ld where orderid=9999", source, source,dest, dest];
} else if (source<dest){
    sql = [NSString stringWithFormat:@"UPDATE entries SET orderid=9999 where orderid=%ld; update entries set orderid = orderid - 1 where orderid BETWEEN orderid>%ld AND orderid<=%ld; update entries set orderid=%ld where orderid=9999", source, source, dest, dest];
}

NSLog(@"%@", sql);

char *err;
if (sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) !=SQLITE_OK) {
    sqlite3_close(db);
    NSLog(@"could not reorder");
} else {
    NSLog(@"rows reordered");
}


}

【问题讨论】:

    标签: ios sql objective-c sqlite


    【解决方案1】:

    我正在使用 pageOrder 在我的 pages 表中创建一个订单。这是表:

    .s pages
    CREATE TABLE pages (              
    uuid INTEGER PRIMARY KEY,              
    name TEXT,              
    pageOrder INTEGER DEFAULT 0              
    );
    

    代码如下:

    int fromRow = [sourceIndexPath row];
    int toRow = [destinationIndexPath row];
    
    if (toRow != fromRow) {
    
      FMDatabase* db = [FMDatabase databaseWithPath:[appDelegate dbPath]];
      [db open];
    
      [db executeUpdate:@"UPDATE pages SET pageOrder = -? WHERE pageOrder = ?",
       [NSNumber numberWithInt:toRow + 1],
       [NSNumber numberWithInt:fromRow + 1]];
    
      if (toRow < fromRow) {
    
        [db executeUpdate:@"UPDATE pages SET pageOrder = pageOrder + 1 WHERE pageOrder > ? AND pageOrder <= ?",
         [NSNumber numberWithInt:toRow],
         [NSNumber numberWithInt:fromRow]];
    
    
      } else {
    
        [db executeUpdate:@"UPDATE pages SET pageOrder = pageOrder - 1 WHERE pageOrder > ? AND pageOrder <= ?",
         [NSNumber numberWithInt:fromRow],
         [NSNumber numberWithInt:toRow + 1]];
    
      }
    
      [db executeUpdate:@"UPDATE pages SET pageOrder = abs(pageOrder) WHERE pageOrder < 0"];
    
      [db close];
    
    }
    

    应该可以了,

    干杯,

    涡流

    【讨论】:

      【解决方案2】:

      如果您的 tableView 中的 numberOfRows 与数据库中的条目数不匹配,一种可能性可能是:如果您在 tableView 底部有一个“添加新行...”单元格,那么您可能遇到麻烦,就像我过去一样。我的麻烦是tableView:moveRowAtIndexPath:toIndexPath 返回了错误的sourceIndexPath。两种解决方案都解决了这个问题。第一个解决方案:在tableView:moveRowAtIndexPath:toIndexPath: 中调用[tableview reloadData],您可能会丢失行动画,但您将保留功能并且sourceIndexPath/destinationIndexPath 将被更新。第二种解决方案:不要使用底部的“添加新行...”单元格并找到要添加的替代解决方案。祝你好运!

      【讨论】:

        【解决方案3】:

        我建议使用 float order_id。当用户重新排序项目时,获取上一个和下一个项目的 order_id,获取它们的平均值(浮点数)并保存到数据库。这样,您只需要更新重新订购的商品。

        【讨论】:

          【解决方案4】:

          这对我来说很好用!

          - (void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)targetIndexPath{
          
          // Define las variables a utilizar: IDorigen hace referencia al ID que tiene la fila antes de moverse e IDDestino hace referencia al ID que va a tener la fila luego de moverse
          int IDorigen = (int)[sourceIndexPath row]+1;
          int IDdestino = (int)[targetIndexPath row]+1;
          int diferencia;
          
          // Define la variable de consulta sobre la base de datos
          NSString *consulta;
          
          
          // Si el IDorigen es menor al IDdestino (es decir, mueve una fila hacia abajo)
          if (IDorigen < IDdestino)
          {
              // Obtiene la diferencia para saber cuantas filas hay entre IDdestino e IDOrigen
              diferencia = IDdestino - IDorigen;
          
              // Hace un FOR desde cero hasta diferencia, y a cada fila que encuentra le pone el ID=9000+i. Esto se hace para mandar las filas invoulucradas en el movimientohacia abajo de todo y evitar conflictos de ID
              for (int i=0;i<diferencia;i++){
          
                  // Define la consulta
                  consulta = [NSString stringWithFormat:@"update homeTabla set ID=%d where ID=%d", 9000+i,IDorigen+1+i];
          
                  // Ejecuta la consulta
                  [self.dbTouchMeCIS executeQuery:consulta];
              }
          
              // Cuando finaliza el FOR, le asigna a la fila que se está moviendo, el IDdestino deseado definiendo la consulta
              consulta = [NSString stringWithFormat:@"update homeTabla set ID=%d where ID=%d", IDdestino,IDorigen];
          
              // Ejecuta la consulta
              [self.dbTouchMeCIS executeQuery:consulta];
          
              // Hace un FOR para asignarle el valor que corresponde a aquellas filas que se le asigno el ID=9000+i
              for (int i=0;i<diferencia;i++){
          
                  // Define la consulta
                  consulta = [NSString stringWithFormat:@"update homeTabla set ID=%d where ID=%d",IDorigen+i,9000+i];
          
                  // Ejecuta la consulta
                  [self.dbTouchMeCIS executeQuery:consulta];
              }
          
          // Si el IDorigen es mayor al IDdestino (es decir, mueve una fila hacia arriba)
          }else if (IDorigen > IDdestino){
          
              // Obtiene la diferencia para saber cuantas filas hay entre IDdestino e IDOrigen
              diferencia = IDorigen - IDdestino;
          
              // Hace un FOR desde cero hasta diferencia, y a cada fila que encuentra le pone el ID=9000+i. Esto se hace para mandar las filas involucradas en el movimiento hacia abajo de todo y evitar conflictos de ID
              for (int i=0;i<diferencia;i++){
          
                  // Define la consulta
                  consulta = [NSString stringWithFormat:@"update homeTabla set ID=%d where ID=%d", 9000+i,IDdestino+i];
          
                  // Ejecuta la consulta
                  [self.dbTouchMeCIS executeQuery:consulta];
              }
          
              // Cuando finaliza el FOR, le asigna a la fila que se está moviendo, el IDdestino deseado definiendo la consulta
              consulta = [NSString stringWithFormat:@"update homeTabla set ID=%d where ID=%d", IDdestino,IDorigen];
          
              // Ejecuta la consulta
              [self.dbTouchMeCIS executeQuery:consulta];
          
              // Hace un FOR para asignarle el valor que corresponde a aquellas filas que se le asigno el ID=9000+i
              for (int i=0;i<diferencia;i++){
          
                  // Define la consulta
                  consulta = [NSString stringWithFormat:@"update homeTabla set ID=%d where ID=%d",IDdestino+1+i,9000+i];
          
                  // Ejecuta la consulta
                  [self.dbTouchMeCIS executeQuery:consulta];
              }
          
          }
          
          // Recarga la base de datos en la tabla una vez finalizado el movimiento
          [self recargarDatos];
          
          }
          

          【讨论】:

            猜你喜欢
            • 2013-02-25
            • 2022-01-21
            • 1970-01-01
            • 1970-01-01
            • 2012-10-27
            • 2013-08-03
            • 2015-01-27
            • 1970-01-01
            • 2020-07-19
            相关资源
            最近更新 更多