I'm basically trying to achieve the following scrollable layout and am looking for some suggestions as to the best way to achieve it...
Potential solutions might be...
Nesting UITableViews
I have considered having all of the 'A' componenets part of a single row in a parent UITableView with rows A1, A2 & A3 in a child UITableView but I'm not sure if this is possible?
Spanning Rows
I am also unsure if its possible to have a single UITableView but have areas within span multiple rows (like you can do in a HTML table for example). Then area A, B, C etc can just be views that span their respective rows.
Any suggestions appreciated.
This is totally doable, but I would strongly suggest not nesting UITableViews or UIScrollViews, this could lead to some pretty major performance issues when scrolling (UITableViews are not automatically reused) and will certainly be a messy, possibly buggy solution.
The best way to go with this is to create Custom UITableViewCells that draw themselves based on the data they are given. They can then draw out to look like the cells you described above, giving the appearance of multiple cells, although each section is in fact a single cell.
By setting cell selection style to NONE and listening for touch events on the cell, you can even make the seperate "subcells" selectable.
This is some pretty complicated drawing, so I'd recomend looking at how others do it.
http://blog.atebits.com/2008/12/fast-scrolling-in-tweetie-with-uitableview/
http://cocoawithlove.com/2010/12/uitableview-construction-drawing-and.html/
This is how I handle it:
https://github.com/andrewzimmer906/XCell
Thanks for all the replies, I've up-voted them because they were helpful however I haven't accepted them as the answer since I actually implemented a completely different solution to those suggested using a combination of a UIScrollView underneath a UITableView as below. Note there's no nesting or spanning going on.
The UITableView's delegate is set to be the UIViewController. The UIScrollView's delegate is NOT set.
When the user scrolls the UITableView its scrollViewDidScroll method is fired and I am able to scroll the UIScrollView the same amount manually in code as follows...
- (void)scrollViewDidScroll:(UIScrollView *)tableView
{
[self.scrollView setContentOffset:tableView.contentOffset animated:YES];
}
I have to be a bit clever to calculate (in code) when the page loads the position of the elements in A, B, C etc and the exact height of the scroll view so it matches the UITableView.
Since I am using a standard UITableView for A1, A2, B2, C3 etc I am able to easily control the action when the user selects a row and still get the standard UITableView highlighting for free.
Drawbacks
Swiping/scrolling on the UIScrollView has no effect you have to scroll on the UITableView. I might be able to overcome this by implementing a delegate on the UIScrollView and reacting to its own scrollViewDidScroll method to scroll the UITableView but I've yet to try this and I expect they'll be problems since both methods would be firing at the same time.
Touching/tapping the UIScrollView has no effect. This is fine for my needs however if I wanted to perform some action I could use a UITapGestureRecognizer which I've done before. E.g.
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapGestureCaptured:)];
[self.scrollView addGestureRecognizer:tapRecognizer];
- (void)tapGestureCaptured:(UITapGestureRecognizer *)touch
{
CGPoint touchPoint=[touch locationInView:scrollView];
// Perform action here.
}
Hopefully this helps someone. Thanks again.
The GUI above can definitely be achieved but practically i have never seen that in any application. Anyways you can try following if you aren't done yet.
best option would be to load one table initially with data A,B,C,D. and then when user selects any of the row say A for example then reload the table and put A in section header and A1 A2 etc. in data. You have to write lot of code to handle status of table in this case but it will look good.
You can customize UITableViewCell and arrange UIView inside it to achieve your pattern. All you have to know is how what would be the resulting height of ROW. It can be set in delegate method heightForRowAtIndexPath.
If you want spanned rows(rows with A1,B1 etc.)to scroll that you can achieve it by arranging Tables inside scroll view OR Scrollview inside scroll view.
Related
I need to create a screen that scrolls vertically - like the tableview but I need 3 columns and within those 3 columns I need to add images of varying height - so this will not fit into rows that a tableview can provide.
Should I create 3 tableviews and lay them out side by side - or something else. I think I could build this by simply positioning the images using coordinates but I wanted to benefit from methods that the table view can provide.
If you want the columns to act stuck together, so that they all scroll simultaneously, then I think best approach is to use UIScrollView with the images added in the correct placed "by hand." UITableView and friends is not built to handle non-lined up columns.
added If you do use a UIScrollView, and you have a large number of images you want to display (that is, the user can scroll for a long time), then it would be wise to recycle your UIImageView objects that are scrolled off the screen. This is what UITableView does with UITableViewCell objects, and that's why UITableView wins. You can win, too, if you code carefully.
Three table views would work, but in order to keep things neat and from the same datasource, I would consider using a subclassed UIPickerView and the UIPickerViewDelegate/UIPickerViewDataSource.
Particularly necessary methods:
// UIPickerViewDataSource
– numberOfComponentsInPickerView:
– pickerView:numberOfRowsInComponent:
// UIPickerViewDelegate
– pickerView:rowHeightForComponent:
- pickerView:viewForRow:forComponent:reusingView:
According to my opinion You should have to take three UITableView in xib file and take its IBOutlet then give each UITableView an unique tag and then implement UITableView's Delegate methods and in that Methods Check for Tag and then assign values.
Along With this, the other solution, you can also use UIPickerView and then implement UIPickerView's delegate methods also..
Happy Coding !!!
I need a "PickerView", that behaves like a normal UIPickerView, but only shows one row of data and has a custom design.
Something like you see in the image, showing the transition from subview 1 to subview 2. After the user lifts his finger and after the scrolling stops, only one subview will be shown:
IMAGE
So basically a scrollview which:
is endless in both, positive and negative directions by showing the same entries over and over
uses paging across several subviews
only shows one subview when not scrolling, and no more than two subviews when scrolling.
I can get a endless scrollview to work, but not with paging enabled. Paging will always limit my scrolling to the next subview.
So I'm thinking about creating my own UIView subclass which custom scrolling behaviour to mimic a UIPickerView. But before doing so, I wanted to get some opinions about the idea in general. Is creating a custom UIView the right way to go? Anyone has some experience with the expected performace? (There will be timers to handle the scrolling algorithm, which has to be recreated of course... :)
Another approach would be to subclass UIScrolView and implement the paging myself. I know when the scrollView starts decelerating
, so maybe there is a way to overwrite the contentOffset to have it scroll into the right position...?!
Any help is appreciated! Thanks!
Here is a great custom component, which seems to be able to do everything you need:
http://dev.doukasd.com/2011/04/infinite-scrolling-dial-control-for-ios/
It's not endless, but rather a modified UITableView with a huge number of cells.
Would it be feasible to just use a UIPickerView, but clipped to the middle row? You could turn off showsSelectionIndicator to remove the overlay and have the delegate pass back custom row views.
I am trying to create a excel like view in my app. To do that I wanted to achieve both horizontal n vertical swipes at the same time .i.e., if the vertical scroll would fill with rows and the horizontal with columns.. have no clue hw to begin with.
This is an interesting question. For sure I would say start with UIScrollView, and set the content size bigger than the screen size, exactly how big is up to you.
Next you'll want to make some kind of implementation that efficiently figures out what cells are on screen. If I were you I would do something similar to how UITableView is done, i.e. make a custom object that keeps track of what indexes should be on screen based on the offset of the scroll view.
Next you'll need this custom object to either directly or indirectly get the visible cells to display themselves on screen when they are visible, and remove them from the superview when they aren't. I'd also recommend reusing the views that are offscreen.
This is a moderately challenging thing you are trying to make, so be sure you are very organized and don't be scared to make a few new custom object to perform specific tasks.
Sample interface file:
#protocol doubleTableViewDelegate
-(NSInteger)heightForRow:(NSInteger)row;
-(NSInteger)widthForCol:(NSInteger)col;
-(NSInteger)numberOfRows:(NSInteger)rows;
-(NSInteger)numberOfCols:(NSInteger)cols;
-(UIView *)cellForRow:(NSInteger)row col:(NSInteger)col; //get the custom table view to store and dequeue these, i.e. store them in an NSSet when they go offscreen, and give them back when a certain function is called.
//There's probably a few functions missing here still.
#end
#interface doubleTableView: UIScrollView {
id<doubleTableViewDelegate> infoDelegate;
}
//your functions to show and remove cells as needed
#end
You'll need to work out the rest, but keep updating this page and I'll try to help out.
Good luck with this, let me know how it goes.
i i want to activate scrolling vertically through programming for 2 UITableview at sametime?(one table view length 160,another one has 160).is it possible ?In one Viewcontroller's view i have scrollview, on that i have two tableviews(instead of one,like two column)..how can i scroll vertically both at same time?any help please?
If you want to implement 2 separated and round-rected columns then it might make some sense.
In any other case just use one UITableView and separate each cell visually (the left half will display the data for the first column and the right - for the second).
If you still want to have 2 separate table views and have them both scrolled simultaneously then get rid of the containing scroll view and implement the UIScrollViewDelegate as was already suggested.
Something like this:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
self.leftTableView.contentOffset = scrollView.contentOffset;
self.rightTableView.contentOffset = scrollView.contentOffset;
}
I think that this code should do the magic...
Don't forget to set the view controller to be the delegate of both table views.
I don't really get it but a table View on top of a scroll View will create problems. Because, when users scroll, both of the views will try to get the interaction of the user, and they can take turn to get that interaction randomly.
Can you post a picture, or clearer description of what you want?
If your next question is "how do I make the scroll views stay at the same offset?" -- i.e. you want them to sync vertically -- than I would advise that you abandon the idea of using two UITableViews.
Instead, define a two-column UITableViewCell, which can easily be done with Interface Builder, and use that to give the appearance of two columns.
I think that doing away with neither UITableView’s userInteractionEnabled set to YES, and implementing your own touchesMoved:withEvent: method (maybe also try UIGestureRecognizers) would prove fruitful.
I am guessing that these UITableViews are not used to show plain tabular data but images or other content, and have a different interaction paradigm (e.g., when the two fingers slide separately the two table views scroll in separate velocity & direction). If that is the case you might ultimately want to use custom controls.
But if you just want a 2-column UITableView then as Jonathan said, simply use a two-column cell.
I've started implementing a UIScrollView that will contain many thumbnail-sized pictures and will scroll only horizontally. For this, I keep a limited number of UIImageViews created and remove/add them to the UIScrollView as the user scrolls it.
The problem is I need to find a way to optimize it as scrolling sometimes gets sluggish. Maybe it's the adding/removing from the view, I don't know.
I figure this is a common component that might have been implemented more than once, but I couldn't find any library that featured something like this. If there is something ready available, I wouldn't need to spend many hours fine tuning or figuring out how to improve my component.
This is different from the question that has been asked here many times: I don't want it to behave like the photos app. I want many pictures to be visible at a time and to scroll them smoothly, without "hard pages".
So, anyone know of a component which does something similar to this?
I managed to do something similar by using a rotated UITableView instead:
UITableView *tableView = [[UITableView alloc] initWithFrame:...];
tableView.transform = CGAffineTransformMakeRotation( -M_PI/2 );
You can then configure your UITableViewCells to display the images. You can also rotate the UITableViewCell contentsView.
I made a two dimensional scrolling component called DTGridView. You can use it with just the one row to make a purely horizontal scroll view. It has an API much like UITableView, where you have a dataSource and a delegate to tell it how many rows/columns etc and to handle touch events for the cells.
It also uses a method of cell reuse like UITableView does to save on memory. If you aren't using cell reuse on table views, you should be. :)