ios – 将父容器的平移手势移交给嵌套的UICollectionView

ios – 将父容器的平移手势移交给嵌套的UICollectionView,第1张

概述我正在尝试构建一个复杂的拆分视图容器控制器,它有助于两个可变高度容器,每个容器都有自己的嵌套视图控制器.父控制器上有一个全局平移手势,允许用户在视图容器中的任何位置拖动,并在视图之间向上和向下滑动“分隔符”.它还有一些智能位置阈值检测逻辑,可以扩展任一视图(或重置分频器位置):   这很好用.还有很多代码可以构建它,我很乐意与大家分享,但我认为它不相关,所以暂时我会省略它. 我现在试图通过向底部视 我正在尝试构建一个复杂的拆分视图容器控制器,它有助于两个可变高度容器,每个容器都有自己的嵌套视图控制器.父控制器上有一个全局平移手势,允许用户在视图容器中的任何位置拖动,并在视图之间向上和向下滑动“分隔符”.它还有一些智能位置阈值检测逻辑,可以扩展任一视图(或重置分频器位置):

 

这很好用.还有很多代码可以构建它,我很乐意与大家分享,但我认为它不相关,所以暂时我会省略它.

我现在试图通过向底部视图添加集合视图来使事情复杂化:

我已经能够解决这个问题,这样我就可以用一个决定性的平移手势滚动拆分视图,然后快速轻d手指滚动收集视图(滑动手势,我想它是?),但是这个是一个非常低级别的体验:您无法平移视图并同时滚动集合视图,并期望用户始终如一地复制相似但不同的手势以控制视图对于交互来说太难了.

为了尝试解决这个问题,我尝试了几种委托/协议解决方案,其中我在拆分视图中检测分隔符的位置,并根据底部视图是否完全展开在集合视图上启用/禁用canCanceltouchesInVIEw和/或isUserInteractionEnable .这在某种程度上有效,但在以下两种情况下则不然:

>当拆分视图分隔符处于其默认位置时,如果用户平移到底部视图完全展开的位置,然后继续向上平移,则集合视图应开始滚动直到手势结束.
>当拆分视图分隔符位于顶部(底部容器视图完全展开)且集合视图不在顶部时,如果用户平移,则集合视图应滚动而不是拆分视图分隔符移动,直到集合视图到达其顶部位置,此时拆分视图应返回其默认位置.

这是一个说明此行为的动画:

鉴于此,我开始认为解决问题的唯一方法是在分割视图上创建一个委托方法,告诉集合视图何时底部视图处于最大高度,然后可以拦截父级的平移手势或向前相反,屏幕会触及集合视图吗?但是,我不知道该怎么做.如果我使用解决方案走在正确的轨道上,那么我的问题很简单:我如何将平移手势转发或移交到集合视图,并使集合视图的交互方式与通过触摸捕获的方式相同它在第一位?我可以使用pointInsIDe或触摸_____方法吗?

如果我不能这样做,我怎么能解决这个问题呢?

更新赏金猎人:我有一些零散的运气在集合视图上创建委托方法,并在拆分视图容器上调用它来设置属性shouldScroll,我通过它使用一些平移方向和定位信息来确定是否滚动视图应该滚动.然后我在UIGestureRecognizerDelegate的gestureRecognizer中返回这个值:shouldReceive touch:delegate方法:

// protocol delegateprotocol galleryCollectionVIEwDelegate {    var shouldScroll: Bool? { get }}// shouldScroll propertyprivate var _shouldScroll: Bool? = nilvar shouldScroll: Bool {    get {        // Will attempt to retrIEve delegate value,or self set value,or return false        return self.galleryDelegate?.shouldScroll ?? self._shouldScroll ?? false    }    set {        self._shouldScroll = newValue    }}// UIGestureRecognizerDelegate methodfunc gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,shouldReceive touch: UItouch) -> Bool {    return shouldScroll}// ----------------// Delegate property/getter called on the split vIEw controller and the logic:var shouldScroll: Bool? {    get {        return panTarget != self    }}var panTarget: UIVIEwController! {    get {        // Use intelligent position detection to determine whether the pan should be        // captured by the containing splitvIEw or the gallery's collectionvIEw        switch (vIEwState.currentposition,vIEwState.pan?.directionTravelled,galleryScene.galleryCollectionVIEw.isScrolled) {        case (.top,.up?,_),(.top,.down?,true): return galleryScene        default: return self        }    }}

这在开始滚动时可以正常工作,但在集合视图上启用滚动后效果不佳,因为滚动手势几乎总是覆盖平移手势.我想知道我是否可以使用gestureRecognizer连接:shouldRecognizeSimultaneouslyWith:,但我还没有.

解决方法 如何使底视图的子视图实际占用整个屏幕并将集合视图的contentInset.top设置为顶视图高度.然后在底部视图上方添加另一个子视图控制器.然后你唯一需要做的就是让父视图控制器成为委托,以监听底部视图的集合视图的滚动偏移并更改顶视图的位置.没有复杂的手势识别器的东西.只有一个滚动视图(集合视图)

更新:试试这个!

