//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;
#[cfg(feature = "objc2-core-foundation")]
use objc2_core_foundation::*;
use objc2_foundation::*;
#[cfg(feature = "objc2-quartz-core")]
#[cfg(not(target_os = "watchos"))]
use objc2_quartz_core::*;

use crate::*;

/// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewscrollposition?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct UICollectionViewScrollPosition(pub NSUInteger);
bitflags::bitflags! {
    impl UICollectionViewScrollPosition: NSUInteger {
        #[doc(alias = "UICollectionViewScrollPositionNone")]
        const None = 0;
        #[doc(alias = "UICollectionViewScrollPositionTop")]
        const Top = 1<<0;
        #[doc(alias = "UICollectionViewScrollPositionCenteredVertically")]
        const CenteredVertically = 1<<1;
        #[doc(alias = "UICollectionViewScrollPositionBottom")]
        const Bottom = 1<<2;
        #[doc(alias = "UICollectionViewScrollPositionLeft")]
        const Left = 1<<3;
        #[doc(alias = "UICollectionViewScrollPositionCenteredHorizontally")]
        const CenteredHorizontally = 1<<4;
        #[doc(alias = "UICollectionViewScrollPositionRight")]
        const Right = 1<<5;
    }
}

unsafe impl Encode for UICollectionViewScrollPosition {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for UICollectionViewScrollPosition {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewreorderingcadence?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct UICollectionViewReorderingCadence(pub NSInteger);
impl UICollectionViewReorderingCadence {
    #[doc(alias = "UICollectionViewReorderingCadenceImmediate")]
    pub const Immediate: Self = Self(0);
    #[doc(alias = "UICollectionViewReorderingCadenceFast")]
    pub const Fast: Self = Self(1);
    #[doc(alias = "UICollectionViewReorderingCadenceSlow")]
    pub const Slow: Self = Self(2);
}

unsafe impl Encode for UICollectionViewReorderingCadence {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for UICollectionViewReorderingCadence {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewselfsizinginvalidation?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct UICollectionViewSelfSizingInvalidation(pub NSInteger);
impl UICollectionViewSelfSizingInvalidation {
    /// No updates will take place when -invalidateIntrinsicContentSize is called on a self-sizing cell or its contentView.
    #[doc(alias = "UICollectionViewSelfSizingInvalidationDisabled")]
    pub const Disabled: Self = Self(0);
    /// Calling -invalidateIntrinsicContentSize on a self-sizing cell or its contentView will cause it to be resized if necessary.
    #[doc(alias = "UICollectionViewSelfSizingInvalidationEnabled")]
    pub const Enabled: Self = Self(1);
    /// Calling -invalidateIntrinsicContentSize on a self-sizing cell or its contentView will cause it to be resized if necessary, and
    /// any Auto Layout changes within the contentView of a self-sizing cell will automatically trigger -invalidateIntrinsicContentSize.
    #[doc(alias = "UICollectionViewSelfSizingInvalidationEnabledIncludingConstraints")]
    pub const EnabledIncludingConstraints: Self = Self(2);
}

unsafe impl Encode for UICollectionViewSelfSizingInvalidation {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for UICollectionViewSelfSizingInvalidation {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewlayoutinteractivetransitioncompletion?language=objc)
#[cfg(feature = "block2")]
pub type UICollectionViewLayoutInteractiveTransitionCompletion =
    *mut block2::DynBlock<dyn Fn(Bool, Bool)>;

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewfocusupdatecontext?language=objc)
    #[unsafe(super(UIFocusUpdateContext, NSObject))]
    #[thread_kind = MainThreadOnly]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(feature = "UIFocus")]
    pub struct UICollectionViewFocusUpdateContext;
);

#[cfg(feature = "UIFocus")]
extern_conformance!(
    unsafe impl NSObjectProtocol for UICollectionViewFocusUpdateContext {}
);

#[cfg(feature = "UIFocus")]
impl UICollectionViewFocusUpdateContext {
    extern_methods!(
        #[unsafe(method(previouslyFocusedIndexPath))]
        #[unsafe(method_family = none)]
        pub fn previouslyFocusedIndexPath(&self) -> Option<Retained<NSIndexPath>>;

        #[unsafe(method(nextFocusedIndexPath))]
        #[unsafe(method_family = none)]
        pub fn nextFocusedIndexPath(&self) -> Option<Retained<NSIndexPath>>;
    );
}

/// Methods declared on superclass `NSObject`.
#[cfg(feature = "UIFocus")]
impl UICollectionViewFocusUpdateContext {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new(mtm: MainThreadMarker) -> Retained<Self>;
    );
}

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewdatasource?language=objc)
    pub unsafe trait UICollectionViewDataSource: NSObjectProtocol + MainThreadOnly {
        #[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
        #[unsafe(method(collectionView:numberOfItemsInSection:))]
        #[unsafe(method_family = none)]
        fn collectionView_numberOfItemsInSection(
            &self,
            collection_view: &UICollectionView,
            section: NSInteger,
        ) -> NSInteger;

