Ios 如何拖动UIView元素并更改位置?

Ios 如何拖动UIView元素并更改位置?,ios,objective-c,uiview,drag,uipangesturerecognizer,Ios,Objective C,Uiview,Drag,Uipangesturerecognizer,我正在开发一个允许用户创建表单的iOS应用程序。表单的UIView元素数存储在堆栈中的UIScrollView中。就编辑而言,UIView应该改变顺序 我如何做到这一点?我想拖动任何UIView组件并将其移动到表单中的任何位置。例如,保持第三个元素将激活自身以移动。在第二个元素上移动它将替换其位置。我正在使用平移手势移动视图。现在,我如何知道点击的视图是否位于任何UIView的顶部?据我所知,您希望用户能够在父视图中移动/重新定位某些UIView,如拖放 我建议您使用collectionView

我正在开发一个允许用户创建表单的iOS应用程序。表单的UIView元素数存储在堆栈中的UIScrollView中。就编辑而言,UIView应该改变顺序


我如何做到这一点?我想拖动任何UIView组件并将其移动到表单中的任何位置。例如,保持第三个元素将激活自身以移动。在第二个元素上移动它将替换其位置。我正在使用平移手势移动视图。现在,我如何知道点击的视图是否位于任何UIView的顶部?

据我所知,您希望用户能够在父视图中移动/重新定位某些UIView,如拖放

我建议您使用
collectionView
并启用其交互式移动功能。如果你想使用一些图书馆,那么你可以试试

或者对于
ui视图
拖放实现,您可以检查此项

据我所知,您希望用户能够在父视图中移动/重新定位某些UI视图,如拖放

我建议您使用
collectionView
并启用其交互式移动功能。如果你想使用一些图书馆,那么你可以试试

或者对于
ui视图
拖放实现,您可以检查此项

对于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
    }
}

对于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
    }
}
然后,您可以通过响应UIControlEventTouchDragInside事件将车辆移动到您想要的任何位置,例如:

 - (IBAction) imageMoved:(id) sender withEvent:(UIEvent *) event
 {
CGPoint point = [[[event allTouches] anyObject] locationInView:self.view];
UIControl *control = sender;
control.center = point;
}
然后,您可以通过响应UIControlEventTouchDragInside事件将车辆移动到您想要的任何位置,例如:

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

这应该是一个注释,而不是答案。我现在不能使用collectionView,因为我已经编写了很多代码来处理表单编辑。我现在只需要重新排列添加到UIScrollView中的UIView。@I请更正!!但是我没有添加评论的特权:)@HirenPrajapati看看这应该是一个评论,而不是一个答案。我现在不能使用collectionView,因为我已经写了很多代码来处理表单编辑。我现在只需要重新排列添加到UIScrollView中的UIView。@I请更正!!但是没有添加评论的特权:)@HirenPrajapati查看一下UITableview单元格的重新排序我想我提到过目标cI,我正在使用平移手势移动UIView。现在我怎么知道点击的视图是否位于任何UIView之上?如果您只需要重新订购东西,则无需考虑太多。对不起,斯威夫特,因为我更喜欢斯威夫特,而不是objective-c:)干杯,伙计,我希望这会有帮助。我想我提到过objective cI,我正在使用平移手势来移动视图。现在我怎么知道点击的视图是否位于任何UIView之上?如果您只需要重新订购东西,则无需考虑太多。我为斯威夫特感到抱歉,因为我更喜欢斯威夫特,而不是目标-c:)干杯,伙计,我希望这能有所帮助。