How can I draw in the "bounce" area of a UIScrollView? - iphone

I have a custom-drawn view that I include in a UIScrollView that scrolls horizontally. The view draws a background with lines extending horizontally, and some different background colors. When I scroll to the far left such that the scroll view "bounces", I see gray background color. What I would like to do is to draw additional background lines and colors into that area, so that it looks like the view goes on forever, but I can't quite figure out how to do this. I've tried setting clipsToBounds to NO for all the views, and drawing in an area outside the view, but this doesn't seem to work. How can I draw in this area?

I found the solution to this, at least in my case. I simply increased the size of the scroll view with an extra margin, then positioned the scroll view partly off the screen.
CGFloat scrollViewHeight = 300;
CGFloat preferredWidthOfContent = 500;
CGFloat gutterMargin = self.bounds.size.width / 2;
scrollView.frame = CGRectMake(-1 * gutterMargin, 0, self.bounds.size.width, scrollViewHeight)
scrollView.contentSize = CGSizeMake(preferredWidthOfContent + 2 * gutterMargin, scrollViewHeight);
contentView.frame = CGRectMake(0, 0, preferredWidthOfContent + 2 * gutterMargin, scrollViewHeight);
The content view has to know about the gutter margin width, and then draws the actual content in the correct place based on that. When the scrollView is "bounced", then the remainder of the content view is actually displayed.
This trick works because the scrollview is extending off the screen. If you wanted to use the same trick with a scrollview that did not touch the edges of the screen, you would have to simply place another view over the top of the scrollview to hide the extra space.

If you're drawing your lines in drawRect: method, there's no way to draw them outside of the view bounds. The property clipsToBounds only affects subviews, so, in theory, you could add a subview to your main view (the one displaying the content) with a frame that extends to the right of your view and draw the lines in that subview.
Another option is to add a subview to the scroll view and place it to the right of your main view. Then draw the lines in this subview. The scroll view will still bounce since it doesn't care whether there are still partially visible views in it, it only looks at the contentSize property to decide when to stop scrolling.
If neither option is suitable, describe in more detail what kind of lines you're drawing and what kind of appearance you would like to achieve.

Related

UITableView contentInset makes table view scroll horizontally in addition to vertically

I'm creating a UITableViewController in code and pushing it on top of the navigation stack.
It's table view is intended to just show a simple list of text items.
I need to add some contentInset to my table view which I add in the init method of my UITableViewController
self.tableView.contentInset = UIEdgeInsetsMake(7.0f, 5.0f, 7.0f, 5.0f);
However, when I load the table view it seems the left and right contentInset have actually stretched the width of my table view by 10. I'm now seeing a small horizontal scrollable area. I don't want any sort of horizontal scrolling on my table view. If I remove the contentInset code, my table view behaves plainly i.e. simply provides for vertical scrolling. How I can keep just like that but with my contentInset in place? I tried reducing my contentSize.width by 10 in viewWillAppear, it had no effect.
This seems to be a duplicate but with no acceptable answer: UITableView ContentInsets scrolling content horizontally
In the mock I have marked the desired contentInset with dashed line ---
Thanks.
I ended up setting just the top and bottom insets. To achieve the left and right inset look and feel, I created custom cell as wide as the screen. But the actual cell content was restricted to a slightly narrower subview within the custom cell. Thus, there was space leftover on the left and right of the subview.
Looks like you need to do 2 things:
Add the table view to a container view and make the table view frame thinner (to add the left and right borders).
Add thecontentInset only for the top and bottom.
Maybe you should set the bounces property of the scrollView to YES.
And do not set the contentInset.
Another way that could work, is that, instead of setting the tableView frame, you can set the frame for cell's contentView , something like this,
- (void) layoutSubviews
{
[super layoutSubviews];
CGRect frame = self.contentView.frame;
frame.size.width = frame.size.width * 0.9; //90% of total width
frame.origin.x = self.center.x - (frame.size.width/2); //center the contentView
self.contentView.frame = frame;
}
The using the above, u can add any left or right or left padding u need for the cell. and all the subViews will be added to the contentView , hence no problems there.
happy coding..!

IOS UIScrollView: Cannot scroll until the end of the content

I am trying to generate a scroll controller in a window with the UIScrollView class, which will contain numerous UIButtons, placed vertically. I set the size of the scroll view equal to the current view controller's root view, so that the scroll view covers the entire visible window. Then I generate the UIButtons I am going to add to the scroll view: I add each UIButton just in the below of the previous UIButton and I add the height of the current UIButton to a variable called "totalContentHeight". Finally, I set the height of the contentSize of the scroll view to this value, in the following line of code:
self.scrollViewForNewsButtons.contentSize = CGSizeMake(self.view.frame.size.width, totalContentHeight);
totalContentHeight is equal to numOfButtons*eachButtonsHeight after I add all the buttons to the scroll view.
The problem is, in the simulator, when I run the app and scroll until the end of the last button and release the mouse, the last two buttons bounces back such that they lie outside of the visible window. It is somewhat hard to express with mere words, so here are the images:
1)This is what I get when I scrolled until the end of the content and held the content at the last possible position it could be pushed:
2)This is what I get after I released the mouse and the scroll view bounced back to its final position:
As you can see, the last two buttons are drawn outside of the visible area. It is like the scroll view's area covers the whole window plus the button area of the IPhone. I could not find a reasonable explanation for this. Am I setting the area size wrong or am I missing something else?
just set content size with calculation with your total button and its height...For Ex..
float yheight = totalButton * yourButtonHeight;
[yourScrollView setContentSize:CGSizeMake(320, yheight + 44)];
try this code...
And if you set the scrollview frame size the same as
self.view.bounds

