My view contains a simple TableView with 6 rows and a button that invokes doScroll when clicked. My objective for doScroll() is simply scroll to the 5th cell such that it's at top of the table view.
- (void)doScroll: (id)sender
{
NSIndexPath *index = [NSIndexPath indexPathForRow:4 inSection: 1];
[m_tableView scrollToRowAtIndexPath:index atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
However when doScroll is invoked, the tableview scrolls only slightly. I suspect this has something to do with the size of the scroll view. So I tried increasing the height of m_tableview.contentsize before scrolling. After I do this however, no scrolling occurs at all...
The view controller is a simple UIViewController and refers to the table view via IBOutlet. For some reason, scrolling works as expected for the default Navigation Based Application, where the controller is a UITableViewController
The UITableView will prevent you from scrolling up empty space. Add enough valid content to the bottom of the table so the cell can scroll up. Use the bounds of the table less the height of the cell for a more accurate frame:
myTable.tableFooterView = [[[UIView alloc] initWithFrame:CGRectMake(0,0,320,480)] autorelease];
You could also just use the bottom of the contentInset property.
Related
I have a UICollectionViewController that is part of a Navigation Controller and Tab Bar Controller. At the beginning of the Navigation Controller, I have Interface Builder set to display the Toolbar at the bottom of the View. For the first View Controller of the Navigation Controller, I am using [self.navigationController setToolbarHidden:YES animated:YES]; in order to hide the Toolbar, then in my UICollectionViewController, I use
-(void)viewWillAppear:(BOOL)animated
{
[self.navigationController setToolbarHidden:NO animated:YES];
}
in order to have the Toolbar be displayed. This part works perfectly, my problem comes from the UICollectionViewCell that I have in the UICollectionView. I want it to be the full size of the UICollectionView, and I'm using AutoLayout, so I'm using:
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return self.collectionView.frame.size;
}
However, the first time the view is loaded, it returns the wrong value. The first time the view and CollectionView are loaded, that returns the size of the collectionView INCLUDING the height of the Toolbar, which then leads to the warning:
the item height must be less that the height of the UICollectionView
minus the section insets top and bottom values.
And the cell doesn't load. However, when I force a [self.collectionView reloadData]; after the warning, the correct value is returned for self.collectionView.frame.size and the cell loads.
I'm really frustrated at this and would greatly appreciate any help that anyone can offer.
Edit:
After reading Mundi's comment, I ended up changing some of my code to:
-(void)viewWillAppear:(BOOL)animated
{
[self.navigationController setToolbarHidden:NO animated:YES];
[self.collectionView reloadData];
}
And the issue was solved. However, now I have a new but related problem. When I add [self.collectionView scrollToItemAtIndexPath:selectedIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO]; (selectedIndexPath is pushed from the first view controller) to viewWillAppear, I get the same warning about the size of the UICollectionView item. If I have my code like this:
-(void)viewWillAppear:(BOOL)animated
{
[self.navigationController setToolbarHidden:NO animated:YES];
[self.collectionView scrollToItemAtIndexPath:selectedIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
[self.collectionView reloadData];
}
I don't get that size warning, but my collectionView always starts at index 0 rather than selectedIndexPath. If I change around the ordering to this:
-(void)viewWillAppear:(BOOL)animated
{
[self.navigationController setToolbarHidden:NO animated:YES];
[self.collectionView reloadData];
[self.collectionView scrollToItemAtIndexPath:selectedIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
}
I get that size warning, and the cell doesn't load until I invoke a method to call reloadData. However, it does start at the correct indexPath.
This problem is really about dealing with the view lifecycle. In viewWillAppear all the subviews are already laid out, so maybe you are hiding the toolbar too late.
Your solution to call reloadData after showing the toolbar is not so bad as all this happens before the view appears. It is logical - the geometry has changed and you have to recalculate the layout.
Try experimenting with the view controller's hidesBottomBarWhenPushed property. Maybe that takes care of this problem without having to code anything.
i have a tableview with a text field on each cell the problem is tableview should scroll up on selecting the text field.here i'm attaching my project can u please let me know what mistake i had made.
here is the link u can download it from here http://pastelink.me/dl/9c2f89
code that i have used to scroll up.
[super viewWillAppear:YES];
UITableViewCell *cellC = (UITableViewCell *)[[textField superview]superview];
[tabController scrollToRowAtIndexPath:[tabController indexPathForCell:cellC] atScrollPosition:UITableViewScrollPositionTop animated:YES];
look at this project here
add this class to your project and try to use it it may work(TPKeyboardAvoidingTableView .h/TPKeyboardAvoidingTableView .m).
You are using the code,
[tabController scrollToRowAtIndexPath:[tabController indexPathForCell:cellC] atScrollPosition:UITableViewScrollPositionTop animated:YES];
allow the tableView to scroll only when the content size is greater than the view height..
The above code will works if you give higher row count For eg: 15
Give tag to ur text filed properly in cellForRowAt:
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:[textField convertPoint:textField.frame.origin toView:self.tableView]];
when the textField becomes active, use scrollToRowAtIndexPath:atScrollPosition:animated:
for scroll the tableview
I have a UICollectionView which has nine cells in it. Each cell is a square, so that they're laid out in a 3 by 3 grid. This works nicely, and when the device rotates, I call performBatchUpdates:completion: to force the collectionView to layout the cells for the new orientation.
Here's what it looks like without the search bar:
I'm now trying to add a UISearchBar on top of the collectionView, like so:
I've tried adding it as a header view, but instead of appearing on top, it consumes the entire screen, and the cells are pushed off to the right. To see them, you scroll over, where there appear as they do without the search bar.
To add the search bar, I've tried two approaches. Neither works completely, and one seems like terrible practice. The first way I've tried is to add the search bar as a header view. My main view is a subclass of UICollectionViewController. Here's how I set things up:
- (void) viewDidLoad
{
// Set up some other things...
//
// Register the header view class
// which installs a search bar inside
// of itself.
//
[[self collectionView] registerClass:[PDReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"header"];
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
PDReusableView *header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"header" forIndexPath:indexPath];
[header setFrame:[[[self navigationController] navigationBar] bounds]];
return header;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
if (section == 0) {
return CGSizeMake(collectionView.frame.size.width, self.navigationController.navigationBar.frame.size.height);
}
return CGSizeZero;
}
Inside of PDReusableView, I install a UISearchBar. This is what I get:
So this approach fails, because I can't wrangle a search controller or search bar into a reusable view. If I can't put it into a reusable view, it can't go into a UICollectionView.
My other option is to resize the collection view, so it doesn't occupy the entirety of the screen. The question then becomes, where do I install the search bar in the view hierarchy? The simplest place, although likely incorrect, is the app delegate, where I set up the rest of the view hierarchy. I managed to get the search bar to appear above the collection view by installing it inside of application:didFinishLaunchingWithOptions: Here's my code for that:
UICollectionView *collectionView = [[self mainMenuViewController] collectionView];
CGRect f = [collectionView frame];
CGFloat height = [[[self navigationController] navigationBar] frame].size.height;
f.size.height -= height;
f.origin.y += height;
[collectionView setFrame:f];
// Cause the cells to be laid out per the new frame
[collectionView performBatchUpdates:nil completion:nil];
[[collectionView superview] addSubview:[self searchBar]];
[[self searchBar] setFrame:[[[self navigationController] navigationBar] bounds]];
While I could proceed to add search logic to the app delegate, it would be inappropriate to do so, because I'd be maintaining a dataset, filtered search results, and a lot of other logic in the app delegate. I feel like the UICollectionViewController subclass is a much more appropriate place to put it.
Is there a way to install the UISearchBar in a UICollectionView without using Interface Builder? How?
Edit:
I'm using a vanilla UICollectionViewFlowLayout and using some of the delegate methods to set the size of cells etc.
I haven't used UICollectionView or UICollectionViewController yet, but I have used UITableView and UITableViewController, and my general rule of thumb is: never use UITableViewController if you want to do anything complicated. I suspect that UICollectionViewController is similar: a fairly brittle, limited view controller that doesn't actually save you much hassle.
So if I were in your position, I'd be looking at just subclassing UIViewController and including a UICollectionView in my view controller. Your view hierarchy might then be as simple as:
Root UIView
UISearchBar
UICollectionView
I have subclassed the a text view, that fires off a delegate method, when the height has changed. When the height has changed I want to reload the table view cell, and increase its size
I am having one issue that I can not solve, the keyboard dismisses when the table view is reloaded, and I can not get around this. Below is the delegate method that is called when the text view's height is changed. Any suggestions?
- (void)textViewHeightChanged:(CGFloat)height
{
if (height > _textViewCellHeight) {
_textViewCellHeight = height;
[[self tableView] reloadRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:4 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
}
}
The tableview is probably causing the textview to resign first responder status when it reloads. Try sending -becomeFirstResponder to your textview after the table reload happens.
I have created one ipad app where 1st screen is split view. In that master view is table view and detail view holds image view controller. My problem is that when initially application gets loaded the 1st cell of table view should seen as selected and corresponding image view should appear at detail view.
It seems like you don't need only the cell to be seen as selected, but you need that cell to be selected (to make corresponding image appear)
You should see this post How do I select a UITableViewCell by default?
Here is sample code
-(void)viewDidLoad:(BOOL)animated {
[uiTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:0];
}
or if you actually want to make the cell look like selected, you can do something like
-(void)viewDidLoad:(BOOL)animated {
UITableViewCell *cell= [uiTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[cell setHighlighted:TRUE animated:TRUE];
}