Scrollview of tweetdeck - objective-c

I am busy with an application and I want to implement a scrollview like the tweetdeck application.
You can zoom in en out UITableviews within an UIScrollview.
I was wondering how they did that. What I can imagine is that there are two UIScrollviews.
This because of the zoom in and out of one item in the UIScrollview.
What I don't understand is how the animation precise work and how they zoom out the UITableView.
I was wondering if someone can help me to get in the right direction

Actually a UITableView is a UIScrollView, so if you add some code like following, you will be able to zoom your table view.
self.tableView.maximumZoomScale = 2.0;
self.tableView.minimumZoomScale = 1.0;
And a UIScrollView delegate method
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.tableView;
}

Related

How to prevent certain object from scrolling in a UIScrollView

I don't know if this is possible and I highly doubt that it is but I'm wondering if there's a way where I can prevent a button for example from scrolling in a UIScrollView using Objective-C programming?
Sure. Simply update the button's origin as the scroll view scrolls.
In your view controller, implement the appropriate scroll view delegate method. If not done already, setup your view controller as the scroll view's delegate.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGPoint offset = scrollView.contentOffset;
CGRect frame = self.fixedButton.frame;
frame.origin.y = offset.y + 40;
self.fixedButton.frame = frame;
}
This will keep the self.fixedButton button 40 points below the top of the visible portion of the scroll view. Adjust as needed.
The above all assumes the button is a subview of the scroll view.
Of course it may be a lot easier if the button and the scroll view share a common parent view. Then the button isn't a subview of the scroll view and won't scroll at all.

Scrolling a UIScrollView in a UIScrollView

If I have a UIScrollView in a UIScrollview, but I only want the contained scrollview to recieve events and work when the parent scroll view Y Offset is 0.
How does one implement this?
Caveat I didn't mention, using self.ptViewController.collectionView.userInteractionEnabled = YES;
Does not help, as the events don't begin passing to the scrollview until the user has released their finger due presumably to the change in FirstResponder.
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView //Or – scrollViewDidScroll:
{
if (scrollView==scrollViewA && scrollViewA.contentOffset.y == 0)
{
scrollViewB.userInteractionEnabled = YES;
}
}
As far as I know, you cannot transfer the first responders between the different scrollviews so you would not have to take your finger off and on again.
However you can do something else:
Once you reach the y=0 point in your parent scrollview, you can then use the touchesMoved event to programatically scroll your contained scrollView.
Basically, you'd do a hit test to make sure the touch is in the contained scrollView, check if the container scrollView contentOffset y position is 0 and then scroll your container scrollView.
Something like:
- (void) touchesMoved: (NSSet *)touches withEvent:(UIEvent *)event
{
if (scrollViewContainer.contentOffset.y == 0)
{
if ([self hitTest:[[touches anyObject] locationInView:containedScrollView] withEvent:nil])
{
//programatically scroll your contained scrollView
}
}
}
This code is just a sample to better understand what I mean. You should adjust it to your own needs.
So, after trying the other suggestions, I found I wasn't able to replicate the fluidity needed to seamlessly scroll as if it were one table.
So long story short, a Scrollview in a scrollview, may be a bad idea if you don't want the user to take their finger off the screen while scrolling between the two.
Thus don't bother, use a UICollectionView and define precisely how each section/header/footer/row cell should be handled.
So what I did was simply add the necessary attribute changes in the Collection Flow Layout, to ensure that all sections and cells were being handled appropriately.
Due to the nature of what I was trying to achieve the flow layout required a lot of math and code to ensure all constraints were handled.

How to control nested scrollviews

In my iphone application I want to use 2 scrollviews and they have some images inside. Well, my question is when I scroll vertically on my first scrollview I want to explore the content of it however when I scroll horizontally I want to move to my second scrollview. I hope I explained clearly.
Well, I tried to use 3 scrollviews first of them located on the background, others are located on the first scrollview but I can only control the background scrollview or the others at once.
Is there a way to control first one horizontally and the others vertically.sorry for my english, hope it makes sense.
I have two recommendations.
1) Scrollviews can scroll horizontally and vertically - so you dont need two of them if you have content in a vertical direction and content in a horizontal direction. You can use one.
2) If for some reason you really do need 2, then you can detect a horizontal swipe by subclassing UIScrollView and switch to the other.
Remember that a UIScrollView will scroll in any direction that exceeds its contentSize. So all you need to do in the first case (1) is take the view that is inside say scrollview 2 (the horizontal scrollview) and put that view in the scroll view to the left or the right outside of the scrollviews viewport when the user scrolls they will see that view and can of course scroll vertically there as well.
If you use method 2 - make sure that the content size of scrollview one is at leat a few pixels more wide than the content size so that you can detect a horizontal swipe then invoke the coe to switch to your other scroll view. If you dont subclass UIScrollview to get the swipe you probably wont get the event. So do that add a little to the width of that view and then look for a value less than the left edge of the scroll view and switch to the other scroll view. You can do the same in reverse to go back to the previous scrollview.
I hope this helps - sorry no code at the moment, but I do have code working on iOS and OSX that does this.
You can distinguish both UIScrollView via if statement
Set delegate of both UIScrollView
Then compare your scrollView in its delegate method. You can change your delegate method according to your requirement -
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if(firstScrollView == scrollView)
{
//Do your work for firstScrollView
}
if(secondScrollView == scrollView)
{
//Do your work for secondScrollView
}
}
try to do in delegates methords
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
set some conditions like
if(myScroll1)
{
//scroll vatical.
}
if(myScroll2)
{
//scroll horizontal.
}
this is not complete code this is an idea Best of luck..

