Is it ok to override -handlePan: in a UIScrollView subclass?
i.e. my app won't get rejected from the app store?
Thanks for sharing your views.
Edit: what about calling -handlePan: in another method of my subclass?
In case anyone is interested, what I did instead of overriding was disabling the default UIPanGestureRecognizer and adding another instance of UIPanGestureRecognizer which is mapped to my custom handler.
Edit for twerdster:
I did it like this
//disables the built-in pan gesture
for (UIGestureRecognizer *gesture in scrollView.gestureRecognizers){
if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]){
gesture.enabled = NO;
}
}
//add your own
UIPanGestureRecognizer *myPan = [[UIPanGestureRecognizer alloc] init...];
//customize myPan here
[scrollView addGestureRecognizer:myPan];
[myPan release];
You can make the code even shorter.
//disables the built-in pan gesture
scrollView.panGestureRecognizer.enabled = NO;
//add your own
UIPanGestureRecognizer *myPan = [[UIPanGestureRecognizer alloc] init...];
[scrollView addGestureRecognizer:myPan];
[myPan release];
Related
I need to add a tableview inside a UIAlertView in Objective-C.
I tried to add a tableview as a subview of the alert view, but this is not working.
-(IBAction)ShowAlertWithTable
{
UIAlertView *select_dialog ;
select_dialog = [[[UIAlertView alloc] init] retain];
[select_dialog setDelegate:self];
[select_dialog setTitle:#"Alphabets"];
[select_dialog setMessage:#"\n\n\n\n"];
[select_dialog addButtonWithTitle:#"Cancel"];
UITableView * Type_table = [[UITableView alloc]initWithFrame:CGRectMake(20, 45, 245, 90)];
Type_table.backgroundColor = [UIColor redColor];
idType_table.delegate = self;
idType_table.dataSource = self;
[select_dialog addSubview:Type_table];
[Type_table reloadData];
[select_dialog show];
}
Why don't you use this library? It has all what you needs!
https://github.com/mindbrix/SBTableAlert
The above developer is using this 'Library' for AlertView
https://github.com/mindbrix/TSAlertView
The default alert isn't meant to take subviews. Although, you can write your own custom UIView that can meet your needs.
I know it is late to answer the question. I want the same functionality in my application and after a little search I found my answer.
You can use UIAlertView's setValue:<your UITableView> forKey:#"accessoryView" property to add your UITableView in UIAlertView. You can create the UITableview programmatically to set value above. You can create and set any object like UIView, UIImageView etc.
For more detail Please refer this answer
Is there a way to do this? Like tapping on any part of the screen dismisses the partial modal curl.
I thought about an invisible button, but that still doesn't cover the whole curl area.
Add gesture recognizers to your main view in viewDidLoad
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(getDismissed)];
UISwipeGestureRecognizer *swipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
action:#selector(getDismissed)];
swipeRecognizer.direction = UISwipeGestureRecognizerDirectionDown;
tapRecognizer.numberOfTapsRequired = 1;
tapRecognizer.numberOfTouchesRequired = 1;
tapRecognizer.delegate = self;
[self.view addGestureRecognizer:tapRecognizer];
[self.view addGestureRecognizer:swipeRecognizer];
-(void)getDismissed
{
// call dismissViewControllerAnimated:completion: by the presenting view controller
// you can use delegation or direct call using presentingViewController property
}
Then exclude in view that you don't want to trigger the dismissal
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
// touching objects of type UIControl will not dismiss the view controller
return ![touch.view isKindOfClass:[UIControl class]];
}
I've got a QuickLook view that I view some of my app's documents in. It works fine, but I'm having my share of trouble closing the view again. How do I create a touch event / gesture recognizer for which I can detect when the user wants to close the view?
I tried the following, but no events seem to trigger when I test it.
/------------------------ [ TouchPreviewController.h ]---------------------------
#import <Quicklook/Quicklook.h>
#interface TouchPreviewController : QLPreviewController
#end
//------------------------ [ TouchPreviewController.m ]---------------------------
#import "TouchPreviewController.h"
#implementation TouchPreviewController
- (id)init:(CGRect)aRect {
if (self = [super init]) {
// We set it here directly for convenience
// As by default for a UIImageView it is set to NO
UITapGestureRecognizer *singleFingerDTap = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleSingleDoubleTap:)];
singleFingerDTap.numberOfTapsRequired = 2;
[self.view addGestureRecognizer:singleFingerDTap];
[self.view setUserInteractionEnabled:YES];
[self.view setMultipleTouchEnabled:YES];
//[singleFingerDTap release];
}
return self;
}
- (IBAction)handleSingleDoubleTap:(UIGestureRecognizer *) sender {
CGPoint tapPoint = [sender locationInView:sender.view.superview];
[UIView beginAnimations:nil context:NULL];
sender.view.center = tapPoint;
[UIView commitAnimations];
NSLog(#"TouchPreviewController tap!" ) ;
}
// I also tried adding this
- (BOOL)gestureRecognizer:(UIGestureRecognizer *) gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*) otherGestureRecognizer {
return YES;
}
#end
Edit: For clarification, this is how I instantiate the controller:
documents = [[NSArray alloc] initWithObjects: filename , nil ] ;
preview = [[TouchPreviewController alloc] init];
preview.dataSource = self;
preview.delegate = self;
//set the frame from the parent view
CGFloat w= backgroundViewHolder.frame.size.width;
CGFloat h= backgroundViewHolder.frame.size.height;
preview.view.frame = CGRectMake(0, 0,w, h);
//refresh the preview controller
[preview reloadData];
[[preview view] setNeedsLayout];
[[preview view] setNeedsDisplay];
[preview refreshCurrentPreviewItem];
//add it
[quickLookView addSubview:preview.view];
Also, I've defined the callback methods as this:
- (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller
{
return [documents count];
}
- (id <QLPreviewItem>) previewController: (QLPreviewController *) controller previewItemAtIndex: (NSInteger) index
{
return [NSURL fileURLWithPath:[documents objectAtIndex:index]];
}
Edit2: One thing i noticed. If I try making swiping gestures, I get the following message. This could shed some light on what is wrong/missing?
Ignoring call to [UIPanGestureRecognizer setTranslation:inView:] since
gesture recognizer is not active.
I think your example code is incomplete. It isn't clear how you are instantiating the TouchPreviewController (storyboard, nib file or loadView.)
I have never used the class so I could be way out in left field.
If you've already instantiated a UITapGestureRecognizer in the parent viewController, it is absorbing the tap events and they aren't passed on to your TouchPreviewController.
I would implement the view hierarchy differently by attaching the UITapGestureRecognizer to the parent viewController and handle presentation and unloading of the QLPreviewController there.
I think you might not have to subclass QLPreviewController by instantiating the viewController from a nib file.
When your parent viewController's UITapGestureRecognizer got an event you would either push the QLPreviewController on the navigation stack or pop it off the navigation stack when done.
Hope this is of some help.
I have a viewcontroller that via "[self.view addSubview: secondView.view]," adds a second view. The problem is that the second view is added outside half.
secondView = [[SecondView alloc] initWithFrame: CGRectMake (-160, 0, 320, 460)];
[self.view addSubview: secondView.view]; "
I have noticed, however, that the part before the 0 (-160) is not interagibile. Is this normal? is there a way to solve?
Thank you!
You can allow subviews to receive touches outside of the parent's bounds by overriding pointInside:withEvent: for the parent view.
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
BOOL pointInside = NO;
// step through our subviews' frames that exist out of our bounds
for (UIView *subview in self.subviews)
{
if(!CGRectContainsRect(self.bounds, subview.frame) && [subview pointInside:[self convertPoint:point toView:subview] withEvent:event])
{
pointInside = YES;
break;
}
}
// now check inside the bounds
if(!pointInside)
{
pointInside = [super pointInside:point withEvent:event];
}
return pointInside;
}
I fear that given the way the UIResponder chain works, what you want is not directly possible (the superview will only pass to its subviews the events that it recognizes as affecting itself).
On the other hand, if you really need to have this view outside of its parent's frame, you could associate a gesture recognizer (reference) to the subview. Indeed, gesture recognizers are handled outside the normal touch event dispatching and it should work.
Try this for a tap:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[secondView addGestureRecognizer:singleTap];
i set a UITapGesture on my scrollView but because of that i can't use the button inside my scrollView... all it reads is the action of the gesture for the scrollView.
how am i gonna able to fix that?
i have this code:
UIGestureRecognizer *tapIt = [[ UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
imgTap = (UITapGestureRecognizer *)tapIt;
imgTap.numberOfTapsRequired = 1;
imgTap.numberOfTouchesRequired = 1;
[scrollView addGestureRecognizer:imgTap];
Try to prevent the touch from reaching the button in the gesture delegate:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
if ([touch.view isDescendantOfView:myButton]) {
return NO;
}
return YES;
}
I believe you can set cancelsTouchesInView property on your gesture to NO. Also there should be some method to ignore gestures in some parts of a view.