I need to have a UIButton inside a UITableViewCell, everything works fine except when I touch inside the button and move my finger, the table does not scroll.
I tried to subclass UIButton and in touchesMoved: method send the same message to self.nextResponder, or call touchesCancelled and hope it will pass the touch event to next responder, they both do not work.
Is there any good way to solve this problem? Currently I am adding a UIView on top of the UITableViewCell, and detecting touch events manually, passing result to the button or the rest of the cell respectively, but this is a little bit dirty.
What you can try is setting the delaysContentTouches property of the UITableView to YES.
Additionally you can set the canCancelContentTouches to YES.
If the value of this property is NO, the scroll view does not scroll
regardless of finger movement once the content view starts tracking.
Source: UIScrollView Class Reference
Try:
_yourTableView.delaysContentTouches = YES;
_yourTableView.canCancelContentTouches = YES;
The best way is to make a custom cell and do your work neatly.
Check the Apple docs
Related
I have a uilabel (and other labels as well) inside a uiview.
I added a gesture that when the label is tapped on I perform some ibaction.
The action is not triggered, however if i place the label outside the uiview (meanning it's not a child of the uiview) than it works fine. I placed it back inside the view than it's stop triggering the action.
any idea why?
something when the label is inside the uiview makes it not react to the gesture and I'm not sure why (despite the fact that both the uiview and the label have 'User interaction enabled).
TIA
Or just not have a UILabel and have only the text of the button be visible, that way you dont have to have a UILabel and a UIButton (from a memory perspective).
I think the problem here is that the UILabel is receiving the touch event instead of the UIView. Try adding the following code (modified to fit your label, of course) to the viewDidLoad method:
myLabel.userInteractionEnabled = FALSE;
This should allow touch events to pass through to the UIView. Why are you doing this? Might it not be easier to work with a UIButton?
apparently there was an issue with the parent control, I redrew the View and it worked fine. Thanks for your comments.
I am working on a custom controller. I want to create a slider, to choose between more options. The problem is that when I touch the button I want to it doesn't call my touchesBegan method. But if I press in any other part of my view, it works. How can I get my button to move?
Thanks.
The UIButton is capturing the touch events. if you try this
myButton.userInteractionEnabled = NO;
Then it will no longer consume the touch events but it will also no longer fire the onTouchUpInside event. In this case you process all of the touches in the super view and position the slider button accordingly.
It should drag just fine. This will work for any UIView.
touchesBegan will not work on a UIButton .. for that to work you will have to subclass UIButton and implement touchesBegan
refer this answer for more info https://stackoverflow.com/a/4863734/919545
Why don't you create a custom UIView and avoid using the UIButton class? It is simplier that subclassing UIButto or to set
myButton.userInteractionEnabled = NO;
I have a custom cell with a uitextfield inside. I want to hide the keyboard when the user touch the screen, I put a custom uibutton over my tableView, and in the touch up inside event, I call
-(IBAction) hideKeyBoard
{
[customcell.textfield resignFirstResponder];
}
is it the right way to hide the keyboard with a uitableview because it don't works
No, a UIButton over your tableview is going to obstruct touches to the table, and views with alpha less than something like 0.1.
One method would be to subclass UITableView and override touchesBegan to detect a touch. From there, you have many options for how to deal with resigning first responder, notification, delegate method, reference to the text field.
I have a custom UITableViewCell. It has a UIView which is added to the "contentView" of the UITableViewCell. For any update, I'm redrawing that UIView by calling its "setNeedsDisplay" and implementing drawing inside "drawRect" method of the UIView.
The UITableViewCell overrides "willTransitionToState" and according to the bit mask value, asks the UIView to redraw.
Because I'm asking the UIView to redraw itself again, every time I do a "swipe to delete", I see the cell "flicker" a moment; even the text that didn't move position due to the Delete button suffers from a flicker since everything is being redrawn.
I'm aware that a possible solution is not to call "setNeedsDisplay" of the UIView from the "willTransitionToState" but instead call "setNeedsLayout" and have the UIView implement "layoutSubviews".
This is where I'm stuck at: how can I re-layout my UIView since everything inside my UIView is "drawn" (I use "drawInRect" and "drawAtPoint" methods for strings and images). There is also a string on the right side that I wanna hide when the "Delete" button appears (like in the Messages app in iPhone).
How can I do this by doing re-layout instead of re-draw?
Thank you!!!
I think there's an issue with your approach. Rather than draw everything, it's better to set up your subviews in an init method, or in the NIB.
In the willTransitionToState method, update whatever subviews according to the state transition.
In layoutSubviews, update each subview's origin and size as required.
Here's some detail from the willTransitionToState documentation. Although, I'm sure you'd have seen this already:
Subclasses of UITableViewCell can implement this method to animate additional changes to a cell when it is changing state. UITableViewCell calls this method whenever a cell transitions between states, such as from a normal state (the default) to editing mode. The custom cell can set up and position any new views that appear with the new state. The cell then receives a layoutSubviews message (UIView) in which it can position these new views in their final locations for the new state. Subclasses must always call super when overriding this method.
I know this has been talked about a lot. I think I've gone thru every question on this site, and still have not been able to get this working.
I'm new to developing but I have a good sense of what's going on with all of my code. I definitely don't have a lot of experience though, this is my first iPhone app.
I'm making a data entry field that is comprised of multiple UITextFields within a UIScrollView. I'll avoid explaining the other details for now, as it seems its a very basic problem. Without a scrollview, the textfields work perfectly. I can touch the textfield and the keyboard or picker view show up appropriately. When I add the textfields to a scrollview, the scrollview works, but then the text fields don't receive my touches.
Here's the key: When 'User Interaction' is ENABLED, the scrollview works but the textfield touches are NOT registered. When 'User Interaction' is DISABLED, the scrollview doesn't work, but the textfield touches ARE registered and the keyboard/picker pops up.
From the other posts I have seen people creating subclasses and overriding the touches in a separate implementation. I've seen people using custom content views (subviews?), I've seen some solutions that are now obsolete since the APIs have changed in newer versions of the SDK, and I am just completely stuck.
I will leave out my code for now, because maybe there is a solution that someone has without requiring my code. If someone needs to see my code, I will put it up. My app is being written in the 3.1.3 SDK.
If anyone has ANY information that could help, it would be so greatly appreciated.
Here is what worked for me in Xcode 4.3.3.
In the storyboard, select your scrollview. Select Attribute Inspector on the right side. Uncheck Delays Content Touches.
It sounds like you're using IB to do a lot of your UI layout. If you take a programmatic approach you could set-up the following view hierarchy which should work.
Your view controller object managing your scroll view and your text fields should have a UIScrollView object and a UIView object (in addition to any UITextField objects you need). In the loadView method of the view controller class, allocate and initalize the UIView object and add your text fields to it as subviews. At the end of the method, allocate and initalize the UIScrollView object then add the UIView to the UIScrollView as a subview.
As an example, if your UIScrollView object were called scrollView and your UIView object called mainView the following lines at the end of the view controller's loadView method would properly set up the scroll view with the main view with the text fields on it:
scrollView = [[UIScrollView alloc] initWithFrame: [[UIScreen mainScreen] bounds] ];
scrollView.backgroundColor = [UIColor whiteColor];
scrollView.contentSize = mainView.frame.size;
[scrollView addSubview: mainView];
self.view = scrollView;
You may need to enable / disable user interaction for both the scroll view and text fields as necessary.
If possible you might best using different touch mechanisms for each process (scrolling and textfield input).
Maybe you can check the time differential between touch start and end such that you can detect the difference between a drag (scroll) and a tap (text input).
Having said that if you propagate the touches up from the textfields to the scrollview you should be fine. One thing I use is:
[myObject addTarget:self action:#selector(itemTouchedUpInside:) forControlEvents:UIControlEventTouchUpInside];
which passes the object touched so you can identify it and act accordingly.