I imagine this is pretty dead-simple, but somehow I haven’t been able to get it to work:
I need to display a View containing a group of controls (roughly 800px tall) -- which can be scrolled vertically by the user, as that view is too big to fit on the screen all at once.
That’s it.
I’d think that this might mean something like this:
UIView [normal size] > UIScrollView >
UIView [the oversized one]
... and then enabling vertical scrolling, etc.
But somehow I'm missing something, as the best I've gotten is the first screenful to appear on-screen, without the ability to scroll down.
~~~
[Note: I know that this might often be done using a Table view, and vertical scrolling then happens for ‘free’. But this is a series of special-purpose controls (an odd assortment of various UISliders, UISwitches, UILabels, UIButtons, etc.) that wouldn’t readily fit into a standard table view without a bunch of customizing anyway. They’re also static as well (i.e., don’t need to be changed programatically) -- hence they can be completely built in IB, and that’s how I’d much prefer to do it for this situation anyway. I just need to allow the whole lot to be accessible via scrolling.
I also know that they could be split up into multiple screens, and I'll do this if absolutely necessary; but they're a unified logical group, and so that's not the optimal choice in this instance.]
Any suggestions? That (and/or a code fragment) would be VERY much appreciated.
Many thanks in advance!
My initial thought is... have you tried:
[scrollView setContentSize:CGSizeMake( scrollWidth, scrollHeight)];
My secondary thought is the UIScrollView may not be receiving the scroll commands as you are really scrolling on a UIView, and not the UIScrollView directly... You might need to do some subClassing to get this operational, but I'm afraid that's a bit beyond me as I am still a beginner. :)
My tertiary thought is - why are you adding a UIView to the UIScrollView rather than adding the controls directly to the UIScrollView?
Related
I've decided that I don't want to ever use UIPickerView again... it's completely inflexible in terms of functionality, design, and size (height). It also occasionally gets stuck between rows, and the delay that occurs between letting go of a wheel and when the delegate method is fired indicating that a new row has been selected (because of the "settling in" animation) has caused lots of problems in the context of the apps I've been working on.
That being said, the user-friendly aspects of UIPickerView are good, and I'd like to try to replicate it. I've tried to research different ways that this might be done, but without much success. Does anyone have any ideas as to what would be involved to make something similar from scratch?
I was trying to get a UITableView subclass to behave in such a way that whatever cell was currently in the middle of the table (it would change while dragging, etc.) would change its background colour to something different implying that it was "selected". As soon as the table was dragged such that the "selected" cell was no longer in the middle, the cell would go back to normal and the new middle cell would change colour. So this would be like UIPickerView in a sense that you don't have to tap on a cell; instead you just drag to have one selected by default.
I figured it should have been easy enough to intercept the "touchesMoved" method of UITableView and add some code that looped through all currently viewable cells in the table, checking to see if their frames overlapped the center point of the table, and changing their appearance accordingly (plus sending a notification to other classes as needed to indicate the "selection" change). Unfortunately, I can't get this to work, as the "touchesMoved" method doesn't get called when I drag the table. Am I missing something obvious?
Any ideas or suggestions would be very much appreciated at this point... I made an app that relied heavily on UIPickerView objects, and because of the problems I've run into with them, I'll have to abandon it unless I can figure out a way to make this work.
Thanks very much,
Chris
Remember that a UITableView is a subclass of a UIScrollView, and the UITableViewDelegate gets all the UIScrollViewDelegate method calls too. scrollViewDidScroll: sounds like it would easily fit the bill for knowing when the table view was scrolled.
As for finding which row is in the middle of the view, just use indexPathForRowAtPoint:.
So I have a UITableViewController. The cells in this tableview have the following UIControls:
2 UILabels, one of which has a shadow and a clearColor background color.
1 Custom Progress view resized to be larger and with a different color
3 UIButtons
Functionally, they do exactly what they are supposed to do. However, I've noticed when looking at it on device that scrolling performance quickly tanks and has dropped frames all over the place, even with other interactions like pushing one of the buttons.
So I was reading around today and found http://blog.atebits.com/2008/12/fast-scrolling-in-tweetie-with-uitableview/ this article by the Tweetie guy about how to achieve fast scrolling performance by subclassing UITableViewCell and doing the drawing yourself.
The example works extremely well, but when I tried to adapt it to work with my desired configuration I realized that he isn't using any predefined UI Controls, he's mapping out everything by hand.
While I can see how this would be an extremely efficient way to do things, it strikes me as problematic for things like the progress view and the buttons, and even one of my labels to a certain extent.
So my question is this: Do I need to completely write my controls from scratch if I want my scrolling performance to be good, or is there a way to use the standard UI Controls and get good scrolling performance?
If you're adding custom controls to your cell, you should still be subclassing UITableViewCell, adding your controls in the init function, laying them out in layoutSubviews, etc. - just like any other view. As VdesmedT says, make sure you're re-using cells via the dequeue mechanism, so that you aren't allocating new cells with each scrolling operation.
OK, I will propose something obvious but to achieve UIScrollView performance, you need to be sure that the dequeue mechanism works well. I often see developers not properly set the identifier in IB and therefore missing the UITableViewCell cache benefit
I'm working on making a special UIScrollView to show a timeline of events, (Like a gantt chart if you're familiar with such things) and there could potentially be dozens of these events, some visible and some not at different times.
What I'm wondering is this: should I make an implementation similar to UITableView to remove the items that have scrolled out of sight, and reuse the views for other items as they come into the screen?
It seems like it could take some work, and I don't want to waste time on it if this isn't something that will affect performance on a small scale.
I'm getting the idea from the UIScrollView class reference:
"The object that manages the drawing of content displayed in a scroll view should tile the content’s subviews so that no view exceeds the size of the screen. As users scroll in the scroll view, this object should add and remove subviews as necessary."
Thanks for any help.
It depends on how much memory each item in the scrollview requires. You cant really tell unless you build it or provide more information about exact amounts and what each element in the UIScrollview contains. Removing items that are not visible is not a massive job but it can have some problems. I would first try it without removing them and optimise the elements that you add to the scrollview so they use as little memory as possible and then use instruments to check your mem usage. Then go from there. Hope that helps.
Please lead me in the right direction.
I need to provide user with small text centered on the iPhone screen. User can make quick scroll left or right in order to get the next or previous text. There can be hundreds of such text pieces. The process itself is similar to Photo application sidescrolling but much simple, no zoom.
As far as I can understand I need to use UIScrollView class, then call hundreds of addSubviews?
Is it the optimal way or I should always keep 3 subviews and replace them on the fly?
What kind of tricks should be used to achieve the "scroll and center" effect?
Thanks
You could use a UIScrollView with pagingEnabled = YES for the "scroll and center" effect, I guess.
Then only add the subviews that you're actually displaying, otherwise you'll run out of memory very quickly.
In the UIScrollViewDelegate, in -scrollViewDidScroll: you can get the current contentOffset and determine which subviews you need to add and which ones can be removed.
I have a problem, I can't solve properly.
In short: I want to create a single view (say: UIImageView) out of multiple subviews - i.e. it consists out of multiple ImageViews and TextViews. The thing is, I want to sort of 'render' them to be a single View.
Say, I take an image, add some description below, add a title above, and maybe another little image at the bottom. I want this whole thing to be a single UIImage to make it sort of 'listen' to one (e.g.) swiping gesture, which I cant tell to bring the new image to display.
Does anyone know the best way to achieve this? So far my results were fairly poor.
Any hints are welcome!
This is definitely possible. You seem to know about views and subviews, but should also read up on the "UIResponder" class and the "responder chain". The master view that you want to contain them all won't be a UIImageView, though, because that exists to just show an image. You can make all the ones you talk about subviews (addSubview: or in Interface Builder) of a plain UIView that you subclass yourself (say, MyContainerView), which then itself handles the gestures. If you want to take advantage of free scrolling on swipe, you could instead put your container view into a UIScrollView, which has its own set of semantics that you can leverage. For this latter, you should check out Apple's sample code for scroll views (don't have a link handy but should be easy to find) which embeds multiple image views in a scroll view.