美文网首页cocos2d-x
Cocos2d-x嵌套使用ScrollView的方案

Cocos2d-x嵌套使用ScrollView的方案

作者: 小城大麦 | 来源:发表于2017-04-09 14:47 被阅读149次

    Cocos2d-x嵌套使用ScrollView的方案
    比较典型的是皇室战争的UI设计,上下可以滚动,左右可以翻页
    假设我们做一个PageView内嵌套ScrollView的UI,直接使用组件,会产生PageView和ScrollView同时发生位移的问题。

    经过试验,只需要在UIScrollView.cpp的onTouchMove中
    增加一句,通过_direction控制scrollview的滚动行为即可

    //UIScrollView.cpp onTouchMove:
    if(_direction == Direction::NONE)
              return;
    

    之后,对于PageView的面板,增加一个触摸Layer,用于判断滑动的方向,如果为水平,则设置一个水平值,同时对ScrollView的面板,要透传PageView的ctx,通过ctx的isHorizontal来设置ScrollView的direction以及swallowTouches的行为。ScrollView也需要一个用于触摸检测的Layer。
    这样可以做到与皇室战争一样的控制效果。

    代码大概如下

    function MyPageViewPanel:onCreate()
        local pageView = ccui.PageView:create()
        local touchLayer = display.newLayer() -- {r=255,g=0,b=0}
        for i=1, 3 do
            local myPage = MyPage:create(self)
            pageView:addPage(myPage)
        end
        self:addChild(pageView)
        self:addChild(touchLayer)
        touchLayer:onTouch(handler(self,self.onTouchLayer))
    end
    function MyPageViewPanel:onTouchLayer(event)
        local touchPos = cc.p(event.x,event.y)
        local touchLayer = self.touchLayer
        if event.name == 'began' then
            local p = touchLayer:convertToNodeSpace(touchPos)
            local size = self.touchLayerSize
            local intersect = cc.rectContainsPoint(cc.rect(0,0, size.width, size.height), p)
            if intersect then
                self.pageStartPos = touchPos
                return true
            end
            return false
        end
    
        if event.name == 'moved' then
            if self.determined then return end
            local dp = cc.pSub(touchPos,self.pageStartPos)
            if  math.abs(dp.x) < 5 and math.abs(dp.y) < 5 or self.determined then
                return
            end
            self.determined = true
            local angle = cc.pToAngleSelf(dp)
            angle = math.deg(angle)
            -- 用于ScrollView的判断
            self.isHorizontal = isHorizontal(angle)
        end
    
        if event.name == 'ended' then
            self.determined = false
            self.isHorizontal = nil
        end
    end
    

    MyPage.lua

    function MyPage:onCreate(ctx)
        self.ctx = ctx
        self.scrollView = ccui.ScrollView:create()
        self.scrollView:setDirection(0) -- 初始方向为0
        self.touchLayer = display.newLayer()
        self:addChild(self.scrollView)
        self:addChild(touchLayer)
        touchLayer:onTouch(handler(self,self.onTouchLayer))
    end
    
    function MyPage:onTouchLayer(event)
        local touchPos = cc.p(event.x,event.y)
        local touchLayer = self.touchLayer
    
        if event.name == 'began' then
            local p = touchLayer:convertToNodeSpace(touchPos)
            local size = touchLayer:getContentSize()
            local intersect = cc.rectContainsPoint(cc.rect(0,0, size.width, size.height), p)
            if intersect then
                self.beganY = touchPos.y
                return true
            end
            return false
        end        
        
        if event.name == 'moved' then
            -- 上层还未确定是否为需要翻页或确实为翻页操作
            local isHorizontal = self.ctx.isHorizontal
            if isHorizontal == nil or isHorizontal then
                if self.scrollView:getDirection() ~= 0 then
                    self.scrollView:setDirection(0) -- 设置为NONE,不会移动
                    self.scrollView:setSwallowTouches(false)
                end
            else
                if self.scrollView:getDirection() == 0 then
                    self.scrollView:setDirection(1)
                    self.scrollView:setSwallowTouches(true)
                end
            end
        end
    
        if event.name == 'ended' then
            self.scrollView:setDirection(0)
            self.scrollView:setSwallowTouches(false)
        end
    end

    相关文章

      网友评论

        本文标题:Cocos2d-x嵌套使用ScrollView的方案

        本文链接:https://www.haomeiwen.com/subject/pbsdattx.html