У меня проблема. У меня есть слово, оно разбито на буквы, у меня есть ячейки для сбора каждой буквы. Мне нужно убедиться, что каждое письмо перетаскивается в нужную ячейку и фиксируется там. В данный момент все буквы, перетаскиваемые в непонятную область на экране, будут видны.
ps, когда я перетаскиваю буквы одну за другой, они окажутся в верхнем левом углу. на экране будет видно
пс, а на другом экране будет показано, как это должно быть
Пожалуйста, помогите мне, есть идеи, как это реализовать? Заранее спасибо
ViewController.swift
import UIKit
class ViewController: UIViewController {
let cellID = "Cell"
let word = "Hello how?"
private var tiles: [TileView] = []
private var targets: [TargetView] = []
lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.minimumLineSpacing = 12
layout.minimumInteritemSpacing = 5
let collectionView1 = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView1.backgroundColor = .darkGray
collectionView1.translatesAutoresizingMaskIntoConstraints = false
collectionView1.isUserInteractionEnabled = true
return collectionView1
}()
let cellTest = CharCell()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .lightGray
setupCollectionView()
setCharWord()
}
func setupCollectionView() {
view.addSubview(collectionView)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(CharCell.self, forCellWithReuseIdentifier: cellID)
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16).isActive = true
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16).isActive = true
//collectionView.topAnchor.constraint(lessThanOrEqualTo: view.topAnchor, constant: 550).isActive = true //600
collectionView.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor, constant: -50).isActive = true //-70
collectionView.heightAnchor.constraint(greaterThanOrEqualToConstant: 700).isActive = true
collectionView.widthAnchor.constraint(greaterThanOrEqualToConstant: 100).isActive = true
collectionView.isUserInteractionEnabled = true
}
func setCharWord() {
for (_,letter) in word.enumerated() {
//if letter != " " {
let tile = TileView(letter: letter, sideLength: 44)
tile.center = CGPoint(x: CGFloat(Float.random(in: 100...300)) - (20 + 0) /*+ CGFloat(arc4random())*/ /*xOffset + CGFloat(index) * (20 + 0)*/, y: CGFloat(Float.random(in: 200...390) )/*UIScreen.main.bounds.size.height/4*/)
collectionView.addSubview(tile)
tile.dragDelegate = self
tiles.append(tile)
//}
}
for (_,letter) in word.enumerated() {
let target = TargetView(letter: letter, sideLength: 15)
targets.append(target)
}
}
func placeTile(tileView: TileView, targetView: TargetView) {
tileView.isMatch = true
targetView.isMatch = true
tileView.isUserInteractionEnabled = false
UIView.animate(withDuration: 0.35, delay: 0.0, options: UIView.AnimationOptions.curveEaseOut, animations: {
tileView.center = targetView.center
tileView.backgroundColor = .clear
targetView.transform = .identity
}, completion: {
(value: Bool) in
targetView.isHidden = true
})
}
}
extension ViewController: TileDragDelegateProtocol {
func tileView(tileView: TileView, didDragToPoint: CGPoint) {
var targetView: TargetView?
for tv in targets {
if tv.frame.contains(didDragToPoint) && !tv.isMatch {
targetView = tv
break
}
}
if let targetView = targetView {
//2 check if letter matches
if targetView.letter == tileView.letter {
//3
self.placeTile(tileView: tileView, targetView: targetView)
print("Success! You should place the tile here!")
//more stuff to do on success here
//self.checkValidate()
print("Check if the player has completed the phrase")
} else {
//4
UIView.animate(withDuration:0.35,
delay:0.00,
options :UIView.AnimationOptions.curveEaseOut,
animations: {
tileView.center = CGPoint(x: tileView.center.x,
y: tileView.center.y /*- (200)*/)
},
completion: nil)
print("Failure. Let the player know this tile doesn't belong here")
//more stuff to do on failure here
}
}
}
}
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegate,
UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return targets.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! CharCell
if targets[indexPath.item].letter != " " {
cell.label.text = targets[indexPath.item].text
} else {
cell.label.text = " "
}
//cell.label.text = tiles[indexPath.item].text
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 20, height: 30)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 400, left: 0, bottom: 0, right: 0)
}
func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
return true
}
}
2.TileView.swift
import UIKit
protocol TileDragDelegateProtocol {
func tileView(tileView: TileView, didDragToPoint: CGPoint)
}
class TileView: UILabel {
private var xOffset: CGFloat = 0.0
private var yOffset: CGFloat = 0.0
var dragDelegate: TileDragDelegateProtocol?
var letter: Character!
var isMatch = false
init(letter: Character, sideLength: CGFloat) {
self.letter = letter
super.init(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
self.backgroundColor = .red
self.textAlignment = .center
self.font = .boldSystemFont(ofSize: 60.0 / 3)
self.text = String(letter).uppercased()
self.textColor = .white
self.lineBreakMode = .byWordWrapping
self.adjustsFontSizeToFitWidth = true
self.translatesAutoresizingMaskIntoConstraints = true
self.isUserInteractionEnabled = true
self.layer.cornerRadius = 22
self.clipsToBounds = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let point = touch.location(in: self.superview)
xOffset = point.x - self.center.x
yOffset = point.y - self.center.y
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let point = touch.location(in: self.superview)
self.center = CGPoint(x: point.x - xOffset, y: point.y - yOffset)
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.touchesMoved(touches, with: event)
dragDelegate?.tileView(tileView: self, didDragToPoint: self.center)
}
}
TragetView.swift
import UIKit
class TargetView: UILabel {
var letter: Character!
var isMatch = false
init(letter: Character, sideLength: CGFloat) {
self.letter = letter
super.init(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
self.backgroundColor = .red
self.textAlignment = .center
self.font = .boldSystemFont(ofSize: 60.0 / 3)
self.text = "_"
self.textColor = .white
self.lineBreakMode = .byWordWrapping
self.adjustsFontSizeToFitWidth = true
self.isUserInteractionEnabled = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
CharCell.swift
import UIKit
class CharCell: UICollectionViewCell {
lazy var label: UILabel = {
let label = UILabel()
label.backgroundColor = .clear
label.textAlignment = .center
label.font = .boldSystemFont(ofSize: 18) //25
label.text = "A"
label.textColor = .white
label.numberOfLines = 3
label.isUserInteractionEnabled = true
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupCell()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupCell() {
backgroundColor = .red
label.frame = CGRect(x: 0, y: 1, width: frame.width , height: frame.height )
label.isUserInteractionEnabled = true
self.addSubview(label)
self.isUserInteractionEnabled = true
}
}