Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Managing focus among Tableview and other scene elements
Started by akak Dec 20 2014 06:29 AM

10 replies to this topic
tableview focus
[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

akak

[GLOBAL: userInfoPane.html]
akak
  • Contributor

  • 181 posts
  • Corona SDK

Hi,

 

I have two scenes. I move from one another by swiping the screen. There is an overlaying invisible rectangle in each screen designated to swipe gesture detection

 

In a scene I added a tableview covering the entire screen and now conflict over focus between tableview and rectangle arises.

Basically if I put a return true in the function that handle the swipe detection for the rectangle I can't scroll the tableview and viceversa.

 

I was thinking about discerning between horizontal and vertical swipes (the tableview doens't have swipeable rows so I don't need it to handle horizontal swipes) as a method to pass focus to the interested object, but this is advanced stuff for my level of programming skill.

 

So if anyone could point me at the right direction to start with this it would be greatly appreciated.

Here's the code I am using so far:

---------- this below is just to set the tableview and 4 rows ---------------------

 tableView = widget.newTableView
{
    left = 0,
    top = 28,
    height = display.contentHeight - 100,
    width = display.contentWidth,
    hideBackground = true,
    onRowRender = onRowRender,
    onRowTouch = onRowTouch,
    listener = scrollListener
}
      sceneGroup:insert(tableView)

local isCategory = false
local rowHeight = 75
local rowColor = {default = { 1, 1, 1, 0 } }                    
local lineColor = {1, 1, 1, 0}

for i = 1, 4 do

  numContainer[i] = 0
  namesContainer[i] = i

  tableView:insertRow({
 
                        isCategory = isCategory,
                        rowHeight = rowHeight,
                        rowColor = rowColor,
                        lineColor = lineColor,
                        onEvent = onRowTouch,      
                        onRender = onRowRender,
                                            
                                            })   
end


------------ here I create the rectangle ---------------------

local swipeLayer = display.newRect( centerX, centerY, display.contentWidth, display.contentHeight )
    swipeLayer.alpha=0 --make it transparent
    swipeLayer.isHitTestable = true
    sceneGroup:insert( swipeLayer )

    swipeLayer:toFront( )



-------------- and this below is the function to detect the swipes and change scene accordingly ---------
               

    local function startDrag(event)
      local swipeLength = math.abs(event.x - event.xStart)
      print(event.phase, swipeLength)
      local t = event.target
      local phase = event.phase
      if "began" == phase then
        return true
      elseif "moved" == phase then
      elseif "ended" == phase or "cancelled" == phase then
        if event.xStart > event.x and swipeLength > 50 then
          print("Swiped Left")
            elseif event.xStart < event.x and swipeLength > 50 then
                print( "Swiped Right" )
          composer.gotoScene("counter", {effect="iosSlideRight01", time= 400})
        end
      end
    end


I'll keep on trying figure out a solution but in the meanwhile any suggestion will be helpful...

 

Thanks a lot!!!



[TOPIC: post.html]
#2

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,544 posts
  • Enterprise

If you don't detect a swipe, return false and let the touch event fall through.

 

Rob



[TOPIC: post.html]
#3

akak

[GLOBAL: userInfoPane.html]
akak
  • Contributor

  • 181 posts
  • Corona SDK

Hi Rob,

 

thanks for the reply!

 

The problem is that if I set to false the tableView only receives the touch, if I set to true the rectangle only does. It's either or....

 

So I would need some help to understand where to start to create a logic that set the focus to the tableview if the swipe is mostly a vertical one or set focus to the rectangle  if the swipe is mostly an horizontal one. Hope this is clear enough...

 

Thanks for the attention.



[TOPIC: post.html]
#4

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,544 posts
  • Enterprise

No, if you detect the swipe on the rectangle, return true.  If you don't detect a swipe, return false.



[TOPIC: post.html]
#5

akak

[GLOBAL: userInfoPane.html]
akak
  • Contributor

  • 181 posts
  • Corona SDK

I think I'm missing something here...

 

I tried to put this logic inside the 'moved' phase of the touch event related to the rectangle :

print (swipeLengthX, swipeLengthY)

       if swipeLengthX > 10 or swipeLengthY > 10 then  --- has a threshold to trigger the following statement

         if swipeLengthX < swipeLengthY then    

           return false    ---- if the swipe is being mostly vertical the touch is supposed to fall thorugh the rectangle 
                           ---- and reach the tableview????

         end

       end 

try put it also inside the other phases but none has produced the effect wanted, the focus stays on the rectangle since return true is in the begin phase of touch. If I don't put return true there and reverse the logic the focus on tableview only...

 

Also I tried to put in a runtime listener and reltice handler such as this:

local function globalTouch (event)

      local swipeLengthX = math.abs(event.x - event.xStart)
      local swipeLengthY = math.abs(event.y - event.yStart)
      local phase = event.phase
      if phase == "began" then

      elseif phase == "moved" then

        print (swipeLengthY, swipeLengthX)

      if swipeLengthY > swipeLengthX then
      display.getCurrentStage():setFocus( tableView )  else
      display.getCurrentStage():setFocus( swipeLayer )
      end
                  
      elseif phase == "ended" or phase == "cancelled" then

         
      end
  end

  Runtime:addEventListener( "touch", globalTouch )

but didn't work at all.

 

Can you kindly explain where return true (or false) is supposed to be put in the rectangle touch handler and sustained by what kind of logic.

 

Sorry, but I'm dealing with this touch events phases for the first time...



[TOPIC: post.html]
#6

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,544 posts
  • Enterprise

local function handleSwipe( event )

    if event .phase == "moved" then

         if math.abs(event.x - event.xStart) > 10 or math.abs(event.y - event.yStart) > 10 then -- swipe detected

               -- do swipe code

               return true

        end

   end

   return false

end



[TOPIC: post.html]
#7

akak

[GLOBAL: userInfoPane.html]
akak
  • Contributor

  • 181 posts
  • Corona SDK

Hi Rob,

 

thanks for the code.

 

It doesn't seem to be working though.

I tried also to modify it in several ways, printing the touch coordinates at all times to check on it.

 

I noticed that the touch event immediatly falls through the rectangle layer to the tableview unless return true is set in the began phase of the touch. Though, by doing so, the touch will always affect the rectangle, never reaching the tableview regardless of any conditional logic set to return false if the length of the swipe is less the a threshold.

 

I really don't know how to handle this thing.........



[TOPIC: post.html]
#8

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,544 posts
  • Enterprise

The rectangle is on top of the tableView right?  You want the events to fall through unless its a swipe.

 

Rob



[TOPIC: post.html]
#9

akak

[GLOBAL: userInfoPane.html]
akak
  • Contributor

  • 181 posts
  • Corona SDK

yes. I bring it on top with rectangle:tofront().

 

If return true is NOT inserted in the begin phase the touch falls through immediately.

I put checkers to print the coordinates of the touch all throughout the rectangle touch handler and in this case I get printed began 0, 0 and the touch interacts immediately with the tableview.

If I put return true in the began phase it stays that way and doesn't pass the touch to the tableview even if the drag action is completely vertical...

 

 

This is the handler function as you suggested to be set up, it only lets the tableview receive the touch:

local function startDrag(event)
      local swipeLengthX = math.abs(event.x - event.xStart)
      local swipeLengthY = math.abs(event.y - event.yStart)
      local phase = event.phase


if phase == "began" then
 
      print (phase, swipeLengthX, swipeLengthY)
   

    elseif phase == "moved" then

                  print (phase, swipeLengthX, swipeLengthY)


                if event.xStart > event.x and swipeLengthX > 50 then
                    print("Swiped Left")

                elseif event.xStart < event.x and swipeLengthX > 50 then
                   print( "Swiped Right" )
                   composer.gotoScene("counter", {effect="iosSlideRight01", time= 400})

          return true
           
     end     
  end
     return false
 end

Here's the other version of the code, giving the rectangle the touch via putting return true in the began phase. It actually detects the touch but never pass it down to the tableview regardless of the conditional statements:

 


local function startDrag(event)
      local swipeLengthX = math.abs(event.x - event.xStart)
      local swipeLengthY = math.abs(event.y - event.yStart)
      local phase = event.phase


if phase == "began" then
 
          return true           
     
 print (phase, swipeLengthX, swipeLengthY)
   
    elseif phase == "moved" then

                  print (phase, swipeLengthX, swipeLengthY)


                if event.xStart > event.x and swipeLengthX > 50 then
                    print("Swiped Left")

                elseif event.xStart < event.x and swipeLengthX > 50 then
                   print( "Swiped Right" )
                   composer.gotoScene("counter", {effect="iosSlideRight01", time= 400})

          return true    

          else return false
        
            end

end
     return false
 end

Then so far it's either one or the other has receives the touch, whithout passing it depending on the cases



[TOPIC: post.html]
#10

akak

[GLOBAL: userInfoPane.html]
akak
  • Contributor

  • 181 posts
  • Corona SDK

So is there a way to tackle this or I should change radically the UI of my project??



[TOPIC: post.html]
#11

corona273

[GLOBAL: userInfoPane.html]
corona273
  • Contributor

  • 482 posts
  • Enterprise

" There is an overlaying invisible rectangle in each screen designated to swipe gesture detection"

 

 

 

Um, the tableview already generates swipeLeft and swipeRight events for you: http://docs.coronalabs.com/api/library/widget/newTableView.html

 

Or, as an alternative, you can do this without the rectangle or swipe-left/swipe-right event by tracking "moved" events as Rob suggested. But in no case do you need the rectangle. The rectangle is not your friend. It is your enemy. Kill the rectangle. Murder it, bury it, sprinkle salt on its grave, and let us never speak of it again.




[topic_controls]
[/topic_controls]