do anyone have experience with UITableView inside a custom UITableViewCell ?
I had a try and the UITableView in the UITableViewCell looks like that can't respond to user inputs (i.e scrolling).
Before going any further I would like to know if I am wasting my time !
Does anyone have seen something like that around ? Any reference would be helpful.
Thanks
I haven't done this, but I discourage this. This could cause odd things to happen.
In a similar vein, Apple says not to use UIWebView inside of a UIScrollView. The reason is because a web view is a subclass of the scroll view. Nesting them can cause unexpected behaviors. Note that the table view is also a subclass of the scroll view. While Apple doesn't explicitly mention your case, I assume that it is the same idea.
If yo must, subclass UITableViewCell and see what happens. It's not that difficult. Make the cell implement the UITableViewDelegate protocol.
Since the parent TableView responds to the vertical swipe gesture, your child TableView is not going to ever see it. Where should the swipe gesture "go"? It has to go one place or the other, so one of the TableViews will always not behave "correctly". I do think that trying to put a TableView inside a TableViewCell and getting it to work just like a root TableView is probably a waste of time.
Related
I'm trying to make a custom table view. I have a UIScrollView loaded up with UIViews. I would like to recreate the reusable cell functionality that a tableview has. And I'm wondering what might be a good way to do this.
I was thinking that when the UIViews are scrolled off screen I'll remove them from the Subview, and when I need another I'll just add it. However I'm not sure what method might be the best to do this in.
I could check to see the views location in scrollViewDidScroll: but I'm not sure if this would be the best thing to check over and over again. If anyone has any suggestions or helpful tips that would be really awesome.
Thanks!
One reason why scrollViewDidScroll is less than ideal choice is that your scroll view subclass will then need to be its own delegate. That will deny the users of that class the chance to be the delegate (easily, at least).
The better place to check this is in overriding layoutSubviews. And yes, like scrollViewDidScroll, it gets called a lot! But if you think about it, the only way to detect with certainty if any subview has been scrolled off, is to check when any scrolling occurs.
So the key is to be as efficient as you can checking. The first thing I'd try is fast enumeration of the subviews, asking if each frame transformed by contentOffset falls within the parent's bounds (using CGRectIntersectsRect). If not, add it to your reuse pool and remove it from superview.
Subclass UIScrollView and override setContentOffset. That's where the scrollViewDidScroll message comes from in the original UITableView, and that's where you can implement your own logic.
Edit: you might want to study the source code for PSTCollectionView, which is not a custom UITableView but a custom UICollectionView.
I do understand how to go about making the UIKeyboard push up the UIView if the active UITextView is blocked by the UIKeyboard as per this question: How to make a UITextField move up when keyboard is present?.
What I'm wondering is, from a design perspective, how do you go about implementing the keyboardDidShow and keyboardDidHide methods so that all of the views in your app, whether they be a UIView, UITableView, or UIScrollView all have this functionality and so you need to implement these methods only once?
The only way I could think of would be to have the view property of the UIViewController always set to a UIView, and if you have a UIViewController that needs a UIScrollView or UITableView, just attach it as a subview to this. Then if the UITextView is being blocked, just move the parent UIView up so it will move all of the views that are attached to it.
Does this sound like a good plan, or is it even worth it? Anyone else have any other ideas?
This is a little old, but it's a great article about using firstResponder methods to tell views to slide up. I, personally, like to put my UITextField in a parent container and move it all up. However, I do NOT suggest putting everything in there and moving it all up, because the UITextField "feels" better just above the keyboard. But I do like the background or certain items to move up with the UITextField.
See below: http://cocoawithlove.com/2008/10/sliding-uitextfields-around-to-avoid.html
This is a nice implementation that moves the field up based on the section of the screen it's in (upper, middle, lower). Works very well. May need to be updated for newest SDK, but should be pretty easy.
In experimenting with this, I noticed that if you want to make a BaseViewController that implements this functionality to work for everything that inherits from it, you have to attach another view on top of the UIViewController's view property in order to get it to work. Reason is, if you push the UIViewController's view property up when the keyboard appears, then it resets itself if the app comes back from being active and it's messy.
The problem with this however, is now in all of your child classes you have to attach your subviews to this new view property instead of the regular view property. Also, you probably have to make a custom UITableViewController which will inherit from your BaseViewController class so it can inherit the keyboard notification methods.
Ultimately, I've found it's not the worst idea to have another view on top of the UIViewController's property for a bunch of different scenarios. Making a custom UITableViewController isn't that big of a deal either. So if you have a lot of text fields in your app, this might not be the worst way to go.
I know there is stuff on GithHub which lets you implement a sleek 'pull down to sync' if you are in an UITableView.
However, all I would need to do is to know if the UITableView has been pulled down. I know there is a - (void)scrollViewDidScroll:(UIScrollView *)scrollView function, but that does not appear to fire if I scroll in an UITableView.
All I would need to know is, I suppose, if the UITableView scrolled beyond the upper bonds (which would give a minus figure, I suppose).
I'd be very grateful if anyone has any suggestions / solutions to this problem. Thanks in advance!
You don't say if your UITableView is being managed by a UITableViewController or you are managing it yourself. UITableView will send scrollViewDidScroll: messages, but only to the delegate of the table view instance.
Since you're saying scrollViewDidScroll: is not firing, I assume you are not subclassing UITableViewController and doing something else. Add the method to your table view's delegate and you will be notified of the scroll position changes.
I'd recommend EGORefreshTableHeaderView. Available on GitHub and works great.
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.
This is really more of a curiosity than a hard coding question.
Both Facebook and Twitter both have a feature where swiping a UITableViewCell animates the cell off the side to reveal a drawer with more controls underneath. How is something like that accomplished?
Here is a great open-source method for doing exactly this, based on the behavior of the Twitter app:
https://github.com/thermogl/TISwipeableTableView
This is a problem I have tried a couple of different solutions to. I really liked the behavior of Mailbox (mailboxapp.com). So I set out to achieve this. In the end I ended up with what I believe is a very simple solution: use a UIScrollView inside your cell. I have blog post that discusses and a sample app that demonstrates this behavior.
2 ways to detect swipt action
look at the willTransitionToState: method of UITableViewCell.
this method will be invoked when you swipe at the cell.
Custom swipe detection in a TableViewCell
and then you can change your cell view easily.
You could just implement -tableView:willBeginEditingRowAtIndexPath: in your table view delegate.
From the doc,
This method is called when the user swipes horizontally across a row; ... This method gives the delegate an opportunity to adjust the application's user interface to editing mode.
As a UITableViewCell is just a UIView, you can use this fact to basically do anything you like with it.
To solve your problem, I'd attach a UISwipeGestureRecognizer to detect the swipe and then animate the view to a different state.
For example, you could create a custom cell that has it's content view laying above the "actions view". Whenever there is a swipe, you use a UIView animation to move the content view aside and show the action view with a couple of buttons instead. In a custom UITableViewCell you could add a delegate protocol to have the pressed action and the cell being sent to the delegate, i.e. your controller. There you'd trigger what ever there is to trigger and then transition the cell out of the state.