2015-10-31 5 views
6

У меня есть один tableView в моем раскадровке, где я добавил 4 статическую ячейку в ней и моей раскадровке выглядеть следующим образом:Как перетащить статическую ячейку в таблицуView swift?

enter image description here

У меня нет никакого DataSource для этого tableView, потому что мои клетки являются статическими.

И я использую ниже код для перетаскивания ячейки, и он работает нормально, пока я не прокручу таблицу.

import UIKit 

class TableViewController: UITableViewController { 

    var sourceIndexPath: NSIndexPath = NSIndexPath() 
    var snapshot: UIView = UIView() 
    let longPress: UILongPressGestureRecognizer = { 
     let recognizer = UILongPressGestureRecognizer() 
     return recognizer 
     }() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     longPress.addTarget(self, action: "longPressGestureRecognized:") 
     self.tableView.addGestureRecognizer(longPress) 

     self.tableView.allowsSelection = false 
    } 

    override func viewWillAppear(animated: Bool) { 

     self.tableView.reloadData() 
    } 

    // MARK: UIGestureRecognizer 
    func longPressGestureRecognized(gesture: UILongPressGestureRecognizer){ 

     let state: UIGestureRecognizerState = gesture.state 
     let location:CGPoint = gesture.locationInView(self.tableView) 
     if let indexPath: NSIndexPath = self.tableView.indexPathForRowAtPoint(location){ 

      switch(state){ 

      case UIGestureRecognizerState.Began: 
       sourceIndexPath = indexPath 

       let cell: UITableViewCell = self.tableView .cellForRowAtIndexPath(indexPath)! 

       //take a snapshot of the selected row using helper method 
       snapshot = customSnapshotFromView(cell) 

       //add snapshot as subview, centered at cell's center 
       var center: CGPoint = cell.center 
       snapshot.center = center 
       snapshot.alpha = 0.0 
       self.tableView.addSubview(snapshot) 
       UIView.animateWithDuration(0.25, animations: {() -> Void in 
        center.y = location.y 
        self.snapshot.center = center 
        self.snapshot.transform = CGAffineTransformMakeScale(1.05, 1.05) 
        self.snapshot.alpha = 0.98 
        cell.alpha = 0.0 
        }, completion: { (finished) in 
         cell.hidden = true 
       }) 

      case UIGestureRecognizerState.Changed: 
       let cell: UITableViewCell = self.tableView.cellForRowAtIndexPath(indexPath)! 

       var center: CGPoint = snapshot.center 
       center.y = location.y 
       snapshot.center = center 
       print("location \(location.y)") 

       //is destination valid and is it different form source? 
       if indexPath != sourceIndexPath{ 
        //update data source 
        //I have commented this part because I am not using any dataSource. 
//     self.customArray.exchangeObjectAtIndex(indexPath.row, withObjectAtIndex: sourceIndexPath.row) 
        //move the row 
        self.tableView.moveRowAtIndexPath(sourceIndexPath, toIndexPath: indexPath) 
        //and update source so it is in sync with UI changes 
        sourceIndexPath = indexPath 
       } 

       if (location.y < 68) || (location.y > 450) { 
        print("cancelled") 
        self.snapshot.alpha = 0.0 
        cell.hidden = false 
        UIView.animateWithDuration(0.10, animations: {() -> Void in 

         self.snapshot.center = cell.center 
         self.snapshot.transform = CGAffineTransformIdentity 
         self.snapshot.alpha = 0.0 
         //undo fade out 
         cell.alpha = 1.0 

         }, completion: { (finished) in 
          self.snapshot.removeFromSuperview() 
        }) 
       } 

      case UIGestureRecognizerState.Ended: 
       //clean up 
       print("ended") 
       let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)! 
       cell.hidden = false 

       UIView.animateWithDuration(0.25, animations: {() -> Void in 

        self.snapshot.center = cell.center 
        self.snapshot.transform = CGAffineTransformIdentity 
        self.snapshot.alpha = 0.0 
        //undo fade out 
        cell.alpha = 1.0 

        }, completion: { (finished) in 
         self.snapshot.removeFromSuperview() 
       }) 
       break 

      default: 
       break 
      } 
     }else{ 
      gesture.cancelsTouchesInView = true 
     } 
    } 

    func customSnapshotFromView(inputView: UIView) -> UIView { 

     // Make an image from the input view. 
     UIGraphicsBeginImageContextWithOptions(inputView.bounds.size, false, 0) 
     inputView.layer.renderInContext(UIGraphicsGetCurrentContext()!) 
     let image = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext(); 

     // Create an image view. 
     let snapshot = UIImageView(image: image) 
     snapshot.layer.masksToBounds = false 
     snapshot.layer.cornerRadius = 0.0 
     snapshot.layer.shadowOffset = CGSize(width: -5.0, height: 0.0) 
     snapshot.layer.shadowRadius = 5.0 
     snapshot.layer.shadowOpacity = 0.4 

     return snapshot 
    } 

} 

Когда я прокручиваю после перетаскивания это выглядит:

enter image description here