import Foundationimport UIKitlet topVIEwHeight: CGfloat = 250class SplitVIEwController: UIVIEwController,BottomVIEwControllerScrollDelegate {    let topVIEwController: topVIEwController = topVIEwController()    let bottomVIEwController: BottomVIEwController = BottomVIEwController()    overrIDe func vIEwDIDLoad() {        super.vIEwDIDLoad()        automaticallyAdjustsScrollVIEwInsets = false        bottomVIEwController.delegate = self        addVIEwController(bottomVIEwController,frame: vIEw.bounds,completion: nil)        addVIEwController(topVIEwController,frame: CGRect(x: 0,y: 0,wIDth: vIEw.frame.size.wIDth,height: topVIEwHeight),completion: nil)    }    func bottomVIEwScrollVIEwDIDScroll(_ scrollVIEw: UIScrollVIEw) {        print("\(scrollVIEw.contentOffset.y)")        let offset = (scrollVIEw.contentOffset.y + topVIEwHeight)        if offset < 0 {            topVIEwController.vIEw.frame.origin.y = 0            topVIEwController.vIEw.frame.size.height = topVIEwHeight - offset        } else {            topVIEwController.vIEw.frame.origin.y = -(scrollVIEw.contentOffset.y + topVIEwHeight)            topVIEwController.vIEw.frame.size.height = topVIEwHeight        }    }}class topVIEwController: UIVIEwController {    let label = UILabel()    overrIDe func vIEwDIDLoad() {        super.vIEwDIDLoad()        automaticallyAdjustsScrollVIEwInsets = false        vIEw.backgroundcolor = UIcolor.red        label.text = "top VIEw"        vIEw.addSubvIEw(label)    }    overrIDe func vIEwWillLayoutSubvIEws() {        super.vIEwWillLayoutSubvIEws()        label.sizetoFit()        label.center = vIEw.center    }}protocol BottomVIEwControllerScrollDelegate: class {    func bottomVIEwScrollVIEwDIDScroll(_ scrollVIEw: UIScrollVIEw)}class BottomVIEwController: UIVIEwController,UICollectionVIEwDataSource,UICollectionVIEwDelegate,UICollectionVIEwDelegateFlowLayout {    var collectionVIEw: UICollectionVIEw!    weak var delegate: BottomVIEwControllerScrollDelegate?    let cellpadding: CGfloat = 5    overrIDe func vIEwDIDLoad() {        super.vIEwDIDLoad()        vIEw.backgroundcolor = UIcolor.yellow        automaticallyAdjustsScrollVIEwInsets = false        let layout = UICollectionVIEwFlowLayout()        layout.minimumInteritemSpacing = cellpadding        layout.minimumlinespacing = cellpadding        layout.scrollDirection = .vertical        layout.sectionInset = UIEdgeInsets(top: cellpadding,left: 0,bottom: cellpadding,right: 0)        collectionVIEw = UICollectionVIEw(frame: vIEw.bounds,collectionVIEwLayout: layout)        collectionVIEw.autoresizingMask = [.flexibleWIDth,.flexibleHeight]        collectionVIEw.contentInset.top = topVIEwHeight        collectionVIEw.scrollindicatorInsets.top = topVIEwHeight        collectionVIEw.alwaysBounceVertical = true        collectionVIEw.backgroundcolor = .clear        collectionVIEw.dataSource = self        collectionVIEw.delegate = self        collectionVIEw.register(UICollectionVIEwCell.self,forCellWithReuseIDentifIEr: String(describing: UICollectionVIEwCell.self))        vIEw.addSubvIEw(collectionVIEw)    }    func collectionVIEw(_ collectionVIEw: UICollectionVIEw,numberOfItemsInSection section: Int) -> Int {        return 30    }    func collectionVIEw(_ collectionVIEw: UICollectionVIEw,cellForItemAt indexPath: IndexPath) -> UICollectionVIEwCell {        let cell = collectionVIEw.dequeueReusableCell(withReuseIDentifIEr: String(describing: UICollectionVIEwCell.self),for: indexPath)        cell.backgroundcolor = UIcolor.darkGray        return cell    }    func collectionVIEw(_ collectionVIEw: UICollectionVIEw,layout collectionVIEwLayout: UICollectionVIEwLayout,sizeforItemAt indexPath: IndexPath) -> CGSize {        let wIDth = floor((collectionVIEw.frame.size.wIDth - 2 * cellpadding) / 3)        return CGSize(wIDth: wIDth,height: wIDth)    }    func scrollVIEwDIDScroll(_ scrollVIEw: UIScrollVIEw) {        delegate?.bottomVIEwScrollVIEwDIDScroll(scrollVIEw)    }}extension UIVIEwController {    func addVIEwController(_ vIEwController: UIVIEwController,frame: CGRect,completion: (()-> VoID)?) {        vIEwController.willMove(toparentVIEwController: self)        vIEwController.beginAppearanceTransition(true,animated: false)        addChildVIEwController(vIEwController)        vIEwController.vIEw.frame = frame        vIEwController.vIEw.autoresizingMask = [.flexibleWIDth,.flexibleHeight]        vIEw.addSubvIEw(vIEwController.vIEw)        vIEwController.dIDMove(toparentVIEwController: self)        vIEwController.endAppearanceTransition()        completion?()    }}
总结

以上是内存溢出为你收集整理的ios – 将父容器的平移手势移交给嵌套的UICollectionView全部内容,希望文章能够帮你解决ios – 将父容器的平移手势移交给嵌套的UICollectionView所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/web/1075393.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存