Как и многие здешние читатели, я смотрел сессию WWDC 2017, посвященную новым методам перетаскивания, доступным в iOS 11.x, и с интересом размышлял о том, какое простое приложение я мог бы создать, чтобы получить некоторый практический опыт работы с эти новые методы.
Когда я играл в шахматы с моим сыном, у меня случился момент озарения. Я знаю, я думал, что пишу простую онлайн-игру в шахматы, приложение, которое потребует от меня перетаскивания изображений по экрану, в данном случае шахматных фигур. Итак, в воскресенье днем я собрал это вместе и решил поделиться с вами историей в процессе.
Начнем с изображения, это была моя цель; и будет конечным результатом, если вам удастся следовать этому короткому руководству.
Это немного грубо по краям, но важна концепция/код. Конечно, на этом изображении этого не видно, но вы можете перетаскивать шахматные фигуры по доске.
Чтобы построить это, вам нужно сначала создать приложение с одним представлением и получить несколько изображений. Один из моих любимых веб-сайтов для такого рода вещей — https://thenounproject.com, где они утверждают, что у них есть иконки для всего. Я нашел и скачал набор шахмат, сделанный [email protected] и пошел оттуда, это его шахматные фигуры, которые вы видите на изображении выше.
Я скопировал изображения в Assets.xcassets и создал простой цикл в моем viewDidLoad, чтобы создать доску и поместить в нее части. Код выглядит так.
var image2M: UIImageView! var image2A:[UIImageView] = [] var sourceIndex: Int! var objectIndex: Int! let cpieces = [0:”wCastle”,1:”wKnight”,2:”wBishop”,3:”wQueen”,4:”wKing”,5:”wBishop”,6:”wKnight”,7:”wCastle”,8:”wPawn”,9:”wPawn”,10:”wPawn”,11:”wPawn”,12:”wPawn”,13:”wPawn”,14:”wPawn”,15:”wPawn”,48:”bPawn”,49:”bPawn”,50:”bPawn”,51:”bPawn”,52:”bPawn”,53:”bPawn”,54:”bPawn”,55:”bPawn”,56:”bCastle”,57:”bKnight”,58:”bBishop”,59:”bQueen”,60:”bKing”,61:”bBishop”,62:”bKnight”,63:”bCastle”] var imageIndex = 0 let midX = self.view.bounds.midX — (8 * 64) / 2 let midY = self.view.bounds.midY — (8 * 64) / 2 for Xloop in 0..<8 { for Yloop in 0..<8 { let image2D = UIImageView(frame: CGRect(x: Int(midX + CGFloat(Xloop) * 64), y: Int(midY + CGFloat(Yloop) * 64), width: 64, height: 64)) image2D.layer.borderColor = UIColor.black.cgColor image2D.layer.borderWidth = 1 image2D.isUserInteractionEnabled = true image2D.tag = imageIndex if cpieces[imageIndex] != nil { image2D.image = UIImage(named: cpieces[imageIndex]!) } imageIndex = imageIndex + 1 self.view.addSubview(image2D) image2A.append(image2D) } }
Я хочу, чтобы доска находилась в центре экрана, отсюда и строки view.bounds, и я хотел создать доску как можно быстрее и проще, поэтому я просто добавляю к ней 64 UIImageViews с границами. Словарь хорошо помог мне расставить шахматные фигуры. Требования к массиву и тегу станут более очевидными по мере продвижения вперед.
Что касается интересной части, то если вы скопируете и вставите этот код в свой ViewController, у вас не будет ничего, кроме статической шахматной доски. Чтобы сделать его интерактивным, мне нужно было добавить в VC как UIDropInteractionDelegate, так и UIDragInteractionDelegate.
После этого вам нужно добавить эти четыре строки в цикл image2D, показанный выше.
let dragInteraction = UIDragInteraction(delegate: self) image2D.addInteraction(dragInteraction) let dropInteraction = UIDropInteraction(delegate: self) image2D.addInteraction(dropInteraction)
И затем вы добавляете свои методы перетаскивания.
func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] { image2M = interaction.view as? UIImageView sourceIndex = image2M.tag let image = image2M.image let provider = NSItemProvider(object: image!) let item = UIDragItem(itemProvider: provider) item.localObject = image print(“sourceIndex \(sourceIndex)”) return [item] }
Это захватывает выбранное изображение, а также квадрат, на котором оно находится прямо сейчас, с тегом для imageView, содержащим индекс UIImageArray, в котором он находится.
Нам также нужно добавить еще два метода для захвата действия перетаскивания.
func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) { session.loadObjects(ofClass: UIImage.self) { imageItems in let images = imageItems as! [UIImage] let dropLocation:CGPoint = session.location(in: self.view) for image2X in self.image2A { if (image2X.frame.contains(dropLocation) ) { image2X.image = images.first self.objectIndex = image2X.tag print(“objectIndex \(self.objectIndex)”) self.image2M.image = nil } } } }
Это получает изображение, на которое вы перетащили, и dropLocation, на которое вам нужно его поместить. Затем он использует свой массив квадратов, чтобы найти ссылку на тот, на который вы поместили свое изображение, прежде чем поместить его туда, и снова отметить номер индекса изображения, который вы также переместили.
func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal { return UIDropProposal(operation: .move) }
Что подводит нас к концу... если вы скопируете и вставите этот код в новый проект, вы должны получить очень простую шахматную партию. Посмотрите часть II, если вам понравился этот пост.