UITableView inside UIScrollView not receiving first tap after scrollling

前端 未结 14 1729
北海茫月
北海茫月 2020-11-29 04:31

Brief

I am having an issue with a UITableView inside a UIScrollView. When I scroll the external scrollView, the table<

相关标签:
14条回答
  • 2020-11-29 05:07

    Gesture recognizers won't work correctly for two embedded scroll views or subclasses.

    Try a workaround:

    1. Use transparent, custom, and overlaying everything in cell UIButton with proper tag, or subclass UIButton and add a index path property and overwrite each time in reused cell.

    2. Add this button as a property to your custom cell.

    3. Add target for desired UIControlEvent (one or more) that points to your UITableViewDelegate protocol adopting class.

    4. Disable selecting in IB, and manually manage the selection from code.

    This solution requires attention for cases of single/multi selection.

    0 讨论(0)
  • 2020-11-29 05:14
    1. Drop a UIButton over your UITableViewCell and create the outlet as "btnRowSelect".
    2. In your view controller put this code in cellForRowAtIndexPath

      cell.btnRowSelect.tag = indexPath.row
      cell.btnRowSelect.addTarget(self, action: Selector("rowSelect:"), forControlEvents: .TouchUpInside)
      
    3. Add this function to your viewController as well-

      func rowSelect (sender:UIButton) {
      // "sendet.tag" give you the selected row 
      // do whatever you want to do in didSelectRowAtIndexPath
      }
      

    This function "rowSelect" will work as didSelectRowAtIndexPath where you get the row"indexPath.row" as "sender.tag"

    0 讨论(0)
  • 2020-11-29 05:15

    The scrollview is trying to figure out whether the user's intention is to scroll or not, so it's delaying the initial touch on purpose. You can turn this off by setting delaysContentTouches to NO.

    0 讨论(0)
  • 2020-11-29 05:17

    I've encountered a UITableView with scrollEnabled being NO within a UIScrollView in some legacy code. I have not been able to change the existing hierarchy easily nor enable scrolling, but come up with the the following workaround for the first tap problem:

    @interface YourOwnTableView : UITableView
    @end
    
    @implementation YourOwnTableView
    
    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    
        [super touchesCancelled:touches withEvent:event];
    
        // Note that this is a hack and it can stop working at some point.
        // Looks like a table view with scrollEnabled being NO does not handle cancellation cleanly,
        // so let's repeat begin/end touch sequence here hoping it'll reset its own internal state properly
        // but won't trigger cell selection (the touch passed is in its cancelled phase, perhaps there is a part
        // of code inside which actually checks it)
        [super touchesBegan:touches withEvent:event];
        [super touchesEnded:touches withEvent:event];
    }
    
    @end
    

    Again, this is just a workaround working in my specific case. Having a table view within a scroll view is still a wrong thing.

    0 讨论(0)
  • 2020-11-29 05:20

    I ran into this same problem and figured out a solution!!

    You need to set the delaysTouchesBegan to true on your scrollview so that the scrollview sends its failed scrolled-gesture (i.e. the tap) to its children.

    var delaysTouchesBegan: Bool - A Boolean value determining whether the receiver delays sending touches in a begin phase to its view.

    When the value of the property is YES, the window suspends delivery of touch objects in the UITouchPhaseBegan phase to the view. If the gesture recognizer subsequently recognizes its gesture, these touch objects are discarded. If the gesture recognizer, however, does not recognize its gesture, the window delivers these objects to the view in a touchesBegan:withEvent: message (and possibly a follow-up touchesMoved:withEvent: message to inform it of the touches’ current locations).

    https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIGestureRecognizer_Class/index.html#//apple_ref/occ/instp/UIGestureRecognizer/delaysTouchesBegan

    But there's a catch...it doesn't work if you do it directly on the scrollview!

    // Does NOT work
    self.myScrollview.delaysTouchesBegan = true
    

    Apparently this is an iOS bug where setting this property doesn't work (thank you apple). However there's a simple workaround: set the property directly on the scrollview's pan gesture. Sure enough, this worked for me perfectly:

    // This works!!
    self.myScrollview.panGestureRecognizer.delaysTouchesBegan = true
    
    0 讨论(0)
  • 2020-11-29 05:20

    I have the same issue, Then refer to "Nesting Scroll Views" as lxx said.

    https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/UIScrollView_pg/NestedScrollViews/NestedScrollViews.html

    An example of cross directional scrolling can be found in the Stocks application. The top view is a table view, but the bottom view is a horizontal scroll view configured using paging mode. While two of its three subviews are custom views, the third view (that contains the news articles) is a UITableView (a subclass of UIScrollView) that is a subview of the horizontal scroll view. After you scroll horizontally to the news view, you can then scroll its contents vertically.

    It is work

    0 讨论(0)
提交回复
热议问题