#swift #uiscrollview #uicollectionview #swift-protocols
#быстрый #uiscrollview uiscrollview #uicollectionview uicollectionview #swift-протоколы
Вопрос:
Я пытаюсь реализовать реализацию по умолчанию для UIScrollViewDelegate
метода:
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
используя protocol
.
Если я помещаю этот метод внутри класса, он вызывается; однако, если я пытаюсь использовать в качестве реализации по умолчанию via protocol
, он никогда не вызывается.
Код:
protocol DefaultScrollViewEndDragging {
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
}
extension DefaultScrollViewEndDragging {
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
print("scrollViewWillEndDragging is called")
// THIS IS NEVER CALLED
}
}
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, DefaultScrollViewEndDragging {
@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
collectionView.dataSource = self
collectionView.delegate = self
collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
print("Cell (indexPath.row)")
cell.contentView.backgroundColor = .orange
return cell
}
}
Что я делаю не так?
Ответ №1:
Я думаю, вы ищете что-то вроде этого
protocol DefaultScrollViewEndDragging : UIScrollViewDelegate {
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
}
extension DefaultScrollViewEndDragging {
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
print("scrollViewWillEndDragging is called")
// THIS IS NEVER CALLED
}
}
К сожалению, расширения протокола недоступны Obj-C. поэтому он не вызывается scrollViewWillEndDragging
Из заметки
Опять же, единственным исключением из этого правила являются расширения протокола. В отличие от любой другой конструкции в языке, методы расширения протокола отправляются статически в ситуации, когда виртуальная отправка приведет к другим результатам. Никакая ошибка компилятора не предотвращает это несоответствие. https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/001707.html
Комментарии:
1. @user1107173 К сожалению, расширения протокола недоступны Obj-C. поэтому он не вызывается
scrollViewWillEndDragging
2. @user1107173 пожалуйста, проверьте мой обновленный ответ. если у вас все еще есть путаница в какой-либо части, дайте мне знать.
Ответ №2:
Правильный код
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UIScrollViewDelegate {
@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
collectionView.dataSource = self
collectionView.delegate = self
collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
print("Cell (indexPath.row)")
cell.contentView.backgroundColor = .orange
return cell
}
//MARK: scrollview Delegate Method
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
print("scrollViewWillEndDragging is called")
}
}
Комментарии:
1. Я упоминал в своем вопросе, что это работает таким образом. Я пытаюсь использовать его в качестве реализации по умолчанию.
2. что вы хотите сделать? это не будет работать так, как вы хотите. вы должны запустить метод протокола с помощью delegate.method() куда-нибудь, а затем он автоматически вызовет место, где вы реализуете этот метод. пожалуйста, отредактируйте свой запрос подробно, чего вы хотите достичь.