        #[cfg(all(
            feature = "UICollectionViewCell",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView"
        ))]
        #[unsafe(method(collectionView:cellForItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_cellForItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        ) -> Retained<UICollectionViewCell>;

        #[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
        #[optional]
        #[unsafe(method(numberOfSectionsInCollectionView:))]
        #[unsafe(method_family = none)]
        fn numberOfSectionsInCollectionView(&self, collection_view: &UICollectionView)
            -> NSInteger;

        #[cfg(all(
            feature = "UICollectionViewCell",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:viewForSupplementaryElementOfKind:atIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_viewForSupplementaryElementOfKind_atIndexPath(
            &self,
            collection_view: &UICollectionView,
            kind: &NSString,
            index_path: &NSIndexPath,
        ) -> Retained<UICollectionReusableView>;

        #[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:canMoveItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_canMoveItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        ) -> bool;

        #[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:moveItemAtIndexPath:toIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_moveItemAtIndexPath_toIndexPath(
            &self,
            collection_view: &UICollectionView,
            source_index_path: &NSIndexPath,
            destination_index_path: &NSIndexPath,
        );

        #[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
        /// Returns a list of index titles to display in the index view (e.g. ["A", "B", "C" ... "Z", "#"])
        #[optional]
        #[unsafe(method(indexTitlesForCollectionView:))]
        #[unsafe(method_family = none)]
        fn indexTitlesForCollectionView(
            &self,
            collection_view: &UICollectionView,
        ) -> Option<Retained<NSArray<NSString>>>;

        #[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
        /// Returns the index path that corresponds to the given title / index. (e.g. "B",1)
        /// Return an index path with a single index to indicate an entire section, instead of a specific item.
        #[optional]
        #[unsafe(method(collectionView:indexPathForIndexTitle:atIndex:))]
        #[unsafe(method_family = none)]
        fn collectionView_indexPathForIndexTitle_atIndex(
            &self,
            collection_view: &UICollectionView,
            title: &NSString,
            index: NSInteger,
        ) -> Retained<NSIndexPath>;
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewdatasourceprefetching?language=objc)
    pub unsafe trait UICollectionViewDataSourcePrefetching:
        NSObjectProtocol + MainThreadOnly
    {
        #[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
        #[unsafe(method(collectionView:prefetchItemsAtIndexPaths:))]
        #[unsafe(method_family = none)]
        fn collectionView_prefetchItemsAtIndexPaths(
            &self,
            collection_view: &UICollectionView,
            index_paths: &NSArray<NSIndexPath>,
        );

        #[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:cancelPrefetchingForItemsAtIndexPaths:))]
        #[unsafe(method_family = none)]
        fn collectionView_cancelPrefetchingForItemsAtIndexPaths(
            &self,
            collection_view: &UICollectionView,
            index_paths: &NSArray<NSIndexPath>,
        );
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewdelegate?language=objc)
    #[cfg(feature = "UIScrollView")]
    pub unsafe trait UICollectionViewDelegate:
        UIScrollViewDelegate + MainThreadOnly
    {
        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:shouldHighlightItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_shouldHighlightItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        ) -> bool;

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:didHighlightItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_didHighlightItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        );

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:didUnhighlightItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_didUnhighlightItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        );

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:shouldSelectItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_shouldSelectItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        ) -> bool;

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:shouldDeselectItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_shouldDeselectItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        ) -> bool;

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:didSelectItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_didSelectItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        );

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:didDeselectItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_didDeselectItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        );

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        /// Called to determine if a primary action can be performed for the item at the given indexPath.
        /// See
        /// `collectionView:performPrimaryActionForItemAtIndexPath:`for more details about primary actions.
        ///
        ///
        /// Parameter `collectionView`: This UICollectionView
        ///
        /// Parameter `indexPath`: NSIndexPath of the item
        ///
        ///
        /// Returns: `YES` if the primary action can be performed; otherwise `NO`. If not implemented, defaults to `YES` when not editing
        /// and `NO` when editing.
        #[optional]
        #[unsafe(method(collectionView:canPerformPrimaryActionForItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_canPerformPrimaryActionForItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        ) -> bool;

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        /// Called when the primary action should be performed for the item at the given indexPath.
        ///
        ///
        /// Primary actions allow you to distinguish between a change of selection (which can be based on focus changes or
        /// other indirect selection changes) and distinct user actions. Primary actions are performed when the user selects a cell without extending
        /// an existing selection. This is called after
        /// `shouldSelectItem`and
        /// `didSelectItem`, regardless of whether the cell's selection
        /// state was allowed to change.
        ///
        /// As an example, use
        /// `didSelectItemAtIndexPath`for updating state in the current view controller (i.e. buttons, title, etc) and
        /// use the primary action for navigation or showing another split view column.
        ///
        ///
        /// Parameter `collectionView`: This UICollectionView
        ///
        /// Parameter `indexPath`: NSIndexPath of the item to perform the action on
        #[optional]
        #[unsafe(method(collectionView:performPrimaryActionForItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_performPrimaryActionForItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        );

        #[cfg(all(
            feature = "UICollectionViewCell",
            feature = "UIResponder",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:willDisplayCell:forItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_willDisplayCell_forItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            cell: &UICollectionViewCell,
            index_path: &NSIndexPath,
        );

        #[cfg(all(
            feature = "UICollectionViewCell",
            feature = "UIResponder",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:willDisplaySupplementaryView:forElementKind:atIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_willDisplaySupplementaryView_forElementKind_atIndexPath(
            &self,
            collection_view: &UICollectionView,
            view: &UICollectionReusableView,
            element_kind: &NSString,
            index_path: &NSIndexPath,
        );

        #[cfg(all(
            feature = "UICollectionViewCell",
            feature = "UIResponder",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:didEndDisplayingCell:forItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_didEndDisplayingCell_forItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            cell: &UICollectionViewCell,
            index_path: &NSIndexPath,
        );

        #[cfg(all(
            feature = "UICollectionViewCell",
            feature = "UIResponder",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:didEndDisplayingSupplementaryView:forElementOfKind:atIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_didEndDisplayingSupplementaryView_forElementOfKind_atIndexPath(
            &self,
            collection_view: &UICollectionView,
            view: &UICollectionReusableView,
            element_kind: &NSString,
            index_path: &NSIndexPath,
        );

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[deprecated]
        #[optional]
        #[unsafe(method(collectionView:shouldShowMenuForItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_shouldShowMenuForItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        ) -> bool;

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        /// # Safety
        ///
        /// - `action` must be a valid selector.
        /// - `sender` should be of the correct type.
        #[deprecated]
        #[optional]
        #[unsafe(method(collectionView:canPerformAction:forItemAtIndexPath:withSender:))]
        #[unsafe(method_family = none)]
        unsafe fn collectionView_canPerformAction_forItemAtIndexPath_withSender(
            &self,
            collection_view: &UICollectionView,
            action: Sel,
            index_path: &NSIndexPath,
            sender: Option<&AnyObject>,
        ) -> bool;

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        /// # Safety
        ///
        /// - `action` must be a valid selector.
        /// - `sender` should be of the correct type.
        #[deprecated]
        #[optional]
        #[unsafe(method(collectionView:performAction:forItemAtIndexPath:withSender:))]
        #[unsafe(method_family = none)]
        unsafe fn collectionView_performAction_forItemAtIndexPath_withSender(
            &self,
            collection_view: &UICollectionView,
            action: Sel,
            index_path: &NSIndexPath,
            sender: Option<&AnyObject>,
        );

        #[cfg(all(
            feature = "UICollectionViewLayout",
            feature = "UICollectionViewTransitionLayout",
            feature = "UIResponder",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:transitionLayoutForOldLayout:newLayout:))]
        #[unsafe(method_family = none)]
        fn collectionView_transitionLayoutForOldLayout_newLayout(
            &self,
            collection_view: &UICollectionView,
            from_layout: &UICollectionViewLayout,
            to_layout: &UICollectionViewLayout,
        ) -> Retained<UICollectionViewTransitionLayout>;

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:canFocusItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_canFocusItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        ) -> bool;

        #[cfg(all(feature = "UIFocus", feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:shouldUpdateFocusInContext:))]
        #[unsafe(method_family = none)]
        fn collectionView_shouldUpdateFocusInContext(
            &self,
            collection_view: &UICollectionView,
            context: &UICollectionViewFocusUpdateContext,
        ) -> bool;

        #[cfg(all(
            feature = "UIFocus",
            feature = "UIFocusAnimationCoordinator",
            feature = "UIResponder",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:didUpdateFocusInContext:withAnimationCoordinator:))]
        #[unsafe(method_family = none)]
        fn collectionView_didUpdateFocusInContext_withAnimationCoordinator(
            &self,
            collection_view: &UICollectionView,
            context: &UICollectionViewFocusUpdateContext,
            coordinator: &UIFocusAnimationCoordinator,
        );

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(indexPathForPreferredFocusedViewInCollectionView:))]
        #[unsafe(method_family = none)]
        fn indexPathForPreferredFocusedViewInCollectionView(
            &self,
            collection_view: &UICollectionView,
        ) -> Option<Retained<NSIndexPath>>;

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        /// Determines if the item at the specified index path should also become selected when focus moves to it.
        /// If the collection view's global selectionFollowsFocus is enabled, this method will allow you to override that behavior on a per-index path basis. This method is not called if selectionFollowsFocus is disabled.
        #[optional]
        #[unsafe(method(collectionView:selectionFollowsFocusForItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_selectionFollowsFocusForItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        ) -> bool;

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:targetIndexPathForMoveOfItemFromOriginalIndexPath:atCurrentIndexPath:toProposedIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_targetIndexPathForMoveOfItemFromOriginalIndexPath_atCurrentIndexPath_toProposedIndexPath(
            &self,
            collection_view: &UICollectionView,
            original_index_path: &NSIndexPath,
            current_index_path: &NSIndexPath,
            proposed_index_path: &NSIndexPath,
        ) -> Retained<NSIndexPath>;

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[deprecated]
        #[optional]
        #[unsafe(method(collectionView:targetIndexPathForMoveFromItemAtIndexPath:toProposedIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_targetIndexPathForMoveFromItemAtIndexPath_toProposedIndexPath(
            &self,
            collection_view: &UICollectionView,
            current_index_path: &NSIndexPath,
            proposed_index_path: &NSIndexPath,
        ) -> Retained<NSIndexPath>;

        #[cfg(all(
            feature = "UIResponder",
            feature = "UIView",
            feature = "objc2-core-foundation"
        ))]
        #[optional]
        #[unsafe(method(collectionView:targetContentOffsetForProposedContentOffset:))]
        #[unsafe(method_family = none)]
        fn collectionView_targetContentOffsetForProposedContentOffset(
            &self,
            collection_view: &UICollectionView,
            proposed_content_offset: CGPoint,
        ) -> CGPoint;

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:canEditItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_canEditItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        ) -> bool;

        #[cfg(all(
            feature = "UIResponder",
            feature = "UISpringLoadedInteraction",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:shouldSpringLoadItemAtIndexPath:withContext:))]
        #[unsafe(method_family = none)]
        fn collectionView_shouldSpringLoadItemAtIndexPath_withContext(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
            context: &ProtocolObject<dyn UISpringLoadedInteractionContext>,
        ) -> bool;

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:shouldBeginMultipleSelectionInteractionAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_shouldBeginMultipleSelectionInteractionAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        ) -> bool;

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionView:didBeginMultipleSelectionInteractionAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_didBeginMultipleSelectionInteractionAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        );

        #[cfg(all(feature = "UIResponder", feature = "UIView"))]
        #[optional]
        #[unsafe(method(collectionViewDidEndMultipleSelectionInteraction:))]
        #[unsafe(method_family = none)]
        fn collectionViewDidEndMultipleSelectionInteraction(
            &self,
            collection_view: &UICollectionView,
        );

        #[cfg(all(
            feature = "UIContextMenuConfiguration",
            feature = "UIResponder",
            feature = "UIView",
            feature = "objc2-core-foundation"
        ))]
        /// Called when a context menu is invoked from this collection view.
        ///
        ///
        /// Parameter `collectionView`: The
        /// `UICollectionView.`
        /// Parameter `indexPaths`: An array of index paths on which the menu acts.
        ///
        /// Parameter `point`: Touch location in the collection view's coordinate space.
        ///
        ///
        /// Returns: A
        /// `UIContextMenuConfiguration`describing the menu to be presented. Return nil to prevent the interaction from beginning.
        /// Returning an empty configuration causes the interaction to begin then fail with a cancellation effect. You might use this
        /// to indicate to users that it's possible for a menu to be presented from this element, but that there are no actions to
        /// present at this particular time.
        ///
        ///
        /// The
        /// `indexPaths`array may contain 0-many items:
        /// - An empty array indicates that the menu was invoked in the space between cells (or any location that does not map to an item index path).
        /// - An array with multiple index paths indicates that the menu was invoked on an item within a multiple selection.
        #[optional]
        #[unsafe(method(collectionView:contextMenuConfigurationForItemsAtIndexPaths:point:))]
        #[unsafe(method_family = none)]
        fn collectionView_contextMenuConfigurationForItemsAtIndexPaths_point(
            &self,
            collection_view: &UICollectionView,
            index_paths: &NSArray<NSIndexPath>,
            point: CGPoint,
        ) -> Option<Retained<UIContextMenuConfiguration>>;

        #[cfg(all(
            feature = "UIContextMenuConfiguration",
            feature = "UIResponder",
            feature = "UITargetedPreview",
            feature = "UIView"
        ))]
        /// Called when a context menu interaction begins in this collection view to request a preview for the interaction's initial highlight effect.
        /// Return a
        /// `UITargetedPreview`corresponding to the item at the given indexPath.
        ///
        ///
        /// Parameter `collectionView`: The
        /// `UICollectionView.`
        /// Parameter `configuration`: Configuration of the menu that will be presented if the interaction proceeds.
        ///
        /// Parameter `indexPath`: Index path of the item at which the interaction is occurring.
        #[optional]
        #[unsafe(method(collectionView:contextMenuConfiguration:highlightPreviewForItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_contextMenuConfiguration_highlightPreviewForItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            configuration: &UIContextMenuConfiguration,
            index_path: &NSIndexPath,
        ) -> Option<Retained<UITargetedPreview>>;

        #[cfg(all(
            feature = "UIContextMenuConfiguration",
            feature = "UIResponder",
            feature = "UITargetedPreview",
            feature = "UIView"
        ))]
        /// Called when a context menu presented from this collection view is dismissed. Return a
        /// `UITargetedPreview`corresponding to the item at the given indexPath.
        ///
        ///
        /// Parameter `collectionView`: The
        /// `UICollectionView.`
        /// Parameter `configuration`: Configuration of the menu being dismissed.
        ///
        /// Parameter `indexPath`: Index path of the item to which the menu is being dismissed.
        #[optional]
        #[unsafe(method(collectionView:contextMenuConfiguration:dismissalPreviewForItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_contextMenuConfiguration_dismissalPreviewForItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            configuration: &UIContextMenuConfiguration,
            index_path: &NSIndexPath,
        ) -> Option<Retained<UITargetedPreview>>;

        #[cfg(all(
            feature = "UIContextMenuConfiguration",
            feature = "UIContextMenuInteraction",
            feature = "UIResponder",
            feature = "UIView"
        ))]
        /// Called when the interaction is about to "commit" in response to the user tapping the preview.
        ///
        ///
        /// Parameter `collectionView`: The
        /// `UICollectionView.`
        /// Parameter `configuration`: Configuration of the currently displayed menu.
        ///
        /// Parameter `animator`: Commit animator. Add animations to this object to run them alongside the commit transition.
        #[optional]
        #[unsafe(method(collectionView:willPerformPreviewActionForMenuWithConfiguration:animator:))]
        #[unsafe(method_family = none)]
        fn collectionView_willPerformPreviewActionForMenuWithConfiguration_animator(
            &self,
            collection_view: &UICollectionView,
            configuration: &UIContextMenuConfiguration,
            animator: &ProtocolObject<dyn UIContextMenuInteractionCommitAnimating>,
        );

        #[cfg(all(
            feature = "UIContextMenuConfiguration",
            feature = "UIContextMenuInteraction",
            feature = "UIResponder",
            feature = "UIView"
        ))]
        /// Called when the collection view is about to display a menu.
        ///
        ///
        /// Parameter `collectionView`: The
        /// `UICollectionView.`
        /// Parameter `configuration`: The configuration of the menu about to be displayed.
        ///
        /// Parameter `animator`: Appearance animator. Add animations to run them alongside the appearance transition.
        #[optional]
        #[unsafe(method(collectionView:willDisplayContextMenuWithConfiguration:animator:))]
        #[unsafe(method_family = none)]
        fn collectionView_willDisplayContextMenuWithConfiguration_animator(
            &self,
            collection_view: &UICollectionView,
            configuration: &UIContextMenuConfiguration,
            animator: Option<&ProtocolObject<dyn UIContextMenuInteractionAnimating>>,
        );

        #[cfg(all(
            feature = "UIContextMenuConfiguration",
            feature = "UIContextMenuInteraction",
            feature = "UIResponder",
            feature = "UIView"
        ))]
        /// Called when the collection view's context menu interaction is about to end.
        ///
        ///
        /// Parameter `collectionView`: The
        /// `UICollectionView.`
        /// Parameter `configuration`: Ending configuration.
        ///
        /// Parameter `animator`: Disappearance animator. Add animations to run them alongside the disappearance transition.
        #[optional]
        #[unsafe(method(collectionView:willEndContextMenuInteractionWithConfiguration:animator:))]
        #[unsafe(method_family = none)]
        fn collectionView_willEndContextMenuInteractionWithConfiguration_animator(
            &self,
            collection_view: &UICollectionView,
            configuration: &UIContextMenuConfiguration,
            animator: Option<&ProtocolObject<dyn UIContextMenuInteractionAnimating>>,
        );

        #[cfg(all(
            feature = "UIResponder",
            feature = "UIView",
            feature = "UIWindowSceneActivationConfiguration",
            feature = "objc2-core-foundation"
        ))]
        /// Return a valid
        /// `UIWindowSceneActivationConfiguration`to allow for the cell to be expanded into a new scene. Return nil to prevent the interaction from starting.
        ///
        ///
        /// Parameter `collectionView`: The collection view
        ///
        /// Parameter `indexPath`: The index path of the cell being interacted with
        ///
        /// Parameter `point`: The centroid of the interaction in the collection view's coordinate space.
        #[optional]
        #[unsafe(method(collectionView:sceneActivationConfigurationForItemAtIndexPath:point:))]
        #[unsafe(method_family = none)]
        fn collectionView_sceneActivationConfigurationForItemAtIndexPath_point(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
            point: CGPoint,
        ) -> Option<Retained<UIWindowSceneActivationConfiguration>>;

        #[cfg(all(
            feature = "UIContextMenuConfiguration",
            feature = "UIResponder",
            feature = "UIView",
            feature = "objc2-core-foundation"
        ))]
        /// Called when the interaction begins.
        ///
        ///
        /// Parameter `collectionView`: The
        /// `UICollectionView.`
        /// Parameter `indexPath`: IndexPath of the item for which a configuration is being requested.
        ///
        /// Parameter `point`: Touch location in the collection view's coordinate space
        ///
        ///
        /// Returns: A UIContextMenuConfiguration describing the menu to be presented. Return nil to prevent the interaction from beginning.
        /// Returning an empty configuration causes the interaction to begin then fail with a cancellation effect. You might use this
        /// to indicate to users that it's possible for a menu to be presented from this element, but that there are no actions to
        /// present at this particular time. If the non-deprecated replacement for the configuration, highlight preview, or dismissal preview methods is implemented this method is not called.
        #[deprecated]
        #[optional]
        #[unsafe(method(collectionView:contextMenuConfigurationForItemAtIndexPath:point:))]
        #[unsafe(method_family = none)]
        fn collectionView_contextMenuConfigurationForItemAtIndexPath_point(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
            point: CGPoint,
        ) -> Option<Retained<UIContextMenuConfiguration>>;

        #[cfg(all(
            feature = "UIContextMenuConfiguration",
            feature = "UIResponder",
            feature = "UITargetedPreview",
            feature = "UIView"
        ))]
        /// Called when the interaction begins. Return a UITargetedPreview describing the desired highlight preview.
        /// If the non-deprecated replacement for the configuration, highlight preview, or dismissal preview methods is implemented this method is not called.
        ///
        ///
        /// Parameter `collectionView`: The
        /// `UICollectionView.`
        /// Parameter `configuration`: The configuration of the menu about to be displayed by this interaction.
        #[deprecated]
        #[optional]
        #[unsafe(method(collectionView:previewForHighlightingContextMenuWithConfiguration:))]
        #[unsafe(method_family = none)]
        fn collectionView_previewForHighlightingContextMenuWithConfiguration(
            &self,
            collection_view: &UICollectionView,
            configuration: &UIContextMenuConfiguration,
        ) -> Option<Retained<UITargetedPreview>>;

        #[cfg(all(
            feature = "UIContextMenuConfiguration",
            feature = "UIResponder",
            feature = "UITargetedPreview",
            feature = "UIView"
        ))]
        /// Called when the interaction is about to dismiss. Return a UITargetedPreview describing the desired dismissal target.
        /// The interaction will animate the presented menu to the target. Use this to customize the dismissal animation.
        /// If the non-deprecated replacement for the configuration, highlight preview, or dismissal preview methods is implemented this method is not called.
        ///
        ///
        /// Parameter `collectionView`: The
        /// `UICollectionView.`
        /// Parameter `configuration`: The configuration of the menu displayed by this interaction.
        #[deprecated]
        #[optional]
        #[unsafe(method(collectionView:previewForDismissingContextMenuWithConfiguration:))]
        #[unsafe(method_family = none)]
        fn collectionView_previewForDismissingContextMenuWithConfiguration(
            &self,
            collection_view: &UICollectionView,
            configuration: &UIContextMenuConfiguration,
        ) -> Option<Retained<UITargetedPreview>>;
    }
);

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionview?language=objc)
    #[unsafe(super(UIScrollView, UIView, UIResponder, NSObject))]
    #[thread_kind = MainThreadOnly]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
    pub struct UICollectionView;
);

