I have one UIImageView (building's floor map) and UIScrollView with gesture recognisers which allow me to scroll horizontally and vertically, zoom in/out. Everything works OK, but the building has two floors, so user should have the option to switch between them. I decided to use segmented control at the top of the map to provide this option.
If I put Segmented Control to the same UIScrollView, it scrolls vertically as well as horizontally. What I am asking is how to fix horizontal position of the Segmented Control, so it will be able to scroll only vertically with map.
I am trying to use this code to test, if it fixes the position of Segmented Control absolutely, but it seems to be that it doesn't.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGRect frame = _floorSelector.frame;
frame.origin.y=50;
frame.origin.x= 160;
_floorSelector.frame = frame;
}
Where is the mistake? Thank you for replies!
I think the issue here is you are misunderstanding how scrolling is implemented in a UIScrollView, and how things are placed in its coordinate space.
When a UIScrollView is scrolled, the frames of its subviews are not changed. Relative to the scrollview, they remain in the same position while the contentOffset and bounds of the scroll view changes. In order to make a subview of a scroll view appear static while the rest of it scrolls, you must change its frame within the scrollview as the bounds change.
With that in mind, what you are doing now is just setting the same frame on that subview repeatedly, which is the same as not doing anything.
It sounds like what you want to do is something like this:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGRect frame = _floorSelector.frame;
frame.origin.x = 160 + scrollView.contentOffset.x;
_floorSelector.frame = frame;
}
Notice I do not change anything in the y axis because based on your question, the vertical scrolling doesn't need to be changed.
Related
I have a UIScrollView for which I have a UIView which is the subview of the scroll view , the UIView has a lot of other subviews and I am getting the height for it dynamically after adding the subviews , this is my piece of code to add the view to scroll view
CGRect frameOfView = CGRectMake(0, 0,Get_Bounds.width, globalYPosition);
self.parentProductDetailView = [[UIView alloc]initWithFrame:frameOfView];
I am first initialising the view this way and then after adding all subviews I am doing this,
frameOfView.size.height = globalYPosition;
[self.parentProductDetailView layoutSubviews];
self.parentProductDetailView.frame = frameOfView;
[self.productDetailScrollView addSubview:self.parentProductDetailView];
self.productDetailScrollView.contentSize = CGSizeMake(0, self.parentProductDetailView.frame.size.height *1);
But my scrollview does not scroll properly it either sticks to top or bottom.
Here globalYPosition is the sum of height of all subviews added to parentProductDetailView
The procedure you used seems correct. No matter the subviews your scroll view should scroll properly by simply using a larger content size then its frame size.
The scroll view may stick, snap to some points if paging is enabled which is what is happening in your case. If the content view is larger then 1.5th of the frame size then the scroll view will snap to top/bottom or left/right. If it is smaller then it will only snap to starting position.
This may be very useful for situations like having a side menu that takes a part of a screen but in your case you should simply disable the paging and scrolling should work fine.
I’m have a view that contains a regular UIView and a UIScrollView. The UIView sits above the UIScrollView offscreen. The UIScrollView typically occupies the entire screen. (It should be noted that I’m not using Autolayout). When the user scrolls to the top of the scrollview content I would like the UIView to start appearing on the screen. And when it reaches a certain threshold have the UIView snap into place and occupy the screen.
My initial thought was to use the UIScrollView delegate method, and adjust the superview.frame.orgin.y value when the scrollview contentOffset.y value is negative.
func scrollViewDidScroll(scrollView: UIScrollView) {
pullDownInProgress = scrollView.contentOffset.y <= 0.0
if pullDownInProgress {
self.view. = (-self.view.height / 2) - scrollView.contentOffset.y
}
}
However, this creates a stretching between the UIView and the UIScrollView due the scrollview bounce setting. If I turn off the bounce setting then the scrollview.contentOffset is never less then zero, therefore my superview frame is never adjusted.
Any suggestions on how to accomplish this?
You don't need to change the superview.frame, instead move the offscreen view down by its height so that it can appears and any bouncing effect for the scroll view might be hidden by that view.Or you can even move both the scroll view and the offscreen view with the height of the offscreen view. It really depends whether your offscreen view is transparent or not
I want to get the position of a UIButton inside a UIScrollView the problem is that i get the same position for when the UIButton is in it’s original position or if I scroll down…
I’m using NSLog to print the position and I get the same output
Without scroll down i get...
2014-11-05 19:28:02.564 ... {{260, 163}, {370, 225}}
Even if I scroll down I get the same output...
2014-11-05 19:28:06.052 ... {{260, 163}, {370, 225}}
This is the code i'm using to obtain the position of the UIButton inside the UIScrollView...
NSLog(#"%#", NSStringFromCGRect(CGRectMake(myButton.frame.origin.x, myButton.frame.origin.y, myScrollDown.frame.size.width, myScrollDown.frame.size.height)));
There is a way to get the actual position of the UIButton even after I scrolled down?
There is another way to get the position of the UIButton inside the ScrollView?
I’ve already visited the following links and I have not resolved it yet.
get UIButton inside an UIScrollView absolute screen location
iPhone - Get Position of UIView within entire UIWindow
Cocoa: What's the difference between the frame and the bounds?
Thanks for any help!
Maybe you can try this
NSLog(NSStringFromCGRect([self.view convertRect:myButton.frame fromView:myButton.superview]));
You're getting the position within the scrollview. Probably what you want is the position within the scrollview's superview (perhaps self.view, perhaps something else).
Your scroll view is going to have a contentOffset value. The frame of the subviews inside of the scroll view don't change when it scrolls. Instead, this contentOffset value is changed. I'm sure there are better ways to do this but on a basic level, you could just do something like so to get the frame in the scroll view's superview:
CGRect frame = myButton.frame;
frame.origin.x -= scrollView.contentOffset.x;
frame.origin.y -= scrollView.contentOffset.y;
NSLog(#"%#", NSStringFromCGRect(frame);
I have added 10 labels to to display 0 to 9 in UIScrollView, User can see only one label in UIScrollView visible part. User needs to scroll to see other labels. How to determine which label is currently visible in UIScrollView after scroll view decelerating.
Thanks in advance
Use the scroll view's contentOffset and calculate how many "pages" down they have scrolled by dividing the y offset by the content size height.
When scrolling is complete compare contentOffset value with labels positions or view to see which label is currently shown:
Use this method for getting scrolled position:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSLog(#"%f", scrollView.contentOffset.y);
//your logic to check shown label...
int currentVisiblePage = (scrollView.contentOffset.y / self.view.frame.size.height) + 1;
}
if you just want a single scrollable label, would be to use UITextView instead (reference). Disable editing, and you get a scrollable label.
(Taken almost verbatim from: how to add a scroll function to a UILabel)
For more detail:
UILabel inside of UIScrollView – programmatically
Sample code
AutoScrollLabel
my question is:
In my app I want realize somethings like this using UIScrollView
A UIScrollView whit all his contents inside. But when I reached the top of the screen (or maybe the bottom of the screen) I want to anchor some contents like in the AppStore (iOS 6).
In this case the "Detail", "Review" and "Related" buttons stop scrolling and remains fixed at the top.
Anyone have any idea how to do?
Give your scroll view a delegate if it doesn't already have one. This would probably be your view controller.
Also give the delegate a reference to the floating view. (In the example, the floating view contains the “Dettagli”, “Recensioni”, and “Correlati” buttons, and the floating view is transparent where the triangular notch is, and the shadow is also part of the floating view.) The floating view must be a subview of the scroll view.
Save the “normal” Y coordinate of the floating view's frame in an instance variable. For example, if the delegate is a view controller, you should probably do it in viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
originalFloatingViewY = floatingView.frame.origin.y;
}
In the delegate's scrollViewDidScroll: method, check whether the scroll view has been scrolled below the top of the “normal” position of the floating view. If so, move the floating view to the top edge of the visible area:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
[self updateFloatingViewFrame];
}
- (void)updateFloatingViewFrame {
CGPoint contentOffset = scrollView.contentOffset;
// The floating view should be at its original position or at top of
// the visible area, whichever is lower.
CGFloat y = MAX(contentOffset.y, originalFloatingViewY);
CGRect frame = floatingView.frame;
if (y != frame.origin.y) {
frame.origin.y = y;
floatingView.frame = frame;
}
}
You could also do it by subclassing UIScrollView and overriding layoutSubviews. Watch the “Advanced ScrollView Techniques” video from WWDC 2011 for more information on this technique.
You need to handle this in the UIScrollView's delegate method( scrollViewDidScroll:) for scrolling. When the y of scrollview reaches that particular value you need to disable scrolling in this direction alone. You just need to add an if condition there to check and reset the y point while scrolling. For this you might have to keep this particular portion as a separate scrollview outside the below content and move it along with the below scroll view's upward movement.