UIScrollView delegate - ios

I have this piece of code, which is in init.
This should be some swipe cell, which is created by UIScrollView and there is some another view (my own action view) below cell.
My problem: if I want swipe my cell, UIScrollView doesnt call delegate methods :-/
Any suggestions? thx
self.cellState = kCellStateClosed;
self.cellScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, kSWIPECELL_WIDTH, kSWIPECELL_HEIGHT)];
self.cellScrollView.delegate = self;
self.cellScrollView.showsHorizontalScrollIndicator = NO;
self.cellScrollView.scrollsToTop = NO;
self.cellScrollView.scrollEnabled = YES;
self.tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(selectCell)];
self.longPressGestureRecognizer = [[PAPLongPressGestureRecognizer alloc] initWithTarget:self action:#selector(scrollViewPressed:)];
self.longPressGestureRecognizer.minimumPressDuration = 0.1;
[self.cellScrollView addGestureRecognizer:self.tapGestureRecognizer];
[self.cellScrollView addGestureRecognizer:self.longPressGestureRecognizer];
// Create the content view that will live in our scroll view
self.scrollViewContentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kSWIPECELL_WIDTH, kSWIPECELL_HEIGHT)];
self.scrollViewContentView.backgroundColor = [UIColor whiteColor];
[self.cellScrollView addSubview:self.scrollViewContentView];
// Add the cell scroll view to the cell
UIView *contentViewParent = [self.subviews firstObject];
NSArray *cellSubviews = [contentViewParent subviews];
[self insertSubview:self.cellScrollView atIndex:0];
for (UIView *subview in cellSubviews)
{
[self.scrollViewContentView addSubview:subview];
}
self.containingTableView.directionalLockEnabled = YES;
//alloc action view
self.actionView = [[PAPActionCellView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height) andPages:[self createActionPages] parentCell:self];
[self.cellScrollView insertSubview:self.actionView belowSubview:self.scrollViewContentView];

What you are missing is to set the contentSize of your UIScrollView, when you set it to some bigger value than its bounds, it will start to scroll, i.e:
self.cellScrollView.contentSize = CGSizeMake(2* kSWIPECELL_WIDTH, kSWIPECELL_HEIGHT);

Related

UITapGestureRecognizer is not called in sub views?

My scenario is that there will be many sub views in the main view and tapping on each sub view should generate different result.
My approach is for each sub view to implement its own tap recognizer, instead of for the main view to have one single tap recognizer and calculate the which sub view's area the user has tapped in. Is this a correct and viable approach?
I have tried this approach but it doesn't seem to work. The tap method never gets called. I read lots of articles on stackoverflow but they didn't seem to help.
For example, although the sub view is not an image view I still manually set its userInteractionEnabled property to YES, as some posts suggested. But that didn't help.
Below is the main code of the sub view:
- (void) handleOneTap:(UITapGestureRecognizer*)paramSender{
// *** Never gets called
NSUInteger touchCounter = 0; for (touchCounter = 0;
touchCounter < paramSender.numberOfTouchesRequired;
touchCounter++){
CGPoint touchPoint = [paramSender locationOfTouch:touchCounter
inView:paramSender.view];
NSLog(#"Touch #%lu: %#",
(unsigned long)touchCounter+1, NSStringFromCGPoint(touchPoint));
}
}
- (void)viewDidLoad {
[super viewDidLoad];
_container = [[UIView alloc] initWithFrame:CGRectMake(20, 50, 280, 300)];
[self.view addSubview:_container];
_container.backgroundColor = [UIColor redColor];
_container.opaque = YES;
// setup tap recognizer
self.tapGestureRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleOneTap:)];
self.tapGestureRecognizer.numberOfTouchesRequired = 1;
self.tapGestureRecognizer.numberOfTapsRequired = 1;
self.view.userInteractionEnabled = YES;
self.container.userInteractionEnabled = YES;
[self.view addGestureRecognizer:self.tapGestureRecognizer];
}
Any help will be appreciated.
If you want to add UIGestureRecognizer to your subview, you should do it like that:
_container = [[UIView alloc] initWithFrame:CGRectMake(20, 50, 280, 300)];
[self.view addSubview:_container];
_container.backgroundColor = [UIColor redColor];
_container.opaque = YES;
_container.userInteractionEnabled = YES;
self.tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleOneTap:)];
self.tapGestureRecognizer.numberOfTouchesRequired = 1;
self.tapGestureRecognizer.numberOfTapsRequired = 1;
self.view.userInteractionEnabled = YES;
[_container addGestureRecognizer:self.tapGestureRecognizer];
It looks like that problem is not in UITapGestureRecognizer, but in case how you add Subview from ViewController.
Right way to add subviewcontoller is:
SSubViewController *pvc = [SSubViewController controllerWithSubViewID:0];
[self.view addSubview:pvc.view];
[self addChildViewController:pvc];
Do it in your ViewController and it should solve your problem

