2017-08-25 91 views
1

我正在開發一個允許用戶創建表單的iOS應用程序。表單中有多個存儲在UIScrollView中的UIView元素。就編輯而言,UIViews應該改變命令。如何拖動UIView元素並更改位置?

我該如何做到這一點?我想拖動任何UIView組件並將它移動到窗體中的任何位置。例如。持有第三元素將激活自己移動。將其移動到第二個元素將取代它的位置。我使用平移手勢來移動UIViews。現在我怎麼能知道在任何UIView的頂部到達了點擊視圖?

+0

https://github.com/bvogelzang/BVReorderTableView重新排序的UITableView –

回答

0

據我瞭解你的要求,你希望用戶能夠移動/重新定位一些UIViews像父視圖中的拖放。

我建議您使用collectionView啓用其交互式移動。如果你想使用一些庫,那麼你可以嘗試https://github.com/ra1028/RAReorderableLayout

或爲UIView拖&下降實現你可以檢查這個 https://blog.apoorvmote.com/uipangesturerecognizer-to-make-draggable-uiview-in-ios-swift/

+0

的細胞這應該是一個評論,不是答案。 – iPeter

+0

我現在不能使用collectionView,因爲我已經寫了很多代碼來處理表單編輯。我只需要重新排列在UIScrollView中添加的UIView。 –

+0

@iPeter正確!但沒有特權添加評論:) – Apogee

0

有用於UICollectionViewController幾個簡單的選項,可以通過canMoveItemAt委託方法 好辦如果你有一個視圖控制器,你可以通過以下方式嘗試:

import UIKit 

class LoveProfileEditViewViewController: BaseViewController { 
    fileprivate var longPressGesture:UILongPressGestureRecognizer! 
    @IBOutlet var theCollectionView:UICollectionView! 
    public var items:[String]! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     let horizontalLayout = UICollectionViewFlowLayout() 
     horizontalLayout.scrollDirection = .horizontal 
     self.theCollectionView.collectionViewLayout = horizontalLayout 
     self.theCollectionView.register(UINib(nibName: "SomeNibName", bundle: nil), forCellWithReuseIdentifier: "Some Identifier") 
     self.longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.handleLongGesture(gesture:))) 
     self.theCollectionView.addGestureRecognizer(longPressGesture) 
    } 

    fileprivate func moveDataItem(_ sIndex: Int, _ dIndex: Int) { 
     let item = self.items.remove(at: sIndex) 
     self.items.insert(item, at:dIndex) 
     self.theCollectionView.reloadData() 
    } 

    @objc private func handleLongGesture(gesture: UILongPressGestureRecognizer) { 
     switch(gesture.state) { 
     case UIGestureRecognizerState.began: 
      guard let selectedIndexPath = self.theCollectionView.indexPathForItem(at: gesture.location(in: self.theCollectionView)) else { 
       break 
      } 
      self.theCollectionView.beginInteractiveMovementForItem(at: selectedIndexPath) 

     case UIGestureRecognizerState.changed: 
      guard let selectedIndexPath = self.theCollectionView.indexPathForItem(at: gesture.location(in: self.theCollectionView)) else { 
       break 
      } 
      self.theCollectionView?.updateInteractiveMovementTargetPosition(gesture.location(in: gesture.view!)) 

     case UIGestureRecognizerState.ended: 
      self.theCollectionView.endInteractiveMovement() 
     default: 
      self.theCollectionView.cancelInteractiveMovement() 
     } 
    } 

} 

// MARK: - UICollectionViewDelegateFlowLayout 
extension LoveProfileEditViewViewController: UICollectionViewDelegateFlowLayout { 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
     return CGSize(width: 88.0, height: collectionView.bounds.size.height) 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { 
     return UIEdgeInsetsMake(0.0, 5.0, 0.0, 5.0) 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { 
     return 10.0 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { 
     return 10.0 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { 
     return .zero 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize { 
     return .zero 
    } 
} 

// MARK: - UICollectionViewDataSource 
extension LoveProfileEditViewViewController: UICollectionViewDataSource { 
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return self.items.count 
    } 

    func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool { 
     //set boolean as per your need 
     return true 
    } 

    func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) { 
     if sourceIndexPath.row > 0 && destinationIndexPath.row > 0 { 
      self.moveDataItem(sourceIndexPath.row, destinationIndexPath.row) 
     } 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Some Identifier", for: indexPath) as! SomeNibName 
     cell.textLabel.text = self.items[indexPath.row] 
     return cell 
    } 
} 
+0

我想我提到過objective-c –

+0

我正在使用平移手勢來移動UIViews。現在我怎麼能知道在任何UIView的頂部到達了點擊視圖? –

+0

如果您只需要重新訂購物品,則無需在這種情況下多加考慮。對不起,因爲我更快進入目標-c :) –

0
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 
[button addTarget:self action:@selector(imageTouch:withEvent:) 
forControlEvents:UIControlEventTouchDown]; 
[button addTarget:self action:@selector(imageMoved:withEvent:) 
forControlEvents:UIControlEventTouchDragInside]; 
[button setImage:[UIImage imageNamed:@"vehicle.png"] 
forState:UIControlStateNormal]; 
[self.view addSubview:button]; 

那麼無論你願意,你可以移動車輛,通過響應UIControlEventTouchDragInside事件,如:

- (IBAction) imageMoved:(id) sender withEvent:(UIEvent *) event 
{ 
CGPoint point = [[[event allTouches] anyObject] locationInView:self.view]; 
UIControl *control = sender; 
control.center = point; 
} 
+0

我已經使用UILongTapGestureRecognizer完成了它。 –