#[cfg(all(
    feature = "UIResponder",
    feature = "UIScrollView",
    feature = "UIView",
    feature = "objc2-quartz-core"
))]
#[cfg(not(target_os = "watchos"))]
extern_conformance!(
    unsafe impl CALayerDelegate for UICollectionView {}
);

#[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
extern_conformance!(
    unsafe impl NSCoding for UICollectionView {}
);

#[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
extern_conformance!(
    unsafe impl NSObjectProtocol for UICollectionView {}
);

#[cfg(all(
    feature = "UIAppearance",
    feature = "UIResponder",
    feature = "UIScrollView",
    feature = "UIView"
))]
extern_conformance!(
    unsafe impl UIAppearance for UICollectionView {}
);

#[cfg(all(
    feature = "UIAppearance",
    feature = "UIResponder",
    feature = "UIScrollView",
    feature = "UIView"
))]
extern_conformance!(
    unsafe impl UIAppearanceContainer for UICollectionView {}
);

#[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
extern_conformance!(
    unsafe impl UICoordinateSpace for UICollectionView {}
);

#[cfg(all(
    feature = "UIDataSourceTranslating",
    feature = "UIResponder",
    feature = "UIScrollView",
    feature = "UIView"
))]
extern_conformance!(
    unsafe impl UIDataSourceTranslating for UICollectionView {}
);