Touch on UISlider prevents scrolling of UIScrollView

I have a (vertical) UISlider inside a UIScrollview. I'd like to be able to change the value of the slider, and, without lifting my finger, scroll the scrollview left or right.
Desired behavior:
Touch down inside vertical UISlider, followed by a finger drag left or right causes the scrollview to scroll
Actual behavior:
Touch down inside vertical UISlider, followed by a finger drag left or right causes no movement in UIScrollview. A touch down outside the UISlider followed by a drag will scroll the scrollview as expected
UIView has a property called exclusiveTouch which seems as if it might be related to my problem. I tried setting it to NO, with no luck.
So, how can is set up my UISliders so that the scrollview beneath them will respond to touches which originate inside the UISliders?
Have you tried subclassing UIScrollView and implementing - (BOOL)touchesShouldCancelInContentView:(UIView *)view? According to the Apple documentation:
// called before scrolling begins if touches have already been delivered to a subview of the scroll view. if it returns NO the touches will continue to be delivered to the subview and scrolling will not occur
// not called if canCancelContentTouches is NO. default returns YES if view isn't a UIControl
If you simply return NO if the view is your UISlider, this may do what you want, assuming your UIScrollView only scrolls horizontally. If this doesn't work, you likely will have to do custom touch handling (ie. overriding touchesBegan:withEvent:, touchesChanged:withEvent:, etc.) for both your UIScrollView and your UISlider.
What you are seeing is the intended behavior.
Each touch event only gets handled by one control. What exclusiveTouch does is actually to prevent other touch events from being delivered to other views.
To do what are trying to do you would have to do some of the touch handling yourself. Passing the event to both your views. You could do either do it by implementing all the touchesBegan:, touchesMoved: etc. methods and pass the events to both views. You can read more about that approach in the UIResponder documentation. Another approach is to do the event handling in a UIGestureRecognizer on the scroll view that hit tests the slider and updates the value of the slider using the y-delta. You can read more about gesture recognizers and event handling in the section about Gesture Recognizers in the Event Handling Guide for iOS.
Side note:
Go to the Settings app and toggle a switch half way (for example the Airplane mode toggle) and then drag down. Nothing will happen. The rest of the OS behaves the same way. Are you sure that this is the interaction that you really want to do? Apps that behave differently often feel weird and unfamiliar.
Your question confused me a bit. You are saying a vertical slider - but dragging left and right?
If you wish to scroll the scrollview when dragging the UISlider, the proper way to do so is
[mySlider addTarget:self action:#selector(sliderMoved:) forControlEvents:UIControlEventValueChanged];
and
- (void) sliderMoved:(UISlider*) slider {
myScrollView.contentOffset.x = slider.value * (myScrollView.contentSize.width - myScrollView.bounds.size.width);
}
Hope this is what you want.
You need to set delaysContentTouches as NO and prevent for UISlider objects to scroll, Check below code.
mySlider.delaysContentTouches = NO;
- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view {
if ([view isKindOfClass:[UISlider class]])
{
UITouch *touchEvent = [[event allTouches] anyObject];
CGPoint locationEvent = [touchEvent locationInView:view];
CGRect thumbRect;
UISlider *mySlide = (UISlider*) view;
CGRect trackRect = [mySlide trackRectForBounds:mySlide.bounds];
thumbRect = [mySlide thumbRectForBounds:mySlide.bounds trackRect:trackRect value:mySlide.value];
if (CGRectContainsPoint(thumbRect, locationEvent))
return YES;
}
return NO;
}
I think you can get some reference from this example in this example it is shown that how to cancel any touch or any gesture recognizers and apply them to other views.
May this lead you to the solution of your problem and if it will just let me know about it
Happy Codding :)

Zoom multiple objects simultaneously in UIScrollView

I have a UIScrollview that contains multiple UIImageViews. I could zoom using the UIScrollView delegate but can only return one UIImageView at a time. I want to be able to zoom all objects inside the scrollview simultaneously when i try to zoom the uiscrollview. How can I achieve this?
This is what my delegate returns when zooming:
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)aScrollView {
return imageView;
}
Put your image views into one single UIView, which in turn is inside the UIScrollView. Then return your UIView as the view to zoom. Since the image views are inside it, they'll get zoomed as well.