I am implementing a UIScrollView which behaves mostly like a UITableView, a bit more advanced with that.. but most of the API used are the same signature.. cellForRowAtIndexPath.. etc. First before people start storming why not just use a UITableView, let me just say that I can't. The reasons are fairly complex, but that is a decision been made.
The issue is now I am implementing infinite scrolling, basically when I scroll down and I am at 65% of the full contentHeight I am doing an async request to the backend to fetch more data and adding it to the data source and then calling reloadData. The issue is that if I am calling reloadData while the user is scrolling, it doesn't provide a very smooth scrolling experience. So what is the best way to tackle this? Also I noticed that reloadData basically refreshes the entire table view (in this case my scroll view). In my table view cell I am animating a UIImage to fade in. So when reloadData is called, the image that is already presented is being faded in again, which is kind of annoying.
How do I avoid such things?
Any tips and tricks?
In case you're still working on this, check out PSTCollectionView. It works exactly like UICollection view but supports backwards of iOS 4.3.
Its difficult to answer without knowing why you need to create a custom view similar to the tableview. If you have a developer account you might want to check the new iOS 6 view based on tableview. Not sure if I can talk more about it as it is under NDA.
For the UIImage fading, how about flagging each UIImage as displayed and then do a check when reloading the data or recalling the fade statement. Only fade the images that are not flagged as already presented?
In new iOS 6.0 there is new controllers call UIContainer view,its similar to UITableview but we can also set more then one column with that.
delegate methods for that controllers are almost same as in UITableview.you can use that controller if you have similar requirements.
Related
I'm trying to load a table view with cells that contain images downloaded off the internet. I'd like to only perform the download operation on cells that are currently visible instead of downloading every image as the user scrolls down quickly.
I found the indexPathsForVisibleRows method and that should fit my needs nicely but I need a way to figure out when the table view is no longer scrolling. My idea is to use the indexPathsForVisibleRows when the table view isn't scrolling so that all of the images currently on screen are loaded without unnecessarily loading images.
Are there any methods that I can override or notifications to subscribe to that will alert me when the table view is no longer scrolling?
Thanks!
Take a look at the methods listed here:
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIScrollViewDelegate_Protocol/Reference/UIScrollViewDelegate.html
If your view controller is the delegate of the UITableView, these will also be fired for it, as the UITableView is a subclass of UIScrollView.
Particularly, pay attention to: scrollViewDidEndDecelerating. This is the one I used to do pretty much what you're asking.
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 have a UIScrollView that I am using to simulate a UITableView like interaction because rows are a bit more complex than what UITableView has to offer. I have 4 UILables a UIImageView and a UIButton for every row. The end result is a lot of subviews.
Even with only 10 rows,the scroll view that looks fine in the simulator but has a fairly low frame rate on the iPhone 4. This is a resource consumption issue for sure.
Is there a way to optimize the redraw durring scrolling like double buffering?
If not is there another way to get customizable UITableview functionality?
thanks
Does every View have 4xUILabels, a UIImageView and a UIButton?
I would create a nib file with a custom UITableViewCell (You can make those as complex as you want), then you can reuse the cells to help with your performance.
Information on how to do this is here:
http://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7-SW1
I think you probably want to create a custom subclass of a UITableViewCell as the UITableView will handle all the redrawing for you. In a custom UITableViewCell you can add as many subviews as you like.
Take a look at http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html.
UITableViews are subclasses of UIScrollView (or at least conform to their behavior), but you really want to let the iPhone handle the selective drawing/cell reuse for you that the UITableView provides.
You should use UITableView if it does everything you need.
However if your tableview cells are really complicated, or you want to enable paging on the scrollview, you should take a look at the PageContol sample code that Apple provides. In a nutshell, you watch for movement in scrollViewDidScroll: and load new "pages" just before they become visible. This method works very well in practice for arbitrarily long lists of pages.
I'm new to iPhone development. I'm working on a table view (default UITableView subclass) that contains complicated custom cells, with multiple subviews and controls. Scrolling is not very smooth, but I'll just leave that for now.
The question is, when I'm scrolling the table view with quick swipes, the table sometimes suddenly stops scrolling and the scroll indicator will not disappear, and I have to swipe again to make it scroll.
If the table contains very few rows, say, 5 or 6, it never stuck. The custom cell class I used is from the example provided here: http://blog.atebits.com/2008/12/fast-scrolling-in-tweetie-with-uitableview/
Can anyone give a hint or solution to this problem? Thanks in advance.
Table cells are only created when needed, that is when they come into view and they are usually unloaded and released when they go out of view.
Put in an NSLog( #"Cell loading" ); in your cell creation code and check the console to see this happen as you scroll.
Are you using caching? The docs demonstrate how you can cache table cells to improve performance. What else are you doing when you're creating table cells? If there's any performance slow downs you should probably not have that happen while creating cells.
What I do is I generate all my content before the table loads and when cells are created all that content is simply placed into the view.
Any kind of drawing will drastically reduce performance especially if you're using transparency.
For posterity, and only valid if you are using Unity-iphone: this problem was driving me insane and I fixed it with the suggestion in this post:
http://forum.unity3d.com/threads/113815-quot-Sticky-quot-scrolling-in-UITableView-and-UIScrollView-when-interfacing-Unity-and-Obj-C
Changing the preprocessor flag to
#define USE_DISPLAY_LINK_IF_AVAILABLE 0
gave the issue a happy ending.
I'd take a look at your cellForRowAtIndexPath method - for a couple of possible problems.
If you aren't using the cell reuse that will slow things down a lot and if you are re-allocating or re-initializing your custom cells in the cellForRowAtIndexPath delegate method that can cause big performance issues.
If you post your code for that method we can give you some hints as to what might be causing it.