#[cfg(all(
    feature = "UIDynamicBehavior",
    feature = "UIResponder",
    feature = "UIScrollView",
    feature = "UIView"
))]
extern_conformance!(
    unsafe impl UIDynamicItem for UICollectionView {}
);

#[cfg(all(
    feature = "UIFocus",
    feature = "UIResponder",
    feature = "UIScrollView",
    feature = "UIView"
))]
extern_conformance!(
    unsafe impl UIFocusEnvironment for UICollectionView {}
);

#[cfg(all(
    feature = "UIFocus",
    feature = "UIResponder",
    feature = "UIScrollView",
    feature = "UIView"
))]
extern_conformance!(
    unsafe impl UIFocusItem for UICollectionView {}
);

#[cfg(all(
    feature = "UIFocus",
    feature = "UIResponder",
    feature = "UIScrollView",
    feature = "UIView"
))]
extern_conformance!(
    unsafe impl UIFocusItemContainer for UICollectionView {}
);

#[cfg(all(
    feature = "UIFocus",
    feature = "UIResponder",
    feature = "UIScrollView",
    feature = "UIView"
))]
extern_conformance!(
    unsafe impl UIFocusItemScrollableContainer for UICollectionView {}
);

#[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
extern_conformance!(
    unsafe impl UIResponderStandardEditActions for UICollectionView {}
);

#[cfg(all(
    feature = "UIResponder",
    feature = "UIScrollView",
    feature = "UITraitCollection",
    feature = "UIView"
))]
extern_conformance!(
    unsafe impl UITraitEnvironment for UICollectionView {}
);

#[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
impl UICollectionView {
    extern_methods!(
        #[cfg(all(feature = "UICollectionViewLayout", feature = "objc2-core-foundation"))]
        #[unsafe(method(initWithFrame:collectionViewLayout:))]
        #[unsafe(method_family = init)]
        pub fn initWithFrame_collectionViewLayout(
            this: Allocated<Self>,
            frame: CGRect,
            layout: &UICollectionViewLayout,
        ) -> Retained<Self>;

        /// # Safety
        ///
        /// `coder` possibly has further requirements.
        #[unsafe(method(initWithCoder:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithCoder(
            this: Allocated<Self>,
            coder: &NSCoder,
        ) -> Option<Retained<Self>>;

        #[cfg(feature = "UICollectionViewLayout")]
        #[unsafe(method(collectionViewLayout))]
        #[unsafe(method_family = none)]
        pub fn collectionViewLayout(&self) -> Retained<UICollectionViewLayout>;

        #[cfg(feature = "UICollectionViewLayout")]
        /// Setter for [`collectionViewLayout`][Self::collectionViewLayout].
        #[unsafe(method(setCollectionViewLayout:))]
        #[unsafe(method_family = none)]
        pub fn setCollectionViewLayout(&self, collection_view_layout: &UICollectionViewLayout);

        #[unsafe(method(delegate))]
        #[unsafe(method_family = none)]
        pub fn delegate(&self) -> Option<Retained<ProtocolObject<dyn UICollectionViewDelegate>>>;

