How to make button in UIScrollView highlight when tapping on it quickly without setting UIScrollView's delaysContentTouches to NO - ios

If you just put a UIButton in a UIScrollView, the button does not highlight when you tap on it quickly. Instead, you have to tap and hold for a while before the button highlights. According to the documentation, this is because UIScrollView waits a little to determine if the user intends to drag the scroll view before forwarding touches to the views in the scroll view.
As noted in several Stackoverflow answers (such as this one: https://stackoverflow.com/a/19656611/2135004), the solution is to prevent this delay by setting the delaysContentTouches property of UIScrollView to NO. (An additional step is to subclass UIScrollView to override touchesShouldCancelInContentView: to return YES for UIButtons, so the user can still scroll the scroll view if the user initially touched the button in the scroll view.)
However, interacting with the App Store app seems to suggest another solution. (Although it may be a little picky, one reason I am not going with the solution where delaysContentTouches is set to NO is because I do not want the button to highlight if the user quickly drags on a button to scroll the scroll view. This is actually the highlighting behavior UITableViewCells.) Consider the following screenshot of the App Store app:
The blue "Quick Links" buttons (namely, "App Collections," "Game Collections," and "Apps Made by Apple") seem to be implemented as UIButtons with the UIButtonTypeSystem style because their highlighting fades in and out as you drag your finger in and out of them. In addition, the scroll view's delaysContentTouches property does not seem to be set to NO because the blue "Quick Links" buttons do not highlight when you quickly tap on them. However, the gray bordered buttons (namely, "Redeem," "Send Gift," and "Apple ID: ...") do highlight when you quickly tap on them! (Their highlighting also fades in and out as you drag your finger in and out of them.) Also note that the buttons do not highlight when you just happen to be touching them when you drag the scroll view.
How are these gray bordered buttons implemented? The key behavior I want is that they highlight when you quickly tap on them in a scroll view that delays content touches. (They should also highlight and unhighlight as you drag your finger in and out of them like plain UIButtons, preferably by fading their highlighting.) I do not see how this could be easily achieved by just subclassing UIButton, and I'm not even sure if somehow subclassing UIControl to create a new button class would work either.

I think what's happening here is that the grey button's highlighted state is being set when its action fires, then unset when the resulting alert or sheet is shown.
(If you're not showing an alert or a sheet, you'll just have to arrange for it to be unhighlighted on the next run loop.)

Related

Scrollview with button(s) that can appear and disappear on tap

I have created a scrollview, to scroll through an array of images, and I have a button and soon to be 6 more on the screen. Now to make the photo nicer, I would simply like to make the buttons disappear and when tapped on again to appear.
Now I know how to do this with just a regular view with simple isHidden, and how to make it reappear when tapped on, but I am largely confused on how to do it on a scrollview because on a regular view, I just put a button over the whole screen but with the scrollview I can't. Any ideas anyone? Still getting better at this one step at a time, and one question at a time.
Here is a screenshot: http://imgur.com/a/Ll6QO
Use a gesture recognizer on the scrollview.
Add a touch gesture recognizer to toggle the visibility of your buttons. Be sure that the gesture recognizer doesn't cancel touches in view, otherwise you won't be able to scroll.

UIButtons not working in Scroll View

I have a Scroll View with a View (content view) inside of it. I've added two buttons to test. The Scroll View scrolls fine but the buttons within the content view are not clickable. I've seen plenty of posts saying this issue happens when they programmatically add UIButtons to the View, but I am not doing this. Here is my exact process:
Drag the Scroll View onto the main view. Add 4 constraints
Drag the Content View onto the Scroll View. Add 4 constraints.
Add 2 Buttons (one high and one low to test scrolling) to the Content View.
This is all I am doing, no code at this point. Is there anything else I have to do to allow the buttons to be clicked? Here is a screenshot of my xib:
Update:
When hooking the button up to a simple IBAction and logging a message, it turns out it IS being pushed and working properly. However, when the button is pushed, the button isn't changing colors like it should (its "pressed" state is not appearing). Any ideas why?
First make the button to custom type
Select button from storyboard then on right attributed inspector change its "state config" to whatever you need like Highlighted, selected, Disabled and default and choose the colour for each state.
Now you can see the colour change on that button.
A UIScrollView first needs to know whether or not you are going to scroll before letting the touch pass to its child views. If you want the child views to get the touch immediately, set the UIScrollView's delaysContentTouches to NO.

Opaque UIView not letting me scroll UIView behind it

I have a view hierarchy that looks like this.
buttonsView <-- UIView with 1-3 small buttons
MKMapView <-- bottom most view
When my buttonsView is shown I still want the user to be able to scroll the MKMapView if the user is NOT touching any of the buttons.
I have tried different combinations of userInteractionEnabled = NO but nothing helps.
You have several ways to solve this:
The top view with the three small buttons can be much smaller, so that is only covers the area the three small buttons need. By this, the top view won't cover the map view, and you can still scroll it around.
Implement your own hitTest / pointInside functions to let the top view decide whether it wants to catch an event (when you tap on one of its buttons) or it decides to send the event further up the responder chain (when the user taps anything else). See for example here for possible ways to do it: Allowing interaction with a UIView under another UIView
The view on the front takes all the interactions. No matter if it is transparent or not. You should pass the gestures to the MKMapView in the bottom.
Another approach is to resize the view with the buttons to not cover the whole MKMapView, but only the part with the buttons. In that way, the user will be able to scroll only in the area where there are no buttons.

ios set background of a UITableViewCell

If you have seen the mailbox app you can swipe cells left and right and they have a UIView underneath that like green with a checkmark or whatever. I want to do this same thing. I have a tableView with custom cells that have gesture recognizers to animate/swipe them left and right but I can't figure out how to place a background underneath them. Does anyone know how to do this?
It might work if you add the subview and then bring the cell's content view above it, and then slide the content view over.
You could also just have a mask that clips the the visibility of your button container, and then animate the size of the mask so that it becomes visible as your cell content slides away.
You would want to add the container on the swipe before the animation starts, and then remove it after the animation stops when hiding it.
If placing it beneath the content view doesn't work, then use the mask, which will.

UIScrollView of buttons - TouchUpInside?

I have a UIScrollView filled with buttons that I created programatically.
Paging is enabled and whenever users scroll through the pages rapidly they always end up accidentally clicking buttons that they didn't mean to... Should I be using TouchUpInside or is this the reason for my problem?
One thing I've noticed is that if a user presses the button then slides the scrollview doesn't move but if they slide the scroll view very quickly and let go half way through the scroll and they grabbed the scrollview on the button then the button will become "pressed" is there any way I can have the buttons not do anything if they are clicked while scrolling is in progress or is the solution simpler than that (i.e. just changing the touch event to a different listener)
This did the trick!
setExclusiveTouch:YES

Resources