I'm trying to perform a segue using a UIButton, which is located within in a custom UITableViewCell class called GFHomeCell.
The GFHomeCell has a postID property, which I want to send in the prepare for segue. I set up a method to run when the button is pressed; however, in the button-pressed method, I need the sender to be a GFHomeCell(or at least that's what I assume).
Does anyone have any ideas how I can do that? Here is my code
My cellForRowAtIndexPath:
GFHomeCell *cell = [tableView dequeueReusableCellWithIdentifier:#"newsfeedCell" forIndexPath:indexPath];
NSDictionary *rootObject = self.posts[indexPath.row];
NSDictionary *post = rootObject[#"post"];
NSDictionary *group = post[#"group"];
NSString *groupName = group[#"name"];
cell.actionLabel.text = [NSString stringWithFormat:#"New post trending on %#", groupName];
cell.descriptionLabel.text = post[#"body"];
cell.descriptionLabel.numberOfLines = 0;
cell.descriptionLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.likesLabel.text = [NSString stringWithFormat:#"%#", post[#"likes"]];
cell.postId = post[#"id"];
cell.groupName = group[#"name"];
cell.postBody = post[#"body"];
cell.likeButton.tag = indexPath.row;
[cell.likeButton addTarget:self action:#selector(likeButtonClick:) forControlEvents:(UIControlEvents)UIControlEventTouchDown];
[cell.commentButton addTarget:self action:#selector(commentButtonClick:) forControlEvents:(UIControlEvents)UIControlEventTouchDown];
NSString *urlString = [NSString stringWithFormat:#"%s/%#", kBaseURL, #"images/"];
NSURL *url = [NSURL URLWithString:urlString];
[cell.imageView setImageWithURL:url
placeholderImage:[UIImage imageNamed:#"Newsfeed-Image-Placeholder"]];
return cell;
Here is the method I'm running when the button is clicked. My thought was that I need the sender here to be a cell, not a button, as the postId property I'm sending in my prepareForSegue only exists on a GFHomeCell:
- (void)commentButtonClick:(id)sender {
[self performSegueWithIdentifier:#"addCommentSegue" sender:sender];
}
Finally my prepareForSegue(I only included the part relevant to this segue):
} else if ([segue.identifier isEqualToString:#"addCommentSegue"]) {
GFPostShowViewController *destViewController = segue.destinationViewController;
GFHomeCell * cell = sender;
destViewController.postId = [cell.postId copy];
destViewController.groupName = [cell.groupName copy];
destViewController.postBody = [cell.postBody copy];
} else {}
I'm new to iOS and this has me stumped so any help would be much appreciated, thanks.
There are basically two common approaches to this situation. One is to search up through the button's superviews until you find the cell. You shouldn't rely on going up one or two levels, because the hierarchy has changed in the past, and may change again (you need to go up two levels in iOS 6, but 3 in iOS 7). You can do it like this,
-(void)commentButtonClick:(UIButton *) sender {
id superView = sender.superview;
while (superView && ![superView isKindOfClass:[UITableViewCell class]]) {
superView = [superView superview];
}
[self performSegueWithIdentifier:#"addCommentSegue" sender:superView];
}
The other way is to assign a tag to your button in cellForRowAtIndexPath: equal to the indexPath.row (if you only have one section), and then use sender.tag to get the indexPath of the cell that contained the tapped button.
Well, one answer would be to just go up a level in the view hierarchy:
- (void)commentButtonClick:(id)sender {
GFHomeCell * cell = (GFHomeCell *) [(UIButton*)sender superview];
if (cell && [cell Class] == [GFHomeCell class]) {
//do whatever with cell.postID
[self performSegueWithIdentifier:#"addCommentSegue" sender:sender];
}
}
Oh, I forget... you may have to go up two levels to get past the contentView property:
GFHomeCell * cell = (GFHomeCell *) [[(UIButton*)sender superview] superview];
Related
I want to send data using a button click which is in uitableviewcell. I got the data from web service. Each row button send different data to viewController.
Attach cellForRowAtIndex Method below:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
static NSString *identifier = #"CategoryCell";
NSDictionary *dictMenuData = [_arrHandMadeList objectAtIndex:indexPath.row];
CategoryCell *cell = (CategoryCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
if(!cell) {
[tableView registerNib:[UINib nibWithNibName:#"CategoryCell" bundle:nil] forCellReuseIdentifier:identifier];
cell = (CategoryCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
}
cell.btnShowRatingDetails.tag = indexPath.row;
[cell.btnShowRatingDetails addTarget:self action:#selector(showRatingClicked:) forControlEvents:UIControlEventTouchUpInside];
[arrReview removeAllObjects];
//arrReview = [dictMenuData objectForKey:#"RivewData"];
[arrReview addObjectsFromArray:[dictMenuData objectForKey:#"RivewData"]];
[cell setupHandMadeCell:dictMenuData];
return cell;
}
Method for button is below:
-(void) showRatingClicked:(UIButton*)sender {
//if (sender.tag == currentIndex) {
ReviewVC *rvc = (ReviewVC*)[self.storyboard instantiateViewControllerWithIdentifier:#"ReviewVC"];
rvc.arrReviewDetails = arrReview;
rvc.strRestaurentName = [dictMenuData objectForKey:#"Restaurant_Name"];
rvc.strRestaurentId = [dictMenuData objectForKey:#"Restaurant_Id"];
rvc.strRestaurentRating = [dictMenuData objectForKey:#"Stars"];
[self.navigationController pushViewController:rvc animated:YES];
//}
}
Please help me
Thanks in advance
You need to get the index of selected cell button. You can get it from sender.tag.
-(void) showRatingClicked:(UIButton*)sender {
ReviewVC *rvc = (ReviewVC*)[self.storyboard instantiateViewControllerWithIdentifier:#"ReviewVC"];
NSDictionary *dictMenuData = [_arrHandMadeList objectAtIndex:sender.tag];
rvc.arrReviewDetails = [dictMenuData objectForKey:#"RivewData"]; //or as per your data
rvc.strRestaurentName = [dictMenuData objectForKey:#"Restaurant_Name"];
rvc.strRestaurentId = [dictMenuData objectForKey:#"Restaurant_Id"];
rvc.strRestaurentRating = [dictMenuData objectForKey:#"Stars"];
[self.navigationController pushViewController:rvc animated:YES];
}
Once cell.btnShowRatingDetails.tag = indexPath.row; button is assigned the tag you can get the data object in the action method, same way you get it using indexpath.row.
You need to use NSDictionary *dictReview = [_arrHandMadeList objectAtIndex:sender.tag]; in -(void) showRatingClicked:(UIButton*)sender to get the appropriate dictionary, then use it at the place of dictMenuData.
Remove dictMenuData altogether from your code.
I am trying to reach button indexpath in a correctly filled UITableView. I have two labels and one button in every cell customized in anouther XIB. When I click the button in any row in any section, it returns mw wrong indexpath. I am wondering what may cause this. Below you can find my code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ProgramCell";
ProgramCell *cell = (ProgramCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ProgramCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell.contentView setUserInteractionEnabled: NO]; //
NSString* strTemp = [NSString stringWithFormat: #"%d/%d", indexPath.section, indexPath.row ];
for (int i = 0; i < buttonClickedArray.count; i++) {
if([[buttonClickedArray objectAtIndex:i] isEqualToString:strTemp])
{
[cell.btnHatirlat setBackgroundColor:[UIColor colorWithRed:0.0 green:0.5 blue:0. alpha:0.7]];
[cell.btnHatirlat setTitle:#"Eklendi" forState:UIControlStateNormal];
}
}
NSString *str = #"";
str = [arrayPazartesi objectAtIndex:indexPath.row];
if ([str length] > 1)
{
NSString *strSaat = [str substringToIndex:5];
NSString *strEtkinlikAdi = [str substringFromIndex:6];
cell.lblEtkinlik.text = strEtkinlikAdi;
cell.lblSaat.text = strSaat;
[cell.btnHatirlat addTarget:self action:#selector(hatirlat:)
forControlEvents:UIControlEventTouchUpInside ];
}
return cell;
}
- (void) hatirlat:(UIButton *)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableProgram];
NSIndexPath *indexPath = [self.tableProgram indexPathForRowAtPoint:buttonPosition];
int j = indexPath.section; //true section
int i = indexPath.row; //wrong row
}
I've seen this problem before (but can't find the reference), and the fix was to not pick the corner of the button (I think this would only be a problem if the button is right at the top of a cell). Instead of,
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableProgram];
Try this to make sure you're not right on an edge,
CGPoint boundsCenter = CGRectOffset(sender.bounds, sender.frame.size.width/2, sender.frame.size.height/2).origin;
CGPoint buttonPosition = [sender convertPoint:boundsCenter toView:self.tableView];
Try using this instead. I have seen quite a few people complain about this method behaving quite weirdly.
CGPoint point = [self.tableView convertPoint:sender.frame.origin fromView:sender.superview];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:point];
Edit
The preferred way to do this would be to have the cell create the button (maybe during the init). And define a protocol for this cell, that returns a reference to the cell. Set the cell as the button delegate and when the button is clicked, pass a reference to the cell back to the cell delegate, which can call
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
e.g.
UITableViewCell.h
#protocol MyCellDelegate <NSObject>
#optional
- (void)cell:(UITableViewCell *)cell buttonPressed:(UIButton *)button;
#end
#interface MyCell : UITableViewCell
#property (weak, nonatomic) id<MyCellDelegate> delegate;
UITableViewCell.m
- (void)setDataWithDictionary:(NSDictionary *)dictionary
{
[self.titleLbl setText:[dictionary objectForKey:#"title"]];
[self.amountLbl setText:[dictionary objectForKey:#"amount"]];
btn = [[UIButton alloc] init];
[btn addTarget:self action:#selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
.....
}
- (void)buttonPressed
{
if(self.delegate)
{
if([self.delegate respondsToSelector:#selector(cell:buttonPressed:)])
{
[self.delegate cell:self buttonPressed:btn];
}
}
}
Why don't you set the elements index inside the UIButtons tag inside cellForRowAtIndexPath ?
Everytime you push the UIButton hatirlat will be called and you can access the index by the sender.
Maybe it will cause a problem because of your two UITableViews but I don't know exactly your code.
- (void) hatirlat:(UIButton *)sender{
UIButton *button = (UIButton *)sender;
_arrayForPosition[button.tag];
}
The button action is SongsSelectionSongs_Click. When I click this button, the button image changing, the button tap count is getting correct and after selected button images also changing, but when I scroll back and forth in the UITableView the button image seems to be randomly changing.
This is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"SongsTAbleViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SongsTAbleViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
btn_songSelect.tag = indexPath.row;
lbl_songLabel.text = [[arr_tablVArray objectAtIndex:indexPath.row] objectForKey:#"SongTitle"];
lbl_artistLabel.text = [[arr_tablVArray objectAtIndex:indexPath.row] objectForKey:#"SongArtist"];
return cell;
}
-(IBAction)SongsSelectionSongs_Click:(id)sender
{
UIButton *button = sender;
CGPoint correctedPoint = [button convertPoint:button.bounds.origin toView:self.tblv_SongslisttableView];
NSIndexPath *indexPath = [self.tblv_SongslisttableView indexPathForRowAtPoint:correctedPoint];
NSLog(#"Button tapped in row %d",indexPath.row);
SelectedAlbumUrl = [[arr_tablVArray objectAtIndex:indexPath.row] objectForKey:#"SongUrl"];
str_songtitle = [[arr_tablVArray objectAtIndex:indexPath.row] objectForKey:#"SongTitle"];
if ([[button backgroundImageForState:UIControlStateNormal] isEqual:[UIImage imageNamed:#"add.png"]])
{
btn_songsShareButton.userInteractionEnabled = YES;
[btn_songSelect setBackgroundImage:[UIImage imageNamed:#"remove.png"] forState:UIControlStateNormal];
buttonStatus = buttonStatus +1;
[btn_songsShareButton setImage:[UIImage imageNamed:#"share selected.png"] forState:UIControlStateNormal];
}
else
{
[btn_songSelect setBackgroundImage:[UIImage imageNamed:#"add.png"] forState:UIControlStateNormal];
buttonStatus = 1;
[btn_songsShareButton setImage:[UIImage imageNamed:#"share unselected.png"] forState:UIControlStateNormal];
}
}
You are not doing anything within your cellForRowAtIndexPath to select or deselect image. When you reuse a cell, it doesn't change the state of the cell unless you explicitly tell it to in cellForRow. Therefore, it will either reuse a selected or deselected cell (whatever is the first available reusable cell) and put that on the screen as-is.
To fix this issue, you need logic in your cellForRowAtIndexPath method to either select or deselect the image based on what is appropriate.
In general, if your problem has anything to do with "my cells don't show up right when scrolling" odds are you're not reusing your cells properly.
EDIT: in response to your comment, no, I will not rewrite your code. But I will give you some direction.
I would recommend keeping an additional key/value on your arr_tablVArray that will track whether or not the "share" should be enabled or disabled (I would suggest a bool value). This would make it so that you could check whether or not the "share" is enabled/disabled by checking a bool instead of checking the contents of the button's image in your IBAction method.
This info would now be available in your cellForRowAtIndexPath method as well, and you could check the value for the current record in arr_tablVArray and set your images accordingly just like you set your lbl_songLabel and lbl_artistLabel.
//Try It, it's Working Fine
pragma .h File
NSMutableArray * rowIdArray;
pragma .M File
#synthesize rowIdArray;
- (void)viewDidLoad
{
rowIdArray=[[NSMutableArray alloc]init];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [NamesArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
ViewControllerCell *cell = (ViewControllerCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
NSArray *nib;
nib = [[NSBundle mainBundle] loadNibNamed:#"ViewControllerCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
// Configure the cell...
cell.nameslbl.text = [NamesArray objectAtIndex:indexPath.row];
cell.nameBtn.tag=indexPath.row;
[cell.nameBtn addTarget:self action:#selector(NamesClick_Tapped:) forControlEvents:UIControlEventTouchUpInside];
NSString *a=[NSString stringWithFormat:#"%d", indexPath.row];
NSString *b=[[NSString alloc]init];
for (int i=0;i<[rowIdArray count];i++)
{
b=[rowIdArray objectAtIndex:i];
if ([a isEqualToString:b])
{
UIImage *buttonImage = [UIImage imageNamed:#"star_selected.png"];
[cell.nameBtn setBackgroundImage:buttonImage forState:UIControlStateNormal];
}
}
return cell;
}
-(IBAction)NamesClick_Tapped:(id)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.NameTableView];
NSIndexPath *indexPath = [self.NameTableView indexPathForRowAtPoint:buttonPosition];
NSString *rowIdStr = [NSString stringWithFormat:#"%d", indexPath.row];
if(![rowIdArray containsObject:rowIdStr])
{
[rowIdArray addObject:rowIdStr];
}else{
[rowIdArray removeObject: rowIdStr];
}
[self.NameTableView reloadData];
}
when you reuse a cell where the button has been already set, the same button appears with the previously set image. Instead of creating a new button every time you need a cell, you should just be resetting the state of an existing button. This link might help you.
I'm having a problem with UICollectionView with paging enabled. Each cell will cover whole screen, so only 1 cell is visible at a time
In the main view I have UICollectionView, and when user swipes to other cell, the navigation title will change accroding to the new cell, this works perfectly when users swipe properly, meaning that when swipe, UICollectionView push whole new cell to the screen
However, when users swipe just a little bit to reveal the next cell, then move back to current showing cell, the navigation title is changed, but the content is still current one
Does anyone have any idea how to solve this issue?
I attached image here for illustration
Thank you very much
Here's my code:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
SingleLabViewCollectionScrollCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:collectionCellID forIndexPath:indexPath];
if (cell == nil){
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SingleLabViewCollectionScrollCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
// hide
[cell.viewMain2 setHidden:YES];
[cell.viewMain3 setHidden:YES];
[cell.viewBubble2 setHidden:YES];
[cell.viewBubble3 setHidden:YES];
// set text view
[cell.lblLabText setFont:FONT_AVANT_BOOK(cell.lblLabText.font.pointSize)];
[cell.textview setScrollEnabled:YES];
[cell.textview setUserInteractionEnabled:YES];
NSDictionary *thisDict = [dictLabContentPlist valueForKey:self.titleName];
if(thisDict != nil){
NSDictionary *thisDictContent = [thisDict objectForKey:#"Text"];
NSString *content = [thisDictContent valueForKey:#"Content"];
NSAttributedString *ctAttri = [self attributedMessageFromMessage:content];
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(messageTapped:)];
[cell.textview addGestureRecognizer:gesture];
cell.textview.attributedText = ctAttri;
cell.lblLabText.text = [thisDictContent valueForKey:#"Title"];
}
// expand textview according to text
[cell.textview sizeToFit];
[cell.textview layoutIfNeeded];
cell.textview.backgroundColor = [UIColor clearColor];
CGRect rect = cell.viewDescription.frame;
rect.size.height = cell.textview.contentSize.height + 40;
cell.viewDescription.frame = rect;
[cell.viewMain.layer setCornerRadius:5];
[cell.viewMain2.layer setCornerRadius:5];
[cell.viewMain3.layer setCornerRadius:5];
[cell.viewDescription.layer setCornerRadius:5];
// set scrollview contentsize
rect.size.height += 400;
cell.cellScrollView.contentSize = rect.size;
[cell.cellScrollView setScrollEnabled:YES];
[cell.cellScrollView scrollsToTop];
// set bubble view
[cell.btnSeeMore addTarget:self action:#selector(expand:) forControlEvents:UIControlEventTouchUpInside];
// get data for this testID
for(int i = 0; i < self.arrayTestIDs.count; i++){
if([self.arrayTestIDs[i] isEqualToString:currentID]){
currentIndex = i;
break;
}
}
// load 1st time
if(firstTimeOpenThisView){
cell.lblTestName.text = self.arrayTestNames[currentIndex];
self.titleName = self.arrayTestNames[currentIndex];
currentID = self.arrayTestIDs[currentIndex];
}else{
currentIndex ++;
// set title name
cell.lblTestName.text = self.arrayTestNames[indexPath.row];
self.titleName = self.arrayTestNames[indexPath.row];
currentID = self.arrayTestIDs[indexPath.row];
}
NSMutableDictionary *postData = [[NSMutableDictionary alloc] init];
[postData setValue:singleton.ACCESS_TOKEN forKey:#"token"];
[postData setValue:currentID forKey:#"testId"];
// this is new block that check db when click next
NSArray *fetchObjects = [singleton loadDataFromTable:#"TestData"];
// first load data from DB
isDataExist = false;
for(NSManagedObject *item in fetchObjects){
if ([[item valueForKey:#"testID"] isEqualToString:[NSString stringWithFormat:#"%#",currentID]]) {
dataResponseDict = [item valueForKey:#"data"];
NSDictionary *commonDict = [dataResponseDict objectForKey:#"Common"];
cell.lblLeftValue.text = [commonDict valueForKey:#"min"];
cell.lblLeftLevel.text = [commonDict valueForKey:#"statusBegin"];
cell.lblUnit.text = [commonDict valueForKey:#"avg"];
cell.lblRightLevel.text = [commonDict valueForKey:#"statusEnd"];
cell.lblRightValue.text = [commonDict valueForKey:#"max"];
dataResponseArray = [dataResponseDict objectForKey:#"LabReport"];
//kenvu
NSDictionary *testDict = [dataResponseArray[0] objectForKey:#"Test"];
NSString *resultStr = [testDict valueForKey:#"result"];
if([resultStr isKindOfClass:[NSNull class]])
numberOfRows = 1;
else
numberOfRows = 2;
[self loadDataIntoCell:cell indexPath:indexPath];
isDataExist=true;
}
}
if(!isDataExist){ // even data exist, still needs to download from server for latest labs data
clvMain.hidden = YES;
[self showHud];
[ws downloadDataWithMethod:#"viewlab" requestMethod:#"POST" data:postData completionBlock:^(NSDictionary *resultDict){
NSDictionary *tmpDict = [resultDict valueForKey:WS_RESULT_DATA];
dataResponseDict = [resultDict valueForKey:WS_RESULT_DATA];
if(dataResponseDict != NULL && ![dataResponseDict isKindOfClass:[NSNull class]] && dataResponseDict.count > 0){
// remove existing data for this category id
for(NSManagedObject *item in fetchObjects){
if ([[item valueForKey:#"testID"] isEqualToString:[NSString stringWithFormat:#"%#",currentID]]) {
[singleton deleteObjectFromDB:item];
}
}
// save data to db
NSMutableDictionary *dataToSave = [[NSMutableDictionary alloc]init];
[dataToSave setObject:[NSString stringWithFormat:#"%#",currentID] forKey:#"testID"];
[dataToSave setObject:tmpDict forKey:#"data"];
[singleton saveNewData:dataToSave forTable:#"TestData"];
// only reload data if no data in DB
if(!isDataExist){
NSDictionary *commonDict = [dataResponseDict objectForKey:#"Common"];
cell.lblLeftValue.text = [commonDict valueForKey:#"min"];
cell.lblLeftLevel.text = [commonDict valueForKey:#"statusBegin"];
cell.lblUnit.text = [commonDict valueForKey:#"avg"];
cell.lblRightLevel.text = [commonDict valueForKey:#"statusEnd"];
cell.lblRightValue.text = [commonDict valueForKey:#"max"];
dataResponseArray = [dataResponseDict objectForKey:#"LabReport"];
//kenvu
NSDictionary *testDict = [dataResponseArray[0] objectForKey:#"Test"];
NSString *resultStr = [testDict valueForKey:#"result"];
if([resultStr isKindOfClass:[NSNull class]])
numberOfRows = 1;
else
numberOfRows = 2;
[self loadDataIntoCell:cell indexPath:indexPath];
}
}else{ // if data == nil, still show static info
numberOfRows = 1;
cell.lblLeftValue.text = cell.lblLeftLevel.text = cell.lblUnit.text = cell.lblRightLevel.text = cell.lblRightValue.text = #"";
[self loadDataIntoCell:cell indexPath:indexPath];
}
[self hideHud];
clvMain.hidden = NO;
}];
}
firstTimeOpenThisView = false;
return cell;
}
-(void)loadDataIntoCell:(SingleLabViewCollectionScrollCell *)cell indexPath:(NSIndexPath*)indexPath{
if(indexPath.row == self.arrayTestIDs.count - 1){
btnNext.hidden = YES;
}else{
btnNext.hidden = NO;
}
if(indexPath.row == 0){
btnPrevious.hidden = YES;
}else{
btnPrevious.hidden = NO;
}
// set navigation title
titleView.lblTestName.text = self.titleName;
[titleView.lblTestName setFont:FONT_AVANT_BOOK(cell.lblTestName.font.pointSize)];
.....
}
I found the solution for this.
By using scrollViewDidEndDecelerating, I just add a delay of 0.1 second before getting visibleCells of UICollectionView, and it always return correct visible cell
UICollectionView inherits from UIScrollView, which means you can access the contentOffset property of the collection view at any time. If you divide the contentOffset by the width of the collection view cells, you'll derive the index of the cell being shown, so you can figure out which cell is currently visible.
You could also exploit UIScrollViewDelegate's scrollViewDidScroll method - override this, then use the contentOffset to figure out how far the visible cell has moved and trigger the change of the navigation bar text. So you could wait until the current cell has scrolled more that 50% of its width to the next cell before changing - that way, if the user touched up and let the cell "snap" back, the nav bar title wouldn't be altered.
Okay, so having a look through Apple's developers documentation shows that there really aren't any delegate methods that will tell you when a cell is visible on screen. My first comment about checking this in cellForItemAtIndexPath isn't technically accurate either. That method should not know where a cell is on screen. Just how to display it.
So my suggestion is try this:
Remove the method call to loadDataIntoCell from cellForItemAtIndexPath.
Next since UICollectionView inherits from UIScrollView, you could use those delegate methods to figure out what to do when scrolling. Here is a rough example:
The method [collectionView visibleCells] will give you all visibleCells in an array. You could use that to change your title:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
for (UICollectionViewCell *cell in [collectionView visibleCells]) {
NSIndexPath *indexPath = [collectionView indexPathForCell:cell];
NSLog(#"%#",indexPath);
//Set the navigation title here
}
}
You will need to just manage the array and make sure the object in it is the correct one. But this should get you going in the right direction.
I have a UITableView that uses a custom UITableViewCell. My UITableVewCell has two textfields inside it, which I have added a tag to in my main ViewController that holds the UITableView which houses my custom UITableViewCell.
So this is the code inside my tableView:cellForRowAIndexPath:
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomFCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString *widthString = [currentFDictionary objectForKey:#"MM"];
if ((NSNull *) widthString != [NSNull null]) {
cell.widthTexField.text = widthString;
cell.widthTexField.tag = indexPath.row;
} else {
cell.widthTexField.text = #" ";
}
NSString *heightString = [currentFDictionary objectForKey:#"NM"];
if ((NSNull *) heightString != [NSNull null]) {
cell.heightTextField.text = heightString;
cell.heightTextField.tag = indexPath.row;
} else {
cell.heightTextField.text = #" ";
}
return cell;
I would like to know how to then use this .tag to scroll the UITableViewCell above the UIKeyboard that will now be shown in the view.
Anyhelp would be greatly apprecited.
A simple way i can think of is by using the -scrollToRowAtIndexPath:atScrollPosition:animated:
Set the delegate on the UITextField objects.
cell.widthTexField.delegate = self;
//...
cell.heightTextField.delegate = self;
Now, use -textFieldShouldBeginEditing: delegate method in this manner:
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
NSIndexPath *currentSelectedIndexPath = [self.tableView indexPathForSelectedRow];
[self.tableView scrollToRowAtIndexPath:currentSelectedIndexPath
atScrollPosition:UITableViewScrollPositionTop
animated:YES];
}
//NOTE: this way we don't really need to work with the textField tag per se
//(unless you are using it elsewhere as well)
//Instead, we work with the entire cell and scroll it to the desired position
this may not be perfect since i haven't tested it here but it's the general idea