        /// Setter for [`delegate`][Self::delegate].
        ///
        /// This is a [weak property][objc2::topics::weak_property].
        #[unsafe(method(setDelegate:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setDelegate(
            &self,
            delegate: Option<&ProtocolObject<dyn UICollectionViewDelegate>>,
        );

        #[unsafe(method(dataSource))]
        #[unsafe(method_family = none)]
        pub fn dataSource(
            &self,
        ) -> Option<Retained<ProtocolObject<dyn UICollectionViewDataSource>>>;

        /// Setter for [`dataSource`][Self::dataSource].
        ///
        /// This is a [weak property][objc2::topics::weak_property].
        #[unsafe(method(setDataSource:))]
        #[unsafe(method_family = none)]
        pub fn setDataSource(
            &self,
            data_source: Option<&ProtocolObject<dyn UICollectionViewDataSource>>,
        );

        #[unsafe(method(prefetchDataSource))]
        #[unsafe(method_family = none)]
        pub fn prefetchDataSource(
            &self,
        ) -> Option<Retained<ProtocolObject<dyn UICollectionViewDataSourcePrefetching>>>;

        /// Setter for [`prefetchDataSource`][Self::prefetchDataSource].
        ///
        /// This is a [weak property][objc2::topics::weak_property].
        #[unsafe(method(setPrefetchDataSource:))]
        #[unsafe(method_family = none)]
        pub fn setPrefetchDataSource(
            &self,
            prefetch_data_source: Option<
                &ProtocolObject<dyn UICollectionViewDataSourcePrefetching>,
            >,
        );

        #[unsafe(method(isPrefetchingEnabled))]
        #[unsafe(method_family = none)]
        pub fn isPrefetchingEnabled(&self) -> bool;

        /// Setter for [`isPrefetchingEnabled`][Self::isPrefetchingEnabled].
        #[unsafe(method(setPrefetchingEnabled:))]
        #[unsafe(method_family = none)]
        pub fn setPrefetchingEnabled(&self, prefetching_enabled: bool);

        #[unsafe(method(dragDelegate))]
        #[unsafe(method_family = none)]
        pub fn dragDelegate(
            &self,
        ) -> Option<Retained<ProtocolObject<dyn UICollectionViewDragDelegate>>>;

        /// Setter for [`dragDelegate`][Self::dragDelegate].
        ///
        /// This is a [weak property][objc2::topics::weak_property].
        #[unsafe(method(setDragDelegate:))]
        #[unsafe(method_family = none)]
        pub fn setDragDelegate(
            &self,
            drag_delegate: Option<&ProtocolObject<dyn UICollectionViewDragDelegate>>,
        );

        #[unsafe(method(dropDelegate))]
        #[unsafe(method_family = none)]
        pub fn dropDelegate(
            &self,
        ) -> Option<Retained<ProtocolObject<dyn UICollectionViewDropDelegate>>>;

        /// Setter for [`dropDelegate`][Self::dropDelegate].
        ///
        /// This is a [weak property][objc2::topics::weak_property].
        #[unsafe(method(setDropDelegate:))]
        #[unsafe(method_family = none)]
        pub fn setDropDelegate(
            &self,
            drop_delegate: Option<&ProtocolObject<dyn UICollectionViewDropDelegate>>,
        );

        #[unsafe(method(dragInteractionEnabled))]
        #[unsafe(method_family = none)]
        pub fn dragInteractionEnabled(&self) -> bool;

        /// Setter for [`dragInteractionEnabled`][Self::dragInteractionEnabled].
        #[unsafe(method(setDragInteractionEnabled:))]
        #[unsafe(method_family = none)]
        pub fn setDragInteractionEnabled(&self, drag_interaction_enabled: bool);

        #[cfg(feature = "UIContextMenuInteraction")]
        #[unsafe(method(contextMenuInteraction))]
        #[unsafe(method_family = none)]
        pub fn contextMenuInteraction(&self) -> Option<Retained<UIContextMenuInteraction>>;

        #[unsafe(method(reorderingCadence))]
        #[unsafe(method_family = none)]
        pub fn reorderingCadence(&self) -> UICollectionViewReorderingCadence;

        /// Setter for [`reorderingCadence`][Self::reorderingCadence].
        #[unsafe(method(setReorderingCadence:))]
        #[unsafe(method_family = none)]
        pub fn setReorderingCadence(&self, reordering_cadence: UICollectionViewReorderingCadence);

        #[unsafe(method(selfSizingInvalidation))]
        #[unsafe(method_family = none)]
        pub fn selfSizingInvalidation(&self) -> UICollectionViewSelfSizingInvalidation;

        /// Setter for [`selfSizingInvalidation`][Self::selfSizingInvalidation].
        #[unsafe(method(setSelfSizingInvalidation:))]
        #[unsafe(method_family = none)]
        pub fn setSelfSizingInvalidation(
            &self,
            self_sizing_invalidation: UICollectionViewSelfSizingInvalidation,
        );

        #[unsafe(method(backgroundView))]
        #[unsafe(method_family = none)]
        pub fn backgroundView(&self) -> Option<Retained<UIView>>;

        /// Setter for [`backgroundView`][Self::backgroundView].
        #[unsafe(method(setBackgroundView:))]
        #[unsafe(method_family = none)]
        pub fn setBackgroundView(&self, background_view: Option<&UIView>);

        /// # Safety
        ///
        /// `cell_class` probably has further requirements.
        #[unsafe(method(registerClass:forCellWithReuseIdentifier:))]
        #[unsafe(method_family = none)]
        pub unsafe fn registerClass_forCellWithReuseIdentifier(
            &self,
            cell_class: Option<&AnyClass>,
            identifier: &NSString,
        );

        #[cfg(feature = "UINib")]
        #[deprecated = "Loading Interface Builder products will not be supported in a future version of visionOS."]
        #[unsafe(method(registerNib:forCellWithReuseIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn registerNib_forCellWithReuseIdentifier(
            &self,
            nib: Option<&UINib>,
            identifier: &NSString,
        );

        /// # Safety
        ///
        /// `view_class` probably has further requirements.
        #[unsafe(method(registerClass:forSupplementaryViewOfKind:withReuseIdentifier:))]
        #[unsafe(method_family = none)]
        pub unsafe fn registerClass_forSupplementaryViewOfKind_withReuseIdentifier(
            &self,
            view_class: Option<&AnyClass>,
            element_kind: &NSString,
            identifier: &NSString,
        );

        #[cfg(feature = "UINib")]
        #[deprecated = "Loading Interface Builder products will not be supported in a future version of visionOS."]
        #[unsafe(method(registerNib:forSupplementaryViewOfKind:withReuseIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn registerNib_forSupplementaryViewOfKind_withReuseIdentifier(
            &self,
            nib: Option<&UINib>,
            kind: &NSString,
            identifier: &NSString,
        );

        #[cfg(feature = "UICollectionViewCell")]
        #[unsafe(method(dequeueReusableCellWithReuseIdentifier:forIndexPath:))]
        #[unsafe(method_family = none)]
        pub fn dequeueReusableCellWithReuseIdentifier_forIndexPath(
            &self,
            identifier: &NSString,
            index_path: &NSIndexPath,
        ) -> Retained<UICollectionViewCell>;

        #[cfg(feature = "UICollectionViewCell")]
        #[unsafe(method(dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:))]
        #[unsafe(method_family = none)]
        pub fn dequeueReusableSupplementaryViewOfKind_withReuseIdentifier_forIndexPath(
            &self,
            element_kind: &NSString,
            identifier: &NSString,
            index_path: &NSIndexPath,
        ) -> Retained<UICollectionReusableView>;

        #[cfg(all(
            feature = "UICollectionViewCell",
            feature = "UICollectionViewItemRegistration"
        ))]
        /// # Safety
        ///
        /// `item` should be of the correct type.
        #[unsafe(method(dequeueConfiguredReusableCellWithRegistration:forIndexPath:item:))]
        #[unsafe(method_family = none)]
        pub unsafe fn dequeueConfiguredReusableCellWithRegistration_forIndexPath_item(
            &self,
            registration: &UICollectionViewCellRegistration,
            index_path: &NSIndexPath,
            item: &AnyObject,
        ) -> Retained<UICollectionViewCell>;

        #[cfg(all(
            feature = "UICollectionViewCell",
            feature = "UICollectionViewItemRegistration"
        ))]
        #[unsafe(method(dequeueConfiguredReusableSupplementaryViewWithRegistration:forIndexPath:))]
        #[unsafe(method_family = none)]
        pub fn dequeueConfiguredReusableSupplementaryViewWithRegistration_forIndexPath(
            &self,
            registration: &UICollectionViewSupplementaryRegistration,
            index_path: &NSIndexPath,
        ) -> Retained<UICollectionReusableView>;

        #[unsafe(method(allowsSelection))]
        #[unsafe(method_family = none)]
        pub fn allowsSelection(&self) -> bool;

        /// Setter for [`allowsSelection`][Self::allowsSelection].
        #[unsafe(method(setAllowsSelection:))]
        #[unsafe(method_family = none)]
        pub fn setAllowsSelection(&self, allows_selection: bool);

        #[unsafe(method(allowsMultipleSelection))]
        #[unsafe(method_family = none)]
        pub fn allowsMultipleSelection(&self) -> bool;

        /// Setter for [`allowsMultipleSelection`][Self::allowsMultipleSelection].
        #[unsafe(method(setAllowsMultipleSelection:))]
        #[unsafe(method_family = none)]
        pub fn setAllowsMultipleSelection(&self, allows_multiple_selection: bool);

        #[unsafe(method(indexPathsForSelectedItems))]
        #[unsafe(method_family = none)]
        pub fn indexPathsForSelectedItems(&self) -> Option<Retained<NSArray<NSIndexPath>>>;

        #[unsafe(method(selectItemAtIndexPath:animated:scrollPosition:))]
        #[unsafe(method_family = none)]
        pub fn selectItemAtIndexPath_animated_scrollPosition(
            &self,
            index_path: Option<&NSIndexPath>,
            animated: bool,
            scroll_position: UICollectionViewScrollPosition,
        );

        #[unsafe(method(deselectItemAtIndexPath:animated:))]
        #[unsafe(method_family = none)]
        pub fn deselectItemAtIndexPath_animated(&self, index_path: &NSIndexPath, animated: bool);

        #[unsafe(method(hasUncommittedUpdates))]
        #[unsafe(method_family = none)]
        pub fn hasUncommittedUpdates(&self) -> bool;

        #[unsafe(method(reloadData))]
        #[unsafe(method_family = none)]
        pub fn reloadData(&self);

        #[cfg(feature = "UICollectionViewLayout")]
        #[unsafe(method(setCollectionViewLayout:animated:))]
        #[unsafe(method_family = none)]
        pub fn setCollectionViewLayout_animated(
            &self,
            layout: &UICollectionViewLayout,
            animated: bool,
        );

        #[cfg(all(feature = "UICollectionViewLayout", feature = "block2"))]
        #[unsafe(method(setCollectionViewLayout:animated:completion:))]
        #[unsafe(method_family = none)]
        pub fn setCollectionViewLayout_animated_completion(
            &self,
            layout: &UICollectionViewLayout,
            animated: bool,
            completion: Option<&block2::DynBlock<dyn Fn(Bool)>>,
        );

        #[cfg(all(
            feature = "UICollectionViewLayout",
            feature = "UICollectionViewTransitionLayout",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// `completion` must be a valid pointer or null.
        #[unsafe(method(startInteractiveTransitionToCollectionViewLayout:completion:))]
        #[unsafe(method_family = none)]
        pub unsafe fn startInteractiveTransitionToCollectionViewLayout_completion(
            &self,
            layout: &UICollectionViewLayout,
            completion: UICollectionViewLayoutInteractiveTransitionCompletion,
        ) -> Retained<UICollectionViewTransitionLayout>;

        #[unsafe(method(finishInteractiveTransition))]
        #[unsafe(method_family = none)]
        pub fn finishInteractiveTransition(&self);

        #[unsafe(method(cancelInteractiveTransition))]
        #[unsafe(method_family = none)]
        pub fn cancelInteractiveTransition(&self);

        #[unsafe(method(numberOfSections))]
        #[unsafe(method_family = none)]
        pub fn numberOfSections(&self) -> NSInteger;

        #[unsafe(method(numberOfItemsInSection:))]
        #[unsafe(method_family = none)]
        pub fn numberOfItemsInSection(&self, section: NSInteger) -> NSInteger;

        #[cfg(feature = "UICollectionViewLayout")]
        #[unsafe(method(layoutAttributesForItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        pub fn layoutAttributesForItemAtIndexPath(
            &self,
            index_path: &NSIndexPath,
        ) -> Option<Retained<UICollectionViewLayoutAttributes>>;

        #[cfg(feature = "UICollectionViewLayout")]
        #[unsafe(method(layoutAttributesForSupplementaryElementOfKind:atIndexPath:))]
        #[unsafe(method_family = none)]
        pub fn layoutAttributesForSupplementaryElementOfKind_atIndexPath(
            &self,
            kind: &NSString,
            index_path: &NSIndexPath,
        ) -> Option<Retained<UICollectionViewLayoutAttributes>>;

        #[cfg(feature = "objc2-core-foundation")]
        #[unsafe(method(indexPathForItemAtPoint:))]
        #[unsafe(method_family = none)]
        pub fn indexPathForItemAtPoint(&self, point: CGPoint) -> Option<Retained<NSIndexPath>>;

        #[cfg(feature = "UICollectionViewCell")]
        #[unsafe(method(indexPathForCell:))]
        #[unsafe(method_family = none)]
        pub fn indexPathForCell(
            &self,
            cell: &UICollectionViewCell,
        ) -> Option<Retained<NSIndexPath>>;

        #[cfg(feature = "UICollectionViewCell")]
        /// Gets the index path of the specified supplementary view.
        ///
        /// Parameter `supplementaryView`: The supplementary or decoration view whose index path you want.
        ///
        /// Returns: The index path of the specified view if it is in the collection view, else `nil`.
        #[unsafe(method(indexPathForSupplementaryView:))]
        #[unsafe(method_family = none)]
        pub fn indexPathForSupplementaryView(
            &self,
            supplementary_view: &UICollectionReusableView,
        ) -> Option<Retained<NSIndexPath>>;

        #[cfg(feature = "UICollectionViewCell")]
        #[unsafe(method(cellForItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        pub fn cellForItemAtIndexPath(
            &self,
            index_path: &NSIndexPath,
        ) -> Option<Retained<UICollectionViewCell>>;

        #[cfg(feature = "UICollectionViewCell")]
        #[unsafe(method(visibleCells))]
        #[unsafe(method_family = none)]
        pub fn visibleCells(&self) -> Retained<NSArray<UICollectionViewCell>>;

        #[unsafe(method(indexPathsForVisibleItems))]
        #[unsafe(method_family = none)]
        pub fn indexPathsForVisibleItems(&self) -> Retained<NSArray<NSIndexPath>>;

        #[cfg(feature = "UICollectionViewCell")]
        #[unsafe(method(supplementaryViewForElementKind:atIndexPath:))]
        #[unsafe(method_family = none)]
        pub fn supplementaryViewForElementKind_atIndexPath(
            &self,
            element_kind: &NSString,
            index_path: &NSIndexPath,
        ) -> Option<Retained<UICollectionReusableView>>;

        #[cfg(feature = "UICollectionViewCell")]
        #[unsafe(method(visibleSupplementaryViewsOfKind:))]
        #[unsafe(method_family = none)]
        pub fn visibleSupplementaryViewsOfKind(
            &self,
            element_kind: &NSString,
        ) -> Retained<NSArray<UICollectionReusableView>>;

        #[unsafe(method(indexPathsForVisibleSupplementaryElementsOfKind:))]
        #[unsafe(method_family = none)]
        pub fn indexPathsForVisibleSupplementaryElementsOfKind(
            &self,
            element_kind: &NSString,
        ) -> Retained<NSArray<NSIndexPath>>;

        #[unsafe(method(scrollToItemAtIndexPath:atScrollPosition:animated:))]
        #[unsafe(method_family = none)]
        pub fn scrollToItemAtIndexPath_atScrollPosition_animated(
            &self,
            index_path: &NSIndexPath,
            scroll_position: UICollectionViewScrollPosition,
            animated: bool,
        );

        #[unsafe(method(insertSections:))]
        #[unsafe(method_family = none)]
        pub fn insertSections(&self, sections: &NSIndexSet);

        #[unsafe(method(deleteSections:))]
        #[unsafe(method_family = none)]
        pub fn deleteSections(&self, sections: &NSIndexSet);

        #[unsafe(method(moveSection:toSection:))]
        #[unsafe(method_family = none)]
        pub fn moveSection_toSection(&self, section: NSInteger, new_section: NSInteger);

        #[unsafe(method(reloadSections:))]
        #[unsafe(method_family = none)]
        pub fn reloadSections(&self, sections: &NSIndexSet);

        #[unsafe(method(insertItemsAtIndexPaths:))]
        #[unsafe(method_family = none)]
        pub fn insertItemsAtIndexPaths(&self, index_paths: &NSArray<NSIndexPath>);

        #[unsafe(method(deleteItemsAtIndexPaths:))]
        #[unsafe(method_family = none)]
        pub fn deleteItemsAtIndexPaths(&self, index_paths: &NSArray<NSIndexPath>);

        #[unsafe(method(moveItemAtIndexPath:toIndexPath:))]
        #[unsafe(method_family = none)]
        pub fn moveItemAtIndexPath_toIndexPath(
            &self,
            index_path: &NSIndexPath,
            new_index_path: &NSIndexPath,
        );

        #[unsafe(method(reloadItemsAtIndexPaths:))]
        #[unsafe(method_family = none)]
        pub fn reloadItemsAtIndexPaths(&self, index_paths: &NSArray<NSIndexPath>);

        #[unsafe(method(reconfigureItemsAtIndexPaths:))]
        #[unsafe(method_family = none)]
        pub fn reconfigureItemsAtIndexPaths(&self, index_paths: &NSArray<NSIndexPath>);

        #[cfg(feature = "block2")]
        #[unsafe(method(performBatchUpdates:completion:))]
        #[unsafe(method_family = none)]
        pub fn performBatchUpdates_completion(
            &self,
            updates: Option<&block2::DynBlock<dyn Fn() + '_>>,
            completion: Option<&block2::DynBlock<dyn Fn(Bool)>>,
        );

        #[unsafe(method(beginInteractiveMovementForItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        pub fn beginInteractiveMovementForItemAtIndexPath(&self, index_path: &NSIndexPath) -> bool;

        #[cfg(feature = "objc2-core-foundation")]
        #[unsafe(method(updateInteractiveMovementTargetPosition:))]
        #[unsafe(method_family = none)]
        pub fn updateInteractiveMovementTargetPosition(&self, target_position: CGPoint);

        #[unsafe(method(endInteractiveMovement))]
        #[unsafe(method_family = none)]
        pub fn endInteractiveMovement(&self);

        #[unsafe(method(cancelInteractiveMovement))]
        #[unsafe(method_family = none)]
        pub fn cancelInteractiveMovement(&self);

        #[unsafe(method(remembersLastFocusedIndexPath))]
        #[unsafe(method_family = none)]
        pub fn remembersLastFocusedIndexPath(&self) -> bool;

        /// Setter for [`remembersLastFocusedIndexPath`][Self::remembersLastFocusedIndexPath].
        #[unsafe(method(setRemembersLastFocusedIndexPath:))]
        #[unsafe(method_family = none)]
        pub fn setRemembersLastFocusedIndexPath(&self, remembers_last_focused_index_path: bool);

        /// When enabled, the collection view ensures that selection is automatically triggered when focus moves to a cell.
        /// Defaults to a system derived value based on platform and other properties of the collection view.
        #[unsafe(method(selectionFollowsFocus))]
        #[unsafe(method_family = none)]
        pub fn selectionFollowsFocus(&self) -> bool;

        /// Setter for [`selectionFollowsFocus`][Self::selectionFollowsFocus].
        #[unsafe(method(setSelectionFollowsFocus:))]
        #[unsafe(method_family = none)]
        pub fn setSelectionFollowsFocus(&self, selection_follows_focus: bool);

        /// Determines if the collection view allows its cells to become focused.
        /// When collectionView:canFocusItemAtIndexPath: is implemented, its return value takes precedence over this method.
        /// Defaults to a system derived value based on platform and other properties of the collection view.
        #[unsafe(method(allowsFocus))]
        #[unsafe(method_family = none)]
        pub fn allowsFocus(&self) -> bool;

        /// Setter for [`allowsFocus`][Self::allowsFocus].
        #[unsafe(method(setAllowsFocus:))]
        #[unsafe(method_family = none)]
        pub fn setAllowsFocus(&self, allows_focus: bool);

        /// Determines if the collection view allows its cells to become focused while editing.
        /// When collectionView:canFocusItemAtIndexPath: is implemented, its return value takes precedence over this method.
        /// Defaults to a system derived value based on platform and other properties of the collection view.
        #[unsafe(method(allowsFocusDuringEditing))]
        #[unsafe(method_family = none)]
        pub fn allowsFocusDuringEditing(&self) -> bool;

        /// Setter for [`allowsFocusDuringEditing`][Self::allowsFocusDuringEditing].
        #[unsafe(method(setAllowsFocusDuringEditing:))]
        #[unsafe(method_family = none)]
        pub fn setAllowsFocusDuringEditing(&self, allows_focus_during_editing: bool);

        #[unsafe(method(hasActiveDrag))]
        #[unsafe(method_family = none)]
        pub fn hasActiveDrag(&self) -> bool;

        #[unsafe(method(hasActiveDrop))]
        #[unsafe(method_family = none)]
        pub fn hasActiveDrop(&self) -> bool;

        #[unsafe(method(isEditing))]
        #[unsafe(method_family = none)]
        pub fn isEditing(&self) -> bool;

        /// Setter for [`isEditing`][Self::isEditing].
        #[unsafe(method(setEditing:))]
        #[unsafe(method_family = none)]
        pub fn setEditing(&self, editing: bool);

        #[unsafe(method(allowsSelectionDuringEditing))]
        #[unsafe(method_family = none)]
        pub fn allowsSelectionDuringEditing(&self) -> bool;

        /// Setter for [`allowsSelectionDuringEditing`][Self::allowsSelectionDuringEditing].
        #[unsafe(method(setAllowsSelectionDuringEditing:))]
        #[unsafe(method_family = none)]
        pub fn setAllowsSelectionDuringEditing(&self, allows_selection_during_editing: bool);

        #[unsafe(method(allowsMultipleSelectionDuringEditing))]
        #[unsafe(method_family = none)]
        pub fn allowsMultipleSelectionDuringEditing(&self) -> bool;

        /// Setter for [`allowsMultipleSelectionDuringEditing`][Self::allowsMultipleSelectionDuringEditing].
        #[unsafe(method(setAllowsMultipleSelectionDuringEditing:))]
        #[unsafe(method_family = none)]
        pub fn setAllowsMultipleSelectionDuringEditing(
            &self,
            allows_multiple_selection_during_editing: bool,
        );
    );
}

