#ios #swift #uicollectionview #ios14 #uimenucontroller
#iOS #swift #uicollectionview #ios14 #uimenucontroller
Вопрос:
Есть несколько руководств о том, как использовать UIMenuController
inside UICollectionView
, но в iOS 14 это не рекомендуется:
// These methods provide support for copy/paste actions on cells.
// All three should be implemented if any are.
- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath API_DEPRECATED_WITH_REPLACEMENT("collectionView:contextMenuConfigurationForItemAtIndexPath:", ios(6.0, 13.0));
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender API_DEPRECATED_WITH_REPLACEMENT("collectionView:contextMenuConfigurationForItemAtIndexPath:", ios(6.0, 13.0));
- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender API_DEPRECATED_WITH_REPLACEMENT("collectionView:contextMenuConfigurationForItemAtIndexPath:", ios(6.0, 13.0));
В то же время UIMenuController
все еще существует в iOS 14. Как теперь использовать его для ячеек?
Ответ №1:
UICollectionViewDelegate не будет запускать те методы, которые вы публикуете после iOS 14. Но мы все еще можем получить firstResponder, который нужен UIMenuController из UIView. Хиты. UICollectionView по-прежнему является UIView
Полный код:
protocol Menuable {
func menuAction(_ sender: Any?)
}
class CustomCell: UICollectionViewCell, Menuable {
...
func menuAction(_ sender: Any?){...}
...
}
class MenuableCollectionView: UICollectionView {
var selectedIndexPath: IndexPath?
func setupLongpress() {
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressGesture(_:)))
self.addGestureRecognizer(longPressGesture)
}
func setupMenu() {
let menuItem = UIMenuItem(title: "action", action: #selector(menuAction(_:)))
UIMenuController.shared.menuItems = [menuItem]
UIMenuController.shared.update()
}
@objc func handleLongPressGesture(_ sender: UILongPressGestureRecognizer) {
let point = sender.location(in: self)
if sender.state == .began {
guard let indexPath = indexPathForItem(at: point) else {
return
}
selectedIndexPath = indexPath
becomeFirstResponder()
let cell = cellForItem(at: indexPath)
let x: CGFloat = cell?.frame.midX ?? point.x
let y: CGFloat = 10
let rect = CGRect(x: x, y: y, width: 10, height: 10)
if #available(iOS 13.0, *) {
UIMenuController.shared.showMenu(from: self, rect: rect)
} else {
UIMenuController.shared.setTargetRect(rect, in: self)
UIMenuController.shared.setMenuVisible(true, animated: true)
}
}
}
@objc func menuAction(_ sender: Any?) {
guard let indexPath = selectedIndexPath else {
return
}
let cell = cellForItem(at: indexPath) as? Menuable
cell?.menuAction(sender)
}
override var canBecomeFirstResponder: Bool {
return true
}
override open func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(menuAction(_:)) {
return true
} else {
return false
}
}
}
// you should call setupLongpress() and setupMenu() after collection view init.
Комментарии:
1. У вас есть источник для части «не будет запускаться после iOS 14»?