I have a UICollectionView and its cells contains questions and UITextField that users must write in. I want to add a button onto the UICollectionViewCell, that the users must press that will scroll them to the next UICollectionViewCell. Is this possible and how do I do this.
You can set the button tag to hold the value of the index row.
So in your cellForRowAtIndexPath method add:
cell.nextButton.tag = indexPath.row
Then to scroll to a certain index you can call this when the button is pressed:
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES];
Sorry It's late, But today I am working on same functionality.
Please use below code and it's working.
1) Add line in cellForItemAtIndexPath.
btnNext.tag = indexPath.item;
2) Create method for scroll to next cell.
-(IBAction)actionNext:(UIButton *)sender{
if(sender.tag == 0 || sender.tag == nil){
btnNext.tag = 1;
}
if(sender.tag > arrImage.count){
[self.colView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:arrImage.count-1 inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
}else{
[self.colView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:sender.tag inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
}
}
Please ask me if you have any question. :)
Related
In my cellForRowAtIndexPath and I pre selecting a row:
NSArray *tempArray = [[communityPrefs objectForKey:#"Community"] componentsSeparatedByString:#","];
NSMutableArray *tempArrayMutable = [[NSMutableArray alloc] initWithArray:tempArray];
if ([tempArrayMutable containsObject:cell.textLabel.text])
{
[selectedAreaTable selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
This part works great. However the selected item is at the bottom of the page and the user will not see it, but when they scroll down to that cell it is selected.
Now I am trying to write a piece of code the will deselect all selected cells like so:
for(NSIndexPath *index in selectedAreaTable.indexPathsForSelectedRows)
{
if(index.row != 0)
{
[selectedAreaTable deselectRowAtIndexPath:index animated:NO];
}
}
but after I run this code the cell at the bottom is still selected. So my question is, why is this cell not being deselected? Is it because its not there until you scroll to it? How can I fix this problem?
Is it because its not there until you scroll to it?
Yes. I believe that you should change "selected" state using cell objects only for visible rows. All other rows should retrieve "selected" status in cellForRowAtIndexPath method
user979331,
you dont have to remove the selection in seperate method rather you can handle that too in cellForRowAtIndexPath as well.
You can declare the array NSMutableArray *tempArrayMutable as a property,
when you want to deselect all cell lets assume a method named clear all selection
-(void)clearAllSelection {
[self.tempArrayMutable removeAllObjects];
self.tableView reloadData];
}
Finally in cellForRowAtIndexPath change as
if ([self.tempArrayMutable containsObject:cell.textLabel.text])
{
[selectedAreaTable selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
else{
[selectedAreaTable deselectRowAtIndexPath:indexPath animated:NO];
}
I am having a collection view which shows 3 cells as visible. when i click the right arrow button, It should scroll to show the next 3 cells and when i click the left arrow button, It should scroll to show the previous 3 cells. In case if there is 2 cells behind, it should show those 2 cells with previous last visible cell.
can someone help with it?
You just need to do
[self.collectionView scrollToItemAtIndexPath:nextItem atScrollPosition:UICollectionViewScrollPositionBottom animated:YES];
where you need to pass indexpath for next item you want to scroll
I have found the solution.
- (void)viewDidLoad
{
oldrow=0;
}
- (IBAction)right_button:(id)sender
{
NSIndexPath *newIndexPath;
if (xr-1>0) {
oldsection = 0;
newIndexPath = [NSIndexPath indexPathForRow:oldrow+3 inSection:0];
oldrow=oldrow+3;
[collection_vw scrollToItemAtIndexPath:newIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
xr--;
xl++;
}
else if (y>0)
{
[_btn_right setHidden:YES];
oldsection = 0;
newIndexPath = [NSIndexPath indexPathForRow:array_stories.count-3 inSection:0];
oldrow=array_stories.count-3;
[collection_vw scrollToItemAtIndexPath:newIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
}
}
where
xr=array_stories.count/3;
xl=0;
y=array_stories.count%3;
I am making a chat application. When the keyboard appears, my UITableView and toolbar (with textfield and button) move up using the setFrame method.
The problem occurs when I am receiving a message from another user while I'm typing a message. When that happens (i.e. after an insertRowsAtIndexPaths to the UITableView), my UITableView and toolbar "reset" to their original positions.
Is this normal behavior caused by the system? I can't find anything in my code that would do this. I want that the toolbar remains visible so I can still type my message.
This is the code to add a convoItem (conversation item) to my array and UITableView:
- (void)insertConvoItem:(ConvoItem *)item
{
[_convoItems addObject:item];
// Update the table view
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:([self.convoItems count] - 1) inSection:0];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
// Scroll to the bottom so we focus on the latest message
NSUInteger numberOfRows = [self.tableView numberOfRowsInSection:0];
if (numberOfRows) {
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(numberOfRows - 1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}
It's normal. Receiving new message resets your table view to it's original position.
I have placed a button within a uicollectionviewcell and when that button is pressed, it is programmatically setting the cell as selected.
- (void) deleteItem:(id)sender
{
self.selected = YES;
[self.cellOptionsDelegate deleteItem];
}
It then delegates to the uicollectionviewcontroller to deleted the item that is selected.
- (void) deleteItem
{
NSArray* selectedItemsIndexPaths = [self.collectionView indexPathsForSelectedItems];
// Delete the items from the data source.
[self.taskArray removeObjectAtIndex:[[selectedItemsIndexPaths objectAtIndex:0] row]];
// Now delete the items from the collection view.
[self.collectionView deleteItemsAtIndexPaths:selectedItemsIndexPaths];
}
However, when i get the selected items using the uicollectionview method indexPathsForSelectedItems, it is not seeing that I have selected the item and the list is empty. I am using the press to select delegate method for another functionality so I was hoping to do something along the lines of what I explained above. Is there a way to make this work or a better way to inform the controller that the button pressed in the cell was tied to a cell at a specific index path?
Thank you.
Just send a cell pointer from your cell's deleteItem method
- (void) deleteItem:(id)sender
{
self.selected = YES;
[self.cellOptionsDelegate deleteItem:self];
}
and change uicollectionviewcontroller's method to
- (void) deleteItem:(UICollectionViewCell*)cellToDelete
{
NSIndexPath indexPathToDelete = [self indexPathForCell: cellToDelete];
// Delete the items from the data source.
[self.taskArray removeObjectAtIndex:[indexPathToDelete row]];
// Now delete the items from the collection view.
[self.collectionView deleteItemsAtIndexPaths:#[indexPathToDelete]];
}
Do not forget to update '(void) deleteItem:(UICollectionViewCell*)cellToDelete' declaration in your *.h file.
Solved by sending the cell through the delegate method and using this:
NSIndexPath* indexPath = [self.collectionView indexPathForCell:cell];
animated:
[self.collectionView performBatchUpdates:^ {
[_array removeObject:file];
[self.collectionView deleteItemsAtIndexPaths:#[indexPath]];
} completion:nil];
I have an application that works some what similar to how iPhone's Contact application works. When we add a new Contact user is directed to a view only screen with Contact information. If we select "All Contacts" from the navigation bar, user is navigated to list of all contacts where the recently added contact is in view.
We can move the view to a particular row using:
[itemsTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionBottom];
... but it's not working. I'm calling this right after calling:
[tableView reloadData];
I think I'm not suppose to call selectRowAtIndexPath:animated:scrollPosition method here. But if not here, then where?
Is there any delegate method that gets called after the following method?
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
I think I've got a similar app: A list of item., tap '+' -> new screen, come back and see the updated list, scrolled to show the added item at the bottom.
In summary, I put reloadData in viewWillAppear:animated: and scrollToRowAtIndexPath:... in viewDidAppear:animated:.
// Note: Member variables dataHasChanged and scrollToLast have been
// set to YES somewhere else, e.g. when tapping 'Save' in the new-item view.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (dataHasChanged) {
self.dataHasChanged = NO;
[[self tableView] reloadData];
} else {
self.scrollToLast = NO; // No reload -> no need to scroll!
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (scrollToLast) {
NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([dataController count] - 1) inSection:0];
[[self tableView] scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}
I hope this helps. If you add something in the middle of the list, you could easily scroll to that position instead.
You can try this , my application in some kind of similar to you when i click on a button scroll of uitableview is up.
[tableviewname setContentOffset:CGPointMake(0, ([arrayofcontact count]-10)*cellheight) animated:YES];
10 is for how many cell you want to scroll up
Hope this will help you:-)
Scrolling animation is inevitable when offset is set from viewDidAppear(_:). A better place for setting initial scroll offset is viewWillAppear(_:). You'll need to force the layout of a table view, because it's content size is not defined at that point.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.setNeedsLayout()
tableView.layoutIfNeeded()
if let selectedIndexPath = selectedIndexPath, tableView.numberOfRows(inSection: selectedIndexPath.section) > 0 {
tableView.scrollToRow(at: selectedIndexPath, at: .top, animated: false)
}
}
Do you have enough dummy contacts added to test the scrolling? It seems that only when your tableView is of a certain size the iPhone finds the inputus to scroll.
This is the code that works for me in my project. I use a previous button and therefore I scroll the tableview a little bit further down that it usually would go with UITABLEVIEWSCROLLPOSITION. (my previous button won't work if it can't "see" the previous cell.
Ignore some of the custom method calls.
- (void)textFieldDidBeginEditing:(UITextField *)textField {
//Show the navButtons
[self navButtonAnimation];
DetailsStandardCell *cell = (DetailsStandardCell *)textField.superview.superview.superview;
self.parentController.lastCell = cell;
//Code to scroll the tableview to the previous indexpath so the previous button will work. NOTE previous button only works if its target table cell is visible.
NSUInteger row = cell.cellPath.row;
NSUInteger section = cell.cellPath.section;
NSIndexPath *previousIndexPath = nil;
if (cell.cellPath.row == 0 && cell.cellPath.section != 0) //take selection back to last row of previous section
{
NSUInteger previousIndex[] = {section -1, ([[self.sections objectForKey:[NSNumber numberWithInt:section - 1]]count] -1)};
previousIndexPath = [[NSIndexPath alloc] initWithIndexes:previousIndex length:2];
}
else if (cell.cellPath.row != 0 && cell.cellPath.section != 0)
{
NSUInteger previousIndex[] = {section, row - 1};
previousIndexPath = [[NSIndexPath alloc] initWithIndexes:previousIndex length:2];
}
[self.theTableView scrollToRowAtIndexPath: cell.cellPath.section == 0 ? cell.cellPath : previousIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}