/// Methods declared on superclass `UIView`.
#[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
impl UICollectionView {
    extern_methods!(
        #[cfg(feature = "objc2-core-foundation")]
        #[unsafe(method(initWithFrame:))]
        #[unsafe(method_family = init)]
        pub fn initWithFrame(this: Allocated<Self>, frame: CGRect) -> Retained<Self>;

        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;
    );
}

/// Methods declared on superclass `NSObject`.
#[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
impl UICollectionView {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new(mtm: MainThreadMarker) -> Retained<Self>;
    );
}

/// UIDragAndDrop.
#[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
impl UICollectionView {
    extern_methods!();
}

#[cfg(all(
    feature = "UIResponder",
    feature = "UIScrollView",
    feature = "UISpringLoadedInteractionSupporting",
    feature = "UIView"
))]
extern_conformance!(
    unsafe impl UISpringLoadedInteractionSupporting for UICollectionView {}
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewdragdelegate?language=objc)
    pub unsafe trait UICollectionViewDragDelegate:
        NSObjectProtocol + MainThreadOnly
    {
        #[cfg(all(
            feature = "UIDragItem",
            feature = "UIDragSession",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView"
        ))]
        #[unsafe(method(collectionView:itemsForBeginningDragSession:atIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_itemsForBeginningDragSession_atIndexPath(
            &self,
            collection_view: &UICollectionView,
            session: &ProtocolObject<dyn UIDragSession>,
            index_path: &NSIndexPath,
        ) -> Retained<NSArray<UIDragItem>>;

        #[cfg(all(
            feature = "UIDragItem",
            feature = "UIDragSession",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView",
            feature = "objc2-core-foundation"
        ))]
        #[optional]
        #[unsafe(method(collectionView:itemsForAddingToDragSession:atIndexPath:point:))]
        #[unsafe(method_family = none)]
        fn collectionView_itemsForAddingToDragSession_atIndexPath_point(
            &self,
            collection_view: &UICollectionView,
            session: &ProtocolObject<dyn UIDragSession>,
            index_path: &NSIndexPath,
            point: CGPoint,
        ) -> Retained<NSArray<UIDragItem>>;

        #[cfg(all(
            feature = "UIDragPreviewParameters",
            feature = "UIPreviewParameters",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:dragPreviewParametersForItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_dragPreviewParametersForItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        ) -> Option<Retained<UIDragPreviewParameters>>;

        #[cfg(all(
            feature = "UIDragSession",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:dragSessionWillBegin:))]
        #[unsafe(method_family = none)]
        fn collectionView_dragSessionWillBegin(
            &self,
            collection_view: &UICollectionView,
            session: &ProtocolObject<dyn UIDragSession>,
        );

        #[cfg(all(
            feature = "UIDragSession",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:dragSessionDidEnd:))]
        #[unsafe(method_family = none)]
        fn collectionView_dragSessionDidEnd(
            &self,
            collection_view: &UICollectionView,
            session: &ProtocolObject<dyn UIDragSession>,
        );

        #[cfg(all(
            feature = "UIDragSession",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:dragSessionAllowsMoveOperation:))]
        #[unsafe(method_family = none)]
        fn collectionView_dragSessionAllowsMoveOperation(
            &self,
            collection_view: &UICollectionView,
            session: &ProtocolObject<dyn UIDragSession>,
        ) -> bool;

        #[cfg(all(
            feature = "UIDragSession",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:dragSessionIsRestrictedToDraggingApplication:))]
        #[unsafe(method_family = none)]
        fn collectionView_dragSessionIsRestrictedToDraggingApplication(
            &self,
            collection_view: &UICollectionView,
            session: &ProtocolObject<dyn UIDragSession>,
        ) -> bool;
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewdropdelegate?language=objc)
    pub unsafe trait UICollectionViewDropDelegate:
        NSObjectProtocol + MainThreadOnly
    {
        #[cfg(all(feature = "UIResponder", feature = "UIScrollView", feature = "UIView"))]
        #[unsafe(method(collectionView:performDropWithCoordinator:))]
        #[unsafe(method_family = none)]
        fn collectionView_performDropWithCoordinator(
            &self,
            collection_view: &UICollectionView,
            coordinator: &ProtocolObject<dyn UICollectionViewDropCoordinator>,
        );

        #[cfg(all(
            feature = "UIDragSession",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:canHandleDropSession:))]
        #[unsafe(method_family = none)]
        fn collectionView_canHandleDropSession(
            &self,
            collection_view: &UICollectionView,
            session: &ProtocolObject<dyn UIDropSession>,
        ) -> bool;

        #[cfg(all(
            feature = "UIDragSession",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:dropSessionDidEnter:))]
        #[unsafe(method_family = none)]
        fn collectionView_dropSessionDidEnter(
            &self,
            collection_view: &UICollectionView,
            session: &ProtocolObject<dyn UIDropSession>,
        );

        #[cfg(all(
            feature = "UIDragSession",
            feature = "UIDropInteraction",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:dropSessionDidUpdate:withDestinationIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_dropSessionDidUpdate_withDestinationIndexPath(
            &self,
            collection_view: &UICollectionView,
            session: &ProtocolObject<dyn UIDropSession>,
            destination_index_path: Option<&NSIndexPath>,
        ) -> Retained<UICollectionViewDropProposal>;

        #[cfg(all(
            feature = "UIDragSession",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:dropSessionDidExit:))]
        #[unsafe(method_family = none)]
        fn collectionView_dropSessionDidExit(
            &self,
            collection_view: &UICollectionView,
            session: &ProtocolObject<dyn UIDropSession>,
        );

        #[cfg(all(
            feature = "UIDragSession",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:dropSessionDidEnd:))]
        #[unsafe(method_family = none)]
        fn collectionView_dropSessionDidEnd(
            &self,
            collection_view: &UICollectionView,
            session: &ProtocolObject<dyn UIDropSession>,
        );

        #[cfg(all(
            feature = "UIDragPreviewParameters",
            feature = "UIPreviewParameters",
            feature = "UIResponder",
            feature = "UIScrollView",
            feature = "UIView"
        ))]
        #[optional]
        #[unsafe(method(collectionView:dropPreviewParametersForItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn collectionView_dropPreviewParametersForItemAtIndexPath(
            &self,
            collection_view: &UICollectionView,
            index_path: &NSIndexPath,
        ) -> Option<Retained<UIDragPreviewParameters>>;
    }
);

/// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewdropintent?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct UICollectionViewDropIntent(pub NSInteger);
impl UICollectionViewDropIntent {
    #[doc(alias = "UICollectionViewDropIntentUnspecified")]
    pub const Unspecified: Self = Self(0);
    #[doc(alias = "UICollectionViewDropIntentInsertAtDestinationIndexPath")]
    pub const InsertAtDestinationIndexPath: Self = Self(1);
    #[doc(alias = "UICollectionViewDropIntentInsertIntoDestinationIndexPath")]
    pub const InsertIntoDestinationIndexPath: Self = Self(2);
}

unsafe impl Encode for UICollectionViewDropIntent {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for UICollectionViewDropIntent {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewdropproposal?language=objc)
    #[unsafe(super(UIDropProposal, NSObject))]
    #[thread_kind = MainThreadOnly]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(feature = "UIDropInteraction")]
    pub struct UICollectionViewDropProposal;
);

#[cfg(feature = "UIDropInteraction")]
extern_conformance!(
    unsafe impl NSCopying for UICollectionViewDropProposal {}
);

#[cfg(feature = "UIDropInteraction")]
unsafe impl CopyingHelper for UICollectionViewDropProposal {
    type Result = Self;
}

#[cfg(feature = "UIDropInteraction")]
extern_conformance!(
    unsafe impl NSObjectProtocol for UICollectionViewDropProposal {}
);

#[cfg(feature = "UIDropInteraction")]
impl UICollectionViewDropProposal {
    extern_methods!(
        #[unsafe(method(initWithDropOperation:intent:))]
        #[unsafe(method_family = init)]
        pub fn initWithDropOperation_intent(
            this: Allocated<Self>,
            operation: UIDropOperation,
            intent: UICollectionViewDropIntent,
        ) -> Retained<Self>;

        #[unsafe(method(intent))]
        #[unsafe(method_family = none)]
        pub fn intent(&self) -> UICollectionViewDropIntent;
    );
}