iPhone UIScrollView how to properly zoom the view? Currently it's height is not adjusted properly

I have a UITableView within a UIScrollView. It took me quite a lot of work to make it work.
The tableView is 640x350, I use the scroll view to scroll from one end of the cell to the next.
The scroll view is 320x350.
The scroll view's content size is 640x350
I'm running into this problem:
if I set scrollView's minimum zoom scale to 0.5, the tableview's width now fills the screen, but it's height is only half the screen. I would like the tableview to show more rows when I zoom out to 0.5.
First of all I would like to understand if this is the correct behavior, or the result of my tableView's content size and frame manipulations. The tableview has all springs and struts set in interface builder and should fill the frame available. This is my first attempt at zooming in months, and I don't remember how it works with zooming.
Can someone help me understand where and what do I need to adjust?
As far as I understand, I need to put the code into scrollViewDidZoom: that will manipulate the tableView's frame and content size.
PS. I"m returning the tableview from the viewForZooming: method of UIScrollView
What you are trying to achieve is pretty hard.
Solution 1 This solution uses the exact setup you have (UITableView inside UIScrollView).
You say that when you set the zoomScale to 0.5, you want your table view to fill the scrollView vertically. At 0.5, your table view must be 640x700 in order to fill the UIScrollView as you wish. For this to happen, on scrollViewDidZoom: you must resize the frame of the table view to 640x700
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
// No matter what the zoomScale is, the tableView will be zoomed accordingly
// Only zoom the height of the table
tableView.frame = CGRectMake(0, 0, 640, 350 / zoomScale);
// Also, update the contentSize
scrollView.contentSize = CGSizeMake(640, 350 / zoomScale);
}
If you run the code above for zoomScale = 0.5 you will get a frame size of 640x700.
This only changes the frame of the table and doesn't change the heights of the cells. This means that as you zoom out, you will also see more cells in the tableview.
Solution 2 Use only UITableView
UITableView is a subclass of UIScrollView. This means it has the ability to zoom and scroll around.
Start with a UITableView with the size that you want on the screen. Then, after the content is loaded modify the contentSize and make it wider than your frame width. This should enable horizontal scrolling.
However, UITableViewCells have their frame set automatically to the width of the tableview frame. You can bypass this by using a custom UITableViewCell, with clipsToBounds=false. Inside it you will insert a UIView with the frame set to the width&height you desire and with no autoresizingMask. When the tableview will resize UITableViewCell frame, this will not affect your inner UIView.

iPhone how to implement a "Wide" UITableViewCell?

I'd like to have a UITableView with cells wider than 320 points. The user should be able to scroll sideways to be able to view different parts of a UITableViewCell. Is this kind of behavior possible with a UITableView, or should I go and try to implement a tiling UIScrollView?
I tried wrapping a UITableView within a UIScrollView, and the results are terrible - they compete for the scroll gestures and most of the time the scroll view wins, preventing the table from being traversed vertically.
Any input is appreciated!
Thank you!
Update: I tried the proposed solution and it scrolls properly, but the tableview is still only 320 pixels wide. Is tableView's width linked to the window bounds ?
Wrapping the table view with the scroll view is the right way.
UIScrollView with
Show horizontal scrollers
scrolling enabled
autosize to full screen
Inside that, a UITableView
shows vertical scrollers
scrolling enabled
Then I set the table view's frame, with w, being the calculated width of the table view with all columns, whatever your width, and kTableScrollViewHeight being the fixed height of both the table view and the scroll view, in my case, for example 367 points (screen minus status, navbar and tabbar):
tv.frame = CGRectMake(0, 0, w, kTableScrollViewHeight);
and the scroll view's content size
scrollView.contentSize = CGSizeMake(w, kTableScrollViewHeight);
If you want the scroll-to-top behavior when the user taps the status bar, you might want to set
scrollView.scrollsToTop = NO;
because otherwise the scroll view will take away the tap from the table view.

Scaling a sub classed UIView

I have created a subclass of UIView and am trying to scale and move the view from within its m file but am running into some problems. When I used the command:
self.frame = CGRectMake(self.frame.origin.x-10,self.frame.origin.y-10,self.frame.size.width/2,self.frame.size.height/2); the object moves location but does not resize (the view only contains a few UIImageViews). In the xib file of the sub class I have the options checked to Clip Subviews and to Autoresize Subviews but neither appears to happen. Any ideas as to why the view will not resize with this command and how I could get it to resize.
Resizing your view is not the same as scaling it. Think of your view as a picture frame. What you're doing above is moving the frame, and also moving the lower right corner (you're shortening the frame's wood bars) - but that does not automatically shrink the picture.
There are four ways of resizing a view with subviews:
Let the superview clips its subviews (by setting view.clipsToBounds = YES): Subviews do not resize or relayout, but only show in the area that is inside the frame.
Let the superview not clip its subviews (by setting view.clipsToBounds = NO): Changing superview size does not have any visual effect on subviews, they also show outside of the frame.
Give the subviews autoresizingMasks: The subviews do not change size, but they relayout according to their autoresizing mask (for instance, a subview may always stay 10 px off the lower right corner of the frame, or may always span exactly the width of the frame.) Note that this does not necessarily automatically scale subview content. Set subview.contentMode accordingly.
Scale the superview: By setting superview.transform = CGAffineTransformScale(superview.transform, 0.5, 0.5), you shrink the superview and all its subviews (you essentially zoom out). Note that this makes superview.frame undefined, which means you shouldn't use that anymore. It can also make things a bit blurry.
You could also "manually" change all the subviews, but that kind of defeats the purpose of having a nice view hierarchy.
As MishieMoo said, temporarily set the backgroundColor of your superview to something visible. This will very likely show you that your view is indeed changing.