I create many subviews inside a UIScrollView. Let me call each subview a Cell. Each cell has a UILabel in it.
Then I implement touchEnd method on the Cell class, hoping that my app will respond to my touch whenever I tap on any of the cells. However I am not able to get response from all Cells. I can only get responses from the Cells that are above the bottom of my phone (iPhone 5 is 568 something) in the ScrollView whereas the contentsize of my ScrollView is 2300 * 1000, which means those cells below y = 568 don't respond to my touches. How can I fix this? Here is my touchEnd method in Cell class
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (![self.unit.text isEqualToString:#"?"]) {
[self.soundManager playSoundForUnit:self.unit];
}
}
You have to make CustomScrollView :
.h :
#protocol CustomScrollViewDelegate <NSObject>
#optional
// optional becuase we always don't want to interact with ScrollView
- (void) customScrollViewTouchesEnded :(NSSet *)touches withEvent:(UIEvent *)event;
#end
#interface CustomScrollView : UIScrollView
#property (weak, nonatomic) id<CustomScrollViewDelegate> touchDelegate;
// delegate was giving error becuase name is already there in UIScrollView
#end
.m :
#import "CustomScrollView.h"
#implementation CustomScrollView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!self.dragging) {
//NSLog(#"touchesEnded in custom scroll view");
if (_touchDelegate != nil) {
if ([_touchDelegate respondsToSelector:#selector(customScrollViewTouchesEnded:withEvent:)]) {
[_touchDelegate customScrollViewTouchesEnded:touches withEvent:event];
}
}
}
else {
// it wouldn't be called becuase at the time of dragging touches responding stops.
[super touchesEnded:touches withEvent:event];
}
}
#end
Related
I have a UIButton not responding to touch event. And the button only has some subviews not handling events. So I replaced it with my customized UIButton to find out what happened. Below is my code:
#interface CustomButton : UIButton
#end
#implementation CustomButton
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
}
-(BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
return [super beginTrackingWithTouch:touch withEvent:event];
}
#end
I found out that the touchesBegan:withEvent: method was called, but the beginTrackingWithTouch:withEvent: was never called. It seems that the event has been dispatched to my button, but I don't understand why the event has never been tracked. Any clue will be appreciated.
Disable user interaction of views that are above the button which are not listening for events. Check that the button has user interaction enabled. Check the frame size of UIButton and ensure that it is not zero specifically when using auto layout programatically.
I'm working on an iPhone app in StoryBoard. It has a UIScrollView in it. Inside of this, it has a SliderView, which is a custom subclass that I wrote that derives from UIView.
Inside SliderView I'm executing this method:
// Inside SliderView.m
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// whenever someone touches inside of SliderView, this method fires
}
Here's my problem. In my StoryBoard, I would like to disable the bouncy vertical scrolling of the UIScrollView.
Normally, that would be easy. Assuming I had connected the UIScrollView as an IBOutlet in the app's main ViewController, I could paste this into that file:
// Inside ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.scrollView.bounces = NO;
}
Unfortunately, this isn't so easy because I want this disabling to occur only when touchesBegan is fired.
So here's where I'm completely stumped: how can I get the SliderView.m file to communicate with the ViewController.m file?
Use delegate for this:
SliderView.h
// SliderView.h
#protocol SliderViewDelegate <NSObject>
#optional
- (void) isScrollViewToBounce:(BOOL)isBounce;
#end
#interface SliderView : UIView
#property (nonatomic, weak) id <SliderViewDelegate> sliderViewDelegate;
#end
SliderView.m
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.sliderViewDelegate isScrollViewToBounce:NO];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self.sliderViewDelegate isScrollViewToBounce:YES];
}
ViewController.m
#import "SliderView.h"
#interface ViewController () <SliderViewDelegate>
#end
viewDidLoad() method
- (void)viewDidLoad {
[super viewDidLoad];
self.sliderView setSlideViewDelegate:self];
}
Create Delegate method in your ViewController:
- (void) isScrollViewToBounce:(BOOL)isBounce {
self.scrollView.bounces = isBounce;
}
Also do not forget to remove delegation
#pragma mark Memory management methods
//---------------------------------------------------------------
- (void)dealloc {
// Release resources here.
[self.scrollView setSliderViewDelegate:nil]
}
I got a textField declared as an outlet, it is correctly connected via the storyboard:
#property (weak, nonatomic) IBOutlet UITextField *addBillEventName;
I also have set the delegate of the UITextfield via code and via the storyboard, code:
-(void) viewDidAppear:(BOOL)animated {
[self.addBillEventName setDelegate:self];
}
So you would expect that methods like this:
-(void) viewDidAppear:(BOOL)animated {
[self.addBillEventName setDelegate:self];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"Touch end controller");
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(#"Touch end controller");
}
Would trigger, but they don't get triggered. Weird is that charactersInRange does work.
Anyone familiar with this problem?
I have a subclassed UIView called TargetView that contains several CGPaths. When users click on any of the CGPaths (in UIView's touchesBegan) I would like to make changes to the parent view controller. Here is code from TargetView (UIView)
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
CGPoint tap = [[touches anyObject] locationInView:self];
if(CGPathContainsPoint(region, NULL, tap, NO)){
// ...do something to the parent view controller
}
}
How might I do this? Thanks!
I would suggest that you set the parent view controller as a delegate to the child view controller. Then when touches are detected in the child view controller, you can call the delegate to respond. This way, your child view controller will only have a weak reference to the parent.
if (CGPathContainsPoint(region, NULL, tap, NO)) {
[self.delegate userTappedPoint:tap];
}
You need to pass a reference to the parent viewController to the UIView on allocation, and store this in a property on the UIView Then you have a reference to the parent and you can use this to call methods/set properties on that parent.
Use protocol and set parent view controller as delegate for your UIView.
In your UIView subclass .h file:
#protocol YourClassProtocolName <NSObject>
#optional
- (void)methodThatNeedsToBeTriggered;
#end
#interface YourClass : UIView
...
#property(weak) id<YourClassProtocolName> delegate;
#end
In .m file:
#interface YourClass () <YourClassProtocolName>
#end
#implementation YourClass
...
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
CGPoint tap = [[touches anyObject] locationInView:self];
if(CGPathContainsPoint(region, NULL, tap, NO)){
if (_delegate && [_delegate respondsToSelector:#selector(methodThatNeedsToBeTriggered)]) {
[_delegate methodThatNeedsToBeTriggered];
}
}
}
#end
And now set needed UIViewController as delegate for this new protocol and implement methodThatNeedsToBeTriggered in it.
I am unable to call touchesBegan from a text view.
Its working fine for me in a dummy project where i have just a View and inside it a TextView.
When I try to do it in real proj , having hierarchy like: (i feel here is some problem)
view (parent)
scrollview(subview)
view (grandSubview
textview.
the delegate is not getting called.
.h file
#interface ActionViewController : UIViewController<UITextViewDelegate>
#property (weak, nonatomic) IBOutlet UITextView *actionTakenTextView;
.m file
- (void)viewDidLoad
{
[super viewDidLoad];
actionTakenTextView.delegate=self; //actiontakentextview is the text view i am using.
actionTakenTextView.layer.borderWidth=1;
actionTakenTextView.layer.borderColor=[[UIColor grayColor] CGColor];
// Below property is to set rounded corner of text view.
actionTakenTextView.layer.cornerRadius=5.0;
actionTakenTextView.clipsToBounds=YES;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(#"touchesBegan:withEvent:");
[self.view endEditing:YES];
[super touchesBegan:touches withEvent:event];
}
I feel i am missing something very small here..please help.
thanks in adv.