I added ICarousel to my IOS project and it worked fine. I could scroll pictures.
Then my view contain another data. So I needed to add a UISCrollView wich cover all my view. So, now, I have some elements (labels, textViews, and the UIVIew for ICarousel) in my ScrollView.
The ScrollView works fine. But now, the ICarousel doesn't switch pictures. Pictures are loaded (I see the first one and a part of the second one) but the carousel doesn't work anymore.
Did someone have the same problem? How to solve it?
Edit:
After #Wain advices, I tried this:
- (void)viewDidLoad
{
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(pan:)];
[self.view addGestureRecognizer:panRecognizer];
panRecognizer.delegate = self;
}
- (void)pan:(id)sender {
NSLog(#"Pan");
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
It doesn't work, but I checked with a breakpoint, it ran shouldRecognizeSimultaneouslyWithGestureRecognizer method when I tried a horizontal scroll.
Where am I wrong?
Looks like a clash between gesture recognisers because, by default, only one can be active at any one time.
Not sure why your scroll view covers everything, but you should be able to make your controller the delegate of the gestures and implement gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: to allow them to recognise concurrently.
UIScrollView has a panGestureRecognizer property that you can access to set yourself as the delegate.
iCarousel is a bit different as it doesn't make the gesture available publicly so if setting the delegate on the scroll view doesn't work you can edit the carousel (which sets itself as the delegate) to implement the delegate method.
Related
I have a UIImageView subclass and I need to have a pan gesture so I added the following code:
UIPanGestureRecognizer * panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(handlePan)];
[self addGestureRecognizer:panRecognizer];
but my handlePan selector never gets called.
Is there something else i need to do?
Thanks
If your object is UIImageView subclass, you have to enable user interaction. It is set to NO by default for UIImageView.
self.userInteractionEnabled = YES;
I had EXACTLY the same problem using the StoryBoard - I created a sub-view in my main view, dropped a Pan Gesture Recognizer on it, created an action and joined the pan to it, and it didn't work.
My sub-view had User Interaction Enabled on it and it didn't work. Frustrated, I deleted my Pan Gesture, added it back, everything seemed hooked up and it still didn't work.
Finally, I looked at the SUPERVIEW and its User Interaction Enabled was checked off. Checking it on and it worked.
So as a caveat, if it's not working, look at the parent views too!
I have a UIViewController and I am adding subviews to the main view. The main view has a UIGestureRecogniser and each subview also has a UIGestureRecognizer. In interface builder I have checked canceled in view in the attributes inspector so I would expect taps on the subviews to only fire my gestureRecognizerShouldBegin in the subview handler but they are also firing the handler attached to the view they are place on.
Does anyone have any idea why this might be the case?
I guess I could keep a handle to the particular instance of the GestureRecogniser attached to each subview and compare if the event being fired has come from the correct recogniser but this does not seem like the correct solution. Any help would be much appricated.
Edit: This second solution doesn't even work seems like every UIGestureRecogniser conforming to the current gesture is being fired!
Edit:
The best solution I have come up with is,
(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
if([view isEqual:[touch view]] && self.editing)
return YES;
return NO;
}
I would like the Gesture not to receive the touch at all though
Recently I had a problem. How to disable scrolling in a particular area of a UIScrollView, particularly the area occupied by a UIView or subview.
I've readen a lot about subclassing and other long approaches to solve this.
But recently I solved this problem in a simplier manner without subclassing:
UIPanGestureRecognizer *panrecognizer = [[UIPanGestureRecognizer alloc] init];
and then
[panrecognizer setCancelsTouchesinView:NO];
[mySubViewInScroll addGestureRecognizer:panrecognizer];
I created the UIPanGestureRecognizer without an Action passed to it and then added the recognizer to the view in the scroller. In such way the gestures on the view will be captured but expressly not handled by the view or by the superviews because we passed to the object no Action.
The question is this. Is this a correct approach to handle this type of prolem or it's better to do otherwise. I mean Apple will accept this kind of application with this approach ?
In effect I think that this, even if not the best is the most practical solution..since messing around with the classes and subclassing to achieve only a partial scroll lock of the screen seems to be very odd. So let-s see if Apple will accept this kind of solution...
try rewrite ScrollView's
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
to return chi
I have a UIWebView that is drawn programmatically and gets allocated and displayed through multiple subviews (the webview gets added to the superview).
This all works, however I have one little problem:
If 2 different subviews display this webview then I get 2 webviews, so when 1 view dismisses the webview the other remains. I don't want this.
Originally I was thinking just implement the webview in the superview class, however it didn't work.
How can I have the web view check to see if there are more then one of itself?
A webview instance can only be added to the view hierarchy once. If you have two webviews visible on screen at once, they are two different instances. You should keep track of these instances that you add to the hierarchy and when one dismisses, remove all the instances you are tracking from their superview.
You can also crawl a view hierarchy and look for instances of UIWebView.
for (UIView *subView in [myView subviews]) {
if ([subView isKindOfClass:[UIWebView class]]) {
[subView removeFromSuperview];
}
}
mhm, no, wait, it's not so clear what you are meaning...
You say: "...there are more then one of itself" and "...gets allocated and displayed through multiple subviews"
You probably mean that you have 2 instances of "the same" UIWebView class, but then you should not consider them as "the same object" which lives in 2 different superviews... they are different objects, everyone has its own properties...
Or did i misunderstood?
So, if you meant as i said and you just want to control from a subView (mhm... or we should say from its UIViewController) if there are other views which use a UIWebView.
I'd probably use one UIViewController "parent" where to load my subViews (eventually they could also have their own UIViewController, then every time i Alloc and addSubview a UIWebView in my subView i just add a tag to it:
myWebView.tag = 11;
it could change if needed for next one...
the purpose is to be able to control if in my UIView there are allocated some UIWebView,
now we can do that with this in my main parent UIViewController:
for (UIView *view_level_1 in [self.view subviews]) {
for (UIView *view_level_2 in [view_level_1 subviews]) {
if (view_level_1 >= 10) {
// do something: dismiss this UIWebView too...
}
}
}
it just control in all the subViews of the view of my mainViewControl if there is a subView "tagged" before (a tag is a sort of "name/id")
I'm not sure the structure of your subView could be like that, it was not so clear in your question, but you can change the code adopting it...
luca
Use UIView's isDescendantOfView method to know if any subView is currently present on parentView.
if([addedSubView isDescendantOfView:parentView])
{
//addedSubView is subview of parentView
//Take necessary action.
}
else
{
//addedSubView is not subview of parentView
//Take necessary action.
}
I have added several UIScrollViews as subviews of a single UIView and set the frames so that each one is clearly visable. I set scrollEnabled to YES and set the contentSize larger than the bounds/frame. I do this in a for loop, and with each pass of the loop I release the UIScrollView (though the object is still stored because it has been subviewed into the UIView). This works well for being able to scroll around the imageView stored in each particular UIScrollView but I cannot for the life of me figure out how to get the zoom to work. I included the in the interface. Here are the methods I have tried for choosing the correct view for zooming:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return [[myView subviews] objectAtIndex:pageNum];
}
and
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return [myView viewWithTag:pageNum];
}
neither seems to work. The weird part is that scrolling works fine. I can't even get the viewForZooming method to get called at all if I put in an NSLog call. Any ideas? I think I've lost all my hair from getting frustrated with this.
Edit: Thanks a lot cduhn! All I needed was that little bump, I had forgotten to set the scrollView delegate to self... I've been working with various apps that take advantage of UIScrollView for months now and been using the delegate correctly and this most recent one I don't know where my brain went.
However, you do not need to override the scrollViewDidEndZooming:withView:atScale:, the delegate will call that no matter what after a zoom.
Also, after a little tweeking this worked:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return [[[myView viewWithTag:pageNum] subviews] objectAtIndex:0];
}
This simply calls the scrollView inside View container and then gets the UIImage inside of that... works well.
It sounds like you may not have set the delegate property on your UIScrollViews to point at the object that implements viewForZoomingInScrollView:
Also note this snippet from the UIScrollView Class Reference:
For zooming and panning to work, the delegate must implement both viewForZoomingInScrollView: and scrollViewDidEndZooming:withView:atScale:; in addition, the maximum (maximumZoomScale) and minimum ( minimumZoomScale) zoom scale must be different.
Finally, a word of warning: Be careful when accessing the subviews of UIScrollView. Your subviews are not alone in there. UIScrollView adds its own UIImageViews as subviews of itself to implement its scrollbar UI. So code like this...
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return [[myView subviews] objectAtIndex:pageNum];
}
... may not do what you expect.