/// Methods declared on superclass `UIDropProposal`.
#[cfg(feature = "UIDropInteraction")]
impl UICollectionViewDropProposal {
    extern_methods!(
        #[unsafe(method(initWithDropOperation:))]
        #[unsafe(method_family = init)]
        pub fn initWithDropOperation(
            this: Allocated<Self>,
            operation: UIDropOperation,
        ) -> Retained<Self>;

        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new(mtm: MainThreadMarker) -> Retained<Self>;
    );
}

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewdropcoordinator?language=objc)
    pub unsafe trait UICollectionViewDropCoordinator:
        NSObjectProtocol + MainThreadOnly
    {
        #[unsafe(method(items))]
        #[unsafe(method_family = none)]
        fn items(&self) -> Retained<NSArray<ProtocolObject<dyn UICollectionViewDropItem>>>;

        #[unsafe(method(destinationIndexPath))]
        #[unsafe(method_family = none)]
        fn destinationIndexPath(&self) -> Option<Retained<NSIndexPath>>;

        #[cfg(feature = "UIDropInteraction")]
        #[unsafe(method(proposal))]
        #[unsafe(method_family = none)]
        fn proposal(&self) -> Retained<UICollectionViewDropProposal>;

        #[cfg(feature = "UIDragSession")]
        #[unsafe(method(session))]
        #[unsafe(method_family = none)]
        fn session(&self) -> Retained<ProtocolObject<dyn UIDropSession>>;

        #[cfg(all(feature = "UIDragInteraction", feature = "UIDragItem"))]
        #[unsafe(method(dropItem:toPlaceholder:))]
        #[unsafe(method_family = none)]
        fn dropItem_toPlaceholder(
            &self,
            drag_item: &UIDragItem,
            placeholder: &UICollectionViewDropPlaceholder,
        ) -> Retained<ProtocolObject<dyn UICollectionViewDropPlaceholderContext>>;

        #[cfg(all(feature = "UIDragInteraction", feature = "UIDragItem"))]
        #[unsafe(method(dropItem:toItemAtIndexPath:))]
        #[unsafe(method_family = none)]
        fn dropItem_toItemAtIndexPath(
            &self,
            drag_item: &UIDragItem,
            index_path: &NSIndexPath,
        ) -> Retained<ProtocolObject<dyn UIDragAnimating>>;

        #[cfg(all(
            feature = "UIDragInteraction",
            feature = "UIDragItem",
            feature = "objc2-core-foundation"
        ))]
        #[unsafe(method(dropItem:intoItemAtIndexPath:rect:))]
        #[unsafe(method_family = none)]
        fn dropItem_intoItemAtIndexPath_rect(
            &self,
            drag_item: &UIDragItem,
            index_path: &NSIndexPath,
            rect: CGRect,
        ) -> Retained<ProtocolObject<dyn UIDragAnimating>>;

        #[cfg(all(
            feature = "UIDragInteraction",
            feature = "UIDragItem",
            feature = "UITargetedDragPreview",
            feature = "UITargetedPreview"
        ))]
        #[unsafe(method(dropItem:toTarget:))]
        #[unsafe(method_family = none)]
        fn dropItem_toTarget(
            &self,
            drag_item: &UIDragItem,
            target: &UIDragPreviewTarget,
        ) -> Retained<ProtocolObject<dyn UIDragAnimating>>;
    }
);

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewplaceholder?language=objc)
    #[unsafe(super(NSObject))]
    #[thread_kind = MainThreadOnly]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct UICollectionViewPlaceholder;
);

extern_conformance!(
    unsafe impl NSObjectProtocol for UICollectionViewPlaceholder {}
);

impl UICollectionViewPlaceholder {
    extern_methods!(
        #[unsafe(method(initWithInsertionIndexPath:reuseIdentifier:))]
        #[unsafe(method_family = init)]
        pub fn initWithInsertionIndexPath_reuseIdentifier(
            this: Allocated<Self>,
            insertion_index_path: &NSIndexPath,
            reuse_identifier: &NSString,
        ) -> Retained<Self>;

        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new(mtm: MainThreadMarker) -> Retained<Self>;

        #[cfg(all(
            feature = "UICollectionViewCell",
            feature = "UIResponder",
            feature = "UIView",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// The returned block's argument must be a valid pointer.
        #[unsafe(method(cellUpdateHandler))]
        #[unsafe(method_family = none)]
        pub unsafe fn cellUpdateHandler(
            &self,
        ) -> *mut block2::DynBlock<dyn Fn(NonNull<UICollectionViewCell>)>;

        #[cfg(all(
            feature = "UICollectionViewCell",
            feature = "UIResponder",
            feature = "UIView",
            feature = "block2"
        ))]
        /// Setter for [`cellUpdateHandler`][Self::cellUpdateHandler].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setCellUpdateHandler:))]
        #[unsafe(method_family = none)]
        pub fn setCellUpdateHandler(
            &self,
            cell_update_handler: Option<&block2::DynBlock<dyn Fn(NonNull<UICollectionViewCell>)>>,
        );
    );
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewdropplaceholder?language=objc)
    #[unsafe(super(UICollectionViewPlaceholder, NSObject))]
    #[thread_kind = MainThreadOnly]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct UICollectionViewDropPlaceholder;
);

extern_conformance!(
    unsafe impl NSObjectProtocol for UICollectionViewDropPlaceholder {}
);

impl UICollectionViewDropPlaceholder {
    extern_methods!(
        #[cfg(all(
            feature = "UICollectionViewCell",
            feature = "UIDragPreviewParameters",
            feature = "UIPreviewParameters",
            feature = "UIResponder",
            feature = "UIView",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// The returned block's argument must be a valid pointer.
        #[unsafe(method(previewParametersProvider))]
        #[unsafe(method_family = none)]
        pub unsafe fn previewParametersProvider(
            &self,
        ) -> *mut block2::DynBlock<
            dyn Fn(NonNull<UICollectionViewCell>) -> *mut UIDragPreviewParameters,
        >;

        #[cfg(all(
            feature = "UICollectionViewCell",
            feature = "UIDragPreviewParameters",
            feature = "UIPreviewParameters",
            feature = "UIResponder",
            feature = "UIView",
            feature = "block2"
        ))]
        /// Setter for [`previewParametersProvider`][Self::previewParametersProvider].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// `preview_parameters_provider` block's return must be a valid pointer or null.
        #[unsafe(method(setPreviewParametersProvider:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPreviewParametersProvider(
            &self,
            preview_parameters_provider: Option<
                &block2::DynBlock<
                    dyn Fn(NonNull<UICollectionViewCell>) -> *mut UIDragPreviewParameters,
                >,
            >,
        );
    );
}

/// Methods declared on superclass `UICollectionViewPlaceholder`.
impl UICollectionViewDropPlaceholder {
    extern_methods!(
        #[unsafe(method(initWithInsertionIndexPath:reuseIdentifier:))]
        #[unsafe(method_family = init)]
        pub fn initWithInsertionIndexPath_reuseIdentifier(
            this: Allocated<Self>,
            insertion_index_path: &NSIndexPath,
            reuse_identifier: &NSString,
        ) -> Retained<Self>;

        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new(mtm: MainThreadMarker) -> Retained<Self>;
    );
}

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewdropitem?language=objc)
    pub unsafe trait UICollectionViewDropItem: NSObjectProtocol + MainThreadOnly {
        #[cfg(feature = "UIDragItem")]
        #[unsafe(method(dragItem))]
        #[unsafe(method_family = none)]
        fn dragItem(&self) -> Retained<UIDragItem>;

        #[unsafe(method(sourceIndexPath))]
        #[unsafe(method_family = none)]
        fn sourceIndexPath(&self) -> Option<Retained<NSIndexPath>>;

        #[cfg(feature = "objc2-core-foundation")]
        #[unsafe(method(previewSize))]
        #[unsafe(method_family = none)]
        fn previewSize(&self) -> CGSize;
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/uikit/uicollectionviewdropplaceholdercontext?language=objc)
    #[cfg(feature = "UIDragInteraction")]
    pub unsafe trait UICollectionViewDropPlaceholderContext:
        UIDragAnimating + MainThreadOnly
    {
        #[cfg(feature = "UIDragItem")]
        #[unsafe(method(dragItem))]
        #[unsafe(method_family = none)]
        fn dragItem(&self) -> Retained<UIDragItem>;

        #[cfg(feature = "block2")]
        #[unsafe(method(commitInsertionWithDataSourceUpdates:))]
        #[unsafe(method_family = none)]
        fn commitInsertionWithDataSourceUpdates(
            &self,
            data_source_updates: &block2::DynBlock<dyn Fn(NonNull<NSIndexPath>) + '_>,
        ) -> bool;

        #[unsafe(method(deletePlaceholder))]
        #[unsafe(method_family = none)]
        fn deletePlaceholder(&self) -> bool;

        #[unsafe(method(setNeedsCellUpdate))]
        #[unsafe(method_family = none)]
        fn setNeedsCellUpdate(&self);
    }
);