Tap Gesture Not Firing

I am using the following code to attach gesture recognizers to a custom view. But for some reason I am not able to get the gestures to work.
for(NSString *option in _options) {
UIView *blind = [self createBlind:option];
blind.userInteractionEnabled = YES;
blind.tag = index;
[self addSubview:blind];
[self addGravityBehaviorToBlind:blind];
[self addCollisionBehaviorToBlind:blind];
[self addElasticityBehaviorToBlind:blind];
[self registerGestureRecognizer:blind];
_spacingY += 44;
index++;
}
}
-(void) registerGestureRecognizer:(UIView *) blind {
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(blindTapped:)];
[blind addGestureRecognizer:tapGestureRecognizer];
}
-(void) blindTapped:(UITapGestureRecognizer *) recognizer { <-- THIS NEVER GETS CALLED
NSLog(#"blindTapped");
}
For some reason the blindTapped method never gets called even if I tap on the blind view.
UPDATE:
Yes, I see the views on the screen. The views (blind) is a subview in another view. The parent view gets added to the controller.view. There is no place where I have disabled interaction.
Here is the createBlind method:
-(UIView *) createBlind:(NSString *) option {
UIView *blind = [[UIView alloc] initWithFrame:CGRectMake(0, _spacingY, 200, 44)];
blind.layer.borderWidth = 1.0f;
blind.layer.borderColor = [UIColor whiteColor].CGColor;
UILabel *optionTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, blind.bounds.size.width, blind.bounds.size.height)];
optionTitleLabel.text = option;
optionTitleLabel.font = [UIFont fontWithName:#"GillSans" size:17];
optionTitleLabel.textColor = [UIColor whiteColor];
optionTitleLabel.textAlignment = NSTextAlignmentCenter;
[blind addSubview:optionTitleLabel];
return blind;
}
I have removed all the gravity and UIKit methods but still I am not able to trigger the tap gesture.
SOLUTION:
When adding the custom view to my controller.view I was not setting the frame. Once the frame was setup everything worked.

KAL Calendar does not allow select any row for the list of events tableview

I used below code
- (void)viewDidLoad
{
EKEventStore * store = [[EKEventStore alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(dateSelected:) name:#"D" object:nil];
KalViewController *kal = [[KalViewController alloc] init];
kal.delegate = self;
kal.title= [NSString stringWithFormat:#"%#",kal.selectedDate];
[kal loadView];
EventKitDataSource * dataSource = [[EventKitDataSource alloc]init];
kal.dataSource = dataSource;
navController = [[UINavigationController alloc] initWithRootViewController:kal];
[self.customView addSubview:kal.view];
// when I add kal.view inside of my custom view then It displays the list of events and when I click on any row then It does not get pushed to next view screen
}
You have to make change two changes in KalView.m file..
First:In that class,there is an initwithFrame method in which you will get this below code.In that you can change color as per your requirement..
UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0.f, 0.f, frame.size.width, kHeaderHeight)] autorelease];
headerView.backgroundColor = [UIColor orangeColor];
[self addSubviewsToHeaderView:headerView];
[self addSubview:headerView];
Second :In the same class ,there is a one more method i.e addSubviewsToHeaderView:
In that method you will get this code
//Header background gradient
UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Kal.bundle/kal_grid_background.png"]];
CGRect imageFrame = headerView.frame;
imageFrame.origin = CGPointZero;
backgroundView.frame = imageFrame;
[headerView addSubview:backgroundView];
[backgroundView release];
Comment this whole code because this is setting image in HeaderView..

UITapGestureRecognizer EXC_BAD_ACCESS in self-contained UIView subclass

I've used UITapGestureRecognizer tons of times, but in this case I'm getting EXC_BAD_ACCESS when a tap occurs. I think it has to do with the fact that I'm adding it to an Alert-type overlay view. And for some reason the overlay view isn't getting retained even though it's on-screen.
I'm creating the view like this:
HelperView *testHelper = [HelperView helperWithBodyText:#"test text"];
[testHelper presentAtPoint:screenCenter];
The convenience method in HelperView.m looks like this:
+ (id)helperWithBodyText:(NSString*)text
{
return [[self alloc] initWithFrame:CGRectZero bodyText:text];
}
And the rest of the code looks like this:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.container = [[AGWindowView alloc] initAndAddToKeyWindow];
self.container.supportedInterfaceOrientations = UIInterfaceOrientationMaskLandscapeRight;
self.overlay = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
self.overlay.backgroundColor = [UIColor redColor];
self.overlay.alpha = 0.6;
[self.container addSubviewAndFillBounds:self.overlay]; //this fills the screen with a transparent red color, for testing
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissMe:)];
[self.overlay addGestureRecognizer:tap]; //I want to dismiss the whole view if the overlay is tapped
self.content = [[UIView alloc] initWithFrame:CGRectZero];
}
return self;
}
- (id)initWithFrame:(CGRect)frame bodyText:(NSString*)bodyText
{
self = [self initWithFrame:frame];
if (self) {
//TEST frame
self.content.frame = CGRectMake(0, 0, 217, 134);
// Initialization code
UIImage *bgImage = [[UIImage imageNamed:#"helper-bg"]
resizableImageWithCapInsets:UIEdgeInsetsMake(30, 28, 20, 20)];
UIImageView *bgImgView = [[UIImageView alloc] initWithImage:bgImage];
bgImgView.bounds = self.content.frame;
[self.content addSubview:bgImgView];
}
return self;
}
- (void)presentAtPoint:(CGPoint)loc
{
CGPoint newPoint = [self.container convertPoint:loc toView:self.container];
self.content.center = newPoint;
[self.container addSubview:self.content];
}
- (void)dismissMe:(UITapGestureRecognizer*)recognizer
{
//this never happens - I get EXC_BAD_ACCESS when I tap the overlay
}
HelperView is not the view getting displayed and it's not getting retained, but you're using as the target for the gesture recognizer. The AGWindowView property "container" is getting displayed and retained by its superview. Your code needs refactoring since you have this view HelperView that doesn't ever display anything itself, but if you want it to work like this you need to retain HelperView so it doesn't automatically get released. You can do this by assigning it to a strong instance variable.

UITableViewCell subviews issue

I load cell from xib. I added 3 vertical separators to the cell (tried to add from xib and from code). Everything is OK until I select the cell. When I select the sell, separators disappear.
Here are the images:
Not selected:
Selected
Code of adding separators:
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.topSeparator = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, 1)] autorelease];
[self addSubview:topSeparator];
self.bottomSeparator = [[[UIView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height - 1, self.bounds.size.width, 1)] autorelease];
[self addSubview:bottomSeparator];
// Initialization code
CGFloat xOffset = 314;
UIView *imageView1 = [[[UIView alloc] initWithFrame:CGRectMake(xOffset, 0, 1, self.bounds.size.height)] autorelease];
imageView1.tag = kTagBorder1;
imageView1.backgroundColor = [UIColor blackColor];
[self addSubview:imageView1];
xOffset = 487;
imageView1 = [[[UIView alloc] initWithFrame:CGRectMake(xOffset, 0, 1, self.bounds.size.height)] autorelease];
imageView1.tag = kTagBorder2;
imageView1.backgroundColor = [UIColor blackColor];
[self addSubview:imageView1];
xOffset = 573;
imageView1 = [[[UIView alloc] initWithFrame:CGRectMake(xOffset, 0, 1, self.bounds.size.height)] autorelease];
imageView1.tag = kTagBorder3;
imageView1.backgroundColor = [UIColor blackColor];
[self addSubview:imageView1];
}
return self;
}
I even tried this:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
[self bringSubviewToFront:[self viewWithTag:kTagBorder1]];
[self bringSubviewToFront:[self viewWithTag:kTagBorder2]];
[self bringSubviewToFront:[self viewWithTag:kTagBorder3]];
[self setNeedsDisplay];
// Configure the view for the selected state
}
You should not add the lines as a child view of self (UITableViewCell). Instead, add it as a child of self.contentView - which is the view containing the components inside a UITableViewCell.
This article contains tips on how to customize a UITableView properly.
I fixed it. I used UIImageView with black image instead of uiview with black background. In this case view doesn't disappear.

Resources