Как вы можете видеть, ячейка снова не появляется. Я хочу перетащить статическую ячейку, и я хочу сохранить ее положение, поэтому я не буду переключаться снова при прокрутке.

Sample проект для получения дополнительной информации.

Это всего лишь демонстрационный проект. Но я добавил много элементов в свою ячейку, и каждая ячейка имеет разные интерфейсы.

+0

Я не думаю, что вы можете подойти к нему без 'протокола UITableViewDataSource' –

ответ

2

Существует библиотека, которая делает именно то, что вы хотите сделать с очень похожим подходом. Это называется FMMoveTableView, но это для ячеек с источником данных.

Я думаю, что причиной вашей проблемы является то, что при перемещении ячеек, а затем прокрутка источника данных из раскадровки больше не синхронизируется с таблицей, и поэтому объект ячейки нельзя перерисовать.

Я думаю, вы должны реализовать ваш стол таким образом:

  1. Сделайте 4 ячейки пользовательских ячеек.
  2. Подкласс каждый.
  3. Создание массива с номерами от 1 до 4
  4. Переупорядочьте массив на затянулись
  5. Override cellForRowAtIndexPath показать правильную ячейку для правильного числа
+0

Да я могу сделать это, но я хочу сделать это со статической ячейкой, если возможно .. :) –

1

Вы можете создать несколько динамических ячейки. Вам просто нужно удалить ячейки с правильным идентификатором.

+0

Можете ли вы привести какой-нибудь пример? –

+0

Вместо создания 4 статических ячеек. Создайте 4 динамических ячейки и подключите dataSource tableView к вашему TVC. и в cellForRowAtIndexPathMethod dequeue соответствующие ячейки. например: предоставить ячейкам эти идентификаторы: cell1, cell2, cell3, cell4. , а затем в методе cellForRow выполните следующее: 'return tableView.dequeueReusableCellWithIdentifier ("cell \ (indexPath.row)")' – zurakach

+0

Вам также необходимо сохранить массив порядка ячеек. , а затем метод dequeue будет выглядеть так: return tableView.dequeueReusableCellWithIdentifier ("cell (cellOrderArray [indexPath.row])") – zurakach

1

Вы делаете это только для целей макета, может быть, UICollectionView или изготовленный на заказ UIScrollView мог бы выполнить эту работу?


Тем не менее, у меня есть решение:

  1. Создать коллекцию IBOutlet держит все ваши статические UITableViewCell s
  2. Создать список индексов для имитации "источник данных"
  3. Override cellForRowAtIndexPath сделать используя ваш собственный список индексов
  4. При обновлении порядка списка обновите indexList так, чтобы представление «запоминало» это изменение

Эта таблица-контроллер объясняет все:

class TableViewController: UITableViewController { 

    @IBOutlet var outletCells: [UITableViewCell]! 
    var indexList = [Int]() 

    override func viewDidLoad() { 
    super.viewDidLoad() 
    // Prepare a index list. 
    // We will move positions in this list instead 
    // of trying to move the view's postions. 
    for (index, _) in outletCells.enumerate() { 
     indexList.append(index) 
    } 
    } 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    // Use dynamic count, not needed I guess but 
    // feels better this way. 
    return outletCells.count 
    } 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    // Use the index path to get the true index and return 
    // the view on that index in our IBOutlet collection 
    let realIndexForPos = indexList[indexPath.row] 
    return outletCells[realIndexForPos] 
    } 

    @IBAction func onTap(sender: AnyObject) { 
    // Simulating your drag n drop stuff here... :) 
    let swapThis = 1 
    let swapThat = 2 

    tableView.moveRowAtIndexPath(NSIndexPath(forItem: swapThis, inSection: 0), toIndexPath: NSIndexPath(forItem: swapThat, inSection: 0)) 

    // Update the indexList as this is the "data source" 
    // Do no use moveRowAtIndexPath as this is never triggred 
    // This one line works: swap(&indexList[swapThis], &indexList[swapThat]) 
    // But bellow is easier to understand 
    let tmpVal = indexList[swapThis] 
    indexList[swapThis] = indexList[swapThat] 
    indexList[swapThat] = tmpVal 
    } 
} 

Чтобы создать IBOutlet использовать Interface Builder. Используйте Referencing Outlet Collection на каждой ячейке просмотра таблицы и перетащите, для каждого, то же самое @IBOutlet в свой код контроллера.

enter image description here

+0

Привет, Я сохранил исходный и целевой путь индекса в nsmutable массиве. Как я могу сохранить и изменить порядок моих tableview, открывая мое приложение. func tableView (tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) { let item: String = dataHolder [sourceIndexPath.row]; dataHolder.removeAtIndex (sourceIndexPath.row); dataHolder.insert (item, atIndex: destinationIndexPath.row) toArray.addObject (destinationIndexPath.row) fromArray.addObject (sourceIndexPath.row) } – Apple

2

Вы можете перетащить UITableView ячейки из UITableView делегатов ....... 1) установить стиль редактирования вид таблицы, чтобы ни в его делегатом.

2) осуществлять таблицу просмотра делегата для того, чтобы перетаскивание ячейки т.е. методов canMoveRowAtIndexPath ...

Смежные вопросы