iOS 11中拖放功能的简单示例

我们简要地看到了苹果几个月前在其WWDC中引入的拖放功能。 今天,我们将通过示例代码对功能进行更深入的了解。

我们将看到如何在视图和表视图中实现拖放功能。 创建一个新项目并添加2个选项View和TableView。 当用户选择“自定义视图”选项时,导航至CustomViewController并设计如下所示的UI。

在此屏幕中,我们将执行从一个imageView到另一个imageView的拖动,以及从一个textView文本到另一个textView的拖动。

首先,为imageView启用用户交互。 然后,我们需要使用DragInteraction委托为ImageView设置一个Drag交互。 仅在委托中,我们将指定要拖动的DragItem。

dragImageView.isUserInteractionEnabled = true

dropImageView.isUserInteractionEnabled = true

dragImageView.addInteraction(UIDragInteraction(delegate:self))

dragTextView.addInteraction(UIDragInteraction(delegate:self))

准备好拖动对象后,将调用以下委托方法。

func dragInteraction(_交互:UIDragInteraction,itemsForBeginning会话:UIDragSession)-> [UIDragItem]

我们将拖动要拖动的imageview和textview,因此代码实现如下。

func dragInteraction(_交互:UIDragInteraction,itemsForBeginning会话:UIDragSession)-> [UIDragItem] {如果让textValue = interact.view为? UITextView {让provider = NSItemProvider(object:textValue.text!as NSString)let item = UIDragItem(itemProvider:provider)返回[item]}如果让imageView = interact.view为? UIImageView {保护let image = imageView.image else {return []} let provider = NSItemProvider(object:image)let item = UIDragItem(itemProvider:provider)return [item]} return []

}

弹簧加载:

当我们将鼠标悬停在按钮上方时,这是为了识别按钮的动作。 拖动图像并悬停按钮后,它将取消隐藏放置区域。 像下面

dropOffButton.isSpringLoaded = true

拖放互动:

我们需要使用DropInteraction委托为ImageView设置Drop交互。 仅在委托中,我们将处理放置操作。

一旦拖动操作开始,下面的放置交互委托方法将被调用。

func dropInteraction(_交互:UIDropInteraction,sessionDidUpdate会话:UIDropSession)-> UIDropProposal

要检查图像或文本是否可以放在特定的帧中,请使用以下代码。

func dropInteraction(_交互:UIDropInteraction,sessionDidUpdate会话:UIDropSession)-> UIDropProposal {let location = session.location(in:self.view)let dropOperation:UIDropOperation? 如果session.canLoadObjects(ofClass:String.self){如果dropTextView.frame.contains(location){dropOperation = .copy}否则if dropImageView.frame.contains(location){dropOperation = .forbidden} else {dropOperation = .cancel} } else if session.canLoadObjects(ofClass:UIImage.self){if dropTextView.frame.contains(location){dropOperation = .forbidden} else if dropImageView.frame.contains(location){dropOperation = .copy} else {dropOperation =。取消}}其他{dropOperation = .cancel

}

返回UIDropProposal(操作:dropOperation!)
}

要执行放置操作,我们需要实现以下代码。

func dropInteraction(_交互:UIDropInteraction,performDrop会话:UIDropSession){如果session.canLoadObjects(ofClass:String.self){session.loadObjects(ofClass:String.self){(items)in if let values = items as? [String] {self.dropTextView.text = values.last}}} if session.canLoadObjects(ofClass:UIImage.self){session.loadObjects(ofClass:UIImage.self){(item)in if让images = items as ? [UIImage] {self.dropImageView.image = images.last}}

}

其次,我们将研究TablView拖放。

TableView拖放:

在表视图中,我们具有DataSource和Delegate方法,就像现在我们具有DragInteraction和DropInteraction委托方法。 在“表”视图中,拖放操作主要基于索引路径。

首先,我们需要设置一个拖放委托。

tableView.dragDelegate =自我
tableView.dropDelegate =自我

与在自定义视图中执行的方法类似,我们需要在拖动委托中指定拖动项。 这是通过以下方法完成的。

func tableView(_ tableView:UITableView,itemsForBeginning会话:UIDragSession,在indexPath:IndexPath)-> [UIDragItem]

要拖动一行,请遵循以下代码。

func tableView(_ tableView:UITableView,itemsForBeginning会话:UIDragSession,在indexPath:IndexPath)-> [UIDragItem] {让字符串= stringArray [indexPath.row]让itemProvider = NSItemProvider(对象:字符串为NSString)返回[UIDragItem(itemProvider: itemProvider)]

}

拖动动作开始后,屏幕将如下所示。

对于放置,我们需要检查表视图是否可以处理放置对象。 这将通过以下代码完成。

func tableView(_ tableView:UITableView,canHandle session:UIDropSession)-> Bool {返回session.canLoadObjects(ofClass:NSString.self)

}

一旦满足上述条件,则将调用以下委托方法。 在此委托方法中,我们将处理复制或移动操作到表格视图。

func tableView(_ tableView:UITableView,dropSessionDidUpdate会话:UIDropSession,withDestinationIndexPath destinationIndexPath:IndexPath?)-> UITableViewDropProposal {return UITableViewDropProposal(operation:.copy,intent:.automatic)

}

一旦对象准备好删除,则将调用以下委托方法。

func tableView(_ tableView:UITableView,performDropWith协调器:UITableViewDropCoordinator)

要处理Text的拖放操作,代码如下。

func tableView(_ tableView:UITableView,performDropWith协调器:UITableViewDropCoordinator){
让destinationPath:IndexPath

如果let indexPath = coordinator.destinationIndexPath {destinationPath = indexPath} else {let section = tableView.numberOfSections — 1 let row = tableView.numberOfRows(inSection:section)destinationPath = IndexPath(row:row,section:section)

}

coordinator.session.loadObjects(ofClass:NSString.self){(item)in if let values = items as? [String] {var indexPathArray = [indexPath]()for values.enumerated()中的(索引,项){let indexPath = IndexPath(row:destinationPath.row + index,section:destinationPath.section)self.stringArray.insert(项目,位于:indexPath.row)indexPathArray.append(indexPath)

}

tableView.insertRows(at:indexPathArray,with:.automatic)}}

}

在此博客中,我们已经看到了简单的拖放操作。 在我们即将发布的博客中,我们将看到如何在拖放中合并动画和自定义交互。 您可以在github中找到此示例程序的完整源代码。

Yogesh M,
iOS小组,
锦葵技术。