Make UITableView Smoother - objective-c

I have a UITableView that displays both images and text. Its a social app so I have to retrieve all data from the database, I'm using Parse. Heres the code. I know its long but if you could just skim through it that would be great. I have three different custom cells(nibs) that will be loaded depending on the content. A cell - just a string post, groupPost - also a string post, and a imageCell - for image posts. Im confused on how to make a smoother scroll such as facebooks, or instagrams. How I should load the images, and retrieve the data? Ive looked through posts and seen the recommendation of caching it but not exactly sure how to do that. Thanks for the help
postCell *cell = (postCell *)[tableView dequeueReusableCellWithIdentifier:#"postCell"];
groupPostCell *groupPost = (groupPostCell *) [self.tableView dequeueReusableCellWithIdentifier:#"groupPostCell"];
pictureCell *imageCell = (pictureCell *) [self.tableView dequeueReusableCellWithIdentifier:#"imageCell"];
PFObject *object = [self.friendPosts objectAtIndex:indexPath.row];
if ([object objectForKey:#"Image"] != nil) {
if (imageCell == nil) {
imageCell = [[pictureCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"imageCell"];
}
PFFile *file = [object objectForKey:#"Image"];
NSData *data = [file getData];
imageCell.imagePost.image = [UIImage imageWithData:data];
imageCell.caption.text = [object objectForKey:#"stringPost"];
PFFile *profileFile = [object objectForKey:#"profileImage"];
NSData *profileData = [profileFile getData];
imageCell.profileImage.image = [UIImage imageWithData:profileData];
[imageCell.name setTitle:[object objectForKey:#"User_Name"] forState:UIControlStateNormal];
[imageCell.eventButton setTitle:[object objectForKey:#"Event"] forState:UIControlStateNormal];
imageCell.name.hidden = false;
imageCell.eventButton.hidden = false;
imageCell.name.tag = indexPath.row;
imageCell.profileImageButton.tag = indexPath.row;
imageCell.eventButton.tag = indexPath.row;
[imageCell.name addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[imageCell.profileImageButton addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[imageCell.eventButton addTarget:self action:#selector(eventPage:) forControlEvents:UIControlEventTouchUpInside];
NSArray *likesArray = [object objectForKey:#"likes"];
NSString *likeString = [NSString stringWithFormat:#"%lu Likes", (unsigned long)likesArray.count];
if ([likesArray containsObject:[PFUser currentUser].objectId]) {
imageCell.rateButton.hidden = true;
}
else{
imageCell.rateButton.hidden = false;
}
NSArray *commentArray = [object objectForKey:#"Comments"];
NSString *commentString = [NSString stringWithFormat:#"%lu Comments", (unsigned long)commentArray.count];
[imageCell.likesButton setTitle:likeString forState:UIControlStateNormal];
[imageCell.commentsButton setTitle:commentString forState:UIControlStateNormal];
imageCell.rateButton.tag = indexPath.row;
imageCell.likesButton.tag = indexPath.row;
imageCell.commentsButton.tag = indexPath.row;
imageCell.flagButton.tag = indexPath.row;
[imageCell.rateButton addTarget:self action:#selector(like:) forControlEvents:UIControlEventTouchUpInside];
[imageCell.likesButton addTarget:self action:#selector(likesPage:) forControlEvents:UIControlEventTouchUpInside];
[imageCell.commentsButton addTarget:self action:#selector(imageComment:) forControlEvents:UIControlEventTouchUpInside];
[imageCell.flagButton addTarget:self action:#selector(flagPost:) forControlEvents:UIControlEventTouchUpInside];
[imageCell.timeButton setTitle:[self getDaysBetween:object.createdAt] forState:UIControlStateNormal];
return imageCell;
}
if ([object objectForKey:#"Group"] == nil) {
if (cell == nil) {
cell = [[postCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"postCell"];
}
cell.personStringPost.text = [object objectForKey:#"stringPost"];
if ([object objectForKey:#"Event"] == nil) {
[cell.noEventNameButton setTitle:[object objectForKey:#"User_Name"] forState:UIControlStateNormal];
cell.noEventNameButton.tag = indexPath.row;
[cell.noEventNameButton addTarget:self action:#selector(buttonPressed:) forControlEvents: UIControlEventTouchUpInside];
cell.nameLabel.hidden = true;
cell.eventLabel.hidden = true;
cell.noEventNameButton.hidden = false;
}
else{
[cell.nameLabel setTitle:[object objectForKey:#"User_Name"] forState:UIControlStateNormal];
cell.nameLabel.tag = indexPath.row;
[cell.nameLabel addTarget:self action:#selector(buttonPressed:) forControlEvents: UIControlEventTouchUpInside];
cell.noEventNameButton.hidden = true;
cell.nameLabel.hidden = false;
cell.eventLabel.hidden = false;
[cell.eventLabel setTitle:[object objectForKey:#"Event"] forState:UIControlStateNormal];
[cell.eventLabel addTarget:self action:#selector(eventPage:) forControlEvents:UIControlEventTouchUpInside];
}
[cell.timeLabel setTitle:[self getDaysBetween:object.createdAt] forState:UIControlStateNormal];
PFFile *imageFile = [object objectForKey:#"profileImage"];
NSData *data = [imageFile getData];
cell.profileImage.image = [UIImage imageWithData:data];
NSArray *likesArray = [object objectForKey:#"likes"];
NSString *likeString = [NSString stringWithFormat:#"%lu Likes", (unsigned long)likesArray.count];
if ([likesArray containsObject:[PFUser currentUser].objectId]) {
cell.likeButton.hidden = true;
}
else{
cell.likeButton.hidden = false;
}
NSArray *commentArray = [object objectForKey:#"Comments"];
NSString *commentString = [NSString stringWithFormat:#"%lu Comments", (unsigned long)commentArray.count];
[cell.likePage setTitle:likeString forState:UIControlStateNormal];
[cell.commentButton setTitle:commentString forState:UIControlStateNormal];
cell.eventLabel.tag = indexPath.row;
cell.profileImageButton.tag = indexPath.row;
cell.likeButton.tag = indexPath.row;
cell.commentButton.tag = indexPath.row;
cell.likePage.tag = indexPath.row;
cell.flagButton.tag = indexPath.row;
[cell.flagButton addTarget:self action:#selector(flagPost:) forControlEvents:UIControlEventTouchUpInside];
[cell.profileImageButton addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[cell.likePage addTarget:self action:#selector(likesPage:) forControlEvents:UIControlEventTouchUpInside];
[cell.likeButton addTarget:self action:#selector(like:) forControlEvents:UIControlEventTouchUpInside];
[cell.commentButton addTarget:self action:#selector(commentsPage:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
if ([object objectForKey:#"Group"] != nil) {
if (groupPost == nil) {
groupPost = [[groupPostCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"groupPostCell"];
}
[groupPost.groupNameButton setTitle:[object objectForKey:#"Group"] forState:UIControlStateNormal];
groupPost.groupNameButton.tag = indexPath.row;
[groupPost.groupNameButton addTarget:self action:#selector(groupPage:) forControlEvents:UIControlEventTouchUpInside];
[groupPost.groupNameButton setTitleColor:[self checkType:[object objectForKey:#"Type"]] forState:UIControlStateNormal];
NSArray *likesArray = [object objectForKey:#"likes"];
NSString *likeString = [NSString stringWithFormat:#"%lu Likes", (unsigned long)likesArray.count];
if ([likesArray containsObject:[PFUser currentUser].objectId]) {
groupPost.likeButton.hidden = true;
}
else{
groupPost.likeButton.hidden = false;
}
NSArray *commentArray = [object objectForKey:#"Comments"];
NSString *commentString = [NSString stringWithFormat:#"%lu Comments", (unsigned long)commentArray.count];
[groupPost.likePage setTitle:likeString forState:UIControlStateNormal];
[groupPost.commentsButton setTitle:commentString forState:UIControlStateNormal];
groupPost.likePage.tag = indexPath.row;
groupPost.likeButton.tag = indexPath.row;
groupPost.commentsButton.tag = indexPath.row;
[groupPost.likeButton addTarget:self action:#selector(like:) forControlEvents:UIControlEventTouchUpInside];
[groupPost.likePage addTarget:self action:#selector(likesPage:) forControlEvents:UIControlEventTouchUpInside];
[groupPost.commentsButton addTarget:self action:#selector(commentsPage:) forControlEvents:UIControlEventTouchUpInside];
if ([object objectForKey:#"Event"] == nil) {
groupPost.eventButton.hidden = true;
}
else{
groupPost.eventButton.hidden = false;
[groupPost.eventButton setTitle:[object objectForKey:#"Event"] forState:UIControlStateNormal];
groupPost.eventButton.tag = indexPath.row;
[groupPost.eventButton addTarget:self action:#selector(eventPage:) forControlEvents:UIControlEventTouchUpInside];
}
groupPost.flagButton.tag = indexPath.row;
[groupPost.flagButton addTarget:self action:#selector(flagPost:) forControlEvents:UIControlEventTouchUpInside];
[groupPost.timeButton setTitle:[self getDaysBetween:object.createdAt] forState:UIControlStateNormal];
groupPost.postLabel.text = [object objectForKey:#"stringPost"];
return groupPost;
}

Whenever you're working with data on a server, try to avoid, at all costs, loading that data synchronously. The line that says
NSData *data = [imageFile getData];[imageFile getData];
will make it so that nothing else can execute on the main thread until the data is done downloading. Here's how you should do it:
[imageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
if (!error) {
cell.profileImage.image = [UIImage imageWithData:imageData];
}
}];
That will make it so that all other code executes on the main thread and then when the data finishes downloading THEN it will load in the image. I would suggest putting a placeholder or loading view in the "cell.profileImage" and then when the image loads from Parse, it'll overwrite that placeholder.

Related

selection of cell is repeating while loading in tableview in objective c

Tick mark button selection of uitableview cell is repeating when scroll the tableview. and the tableview is already loaded with an array of item. but i need to do multi selection of cells in tableview
-(void)checkButtonClicked:(UIButton *)sender{
CGPoint touchPoint = [sender convertPoint:CGPointZero toView:_tableView];
NSIndexPath *indexPath = [_tableView indexPathForRowAtPoint:touchPoint];
sender.tag = indexPath.row;
selectedIndexForPassing = sender.tag;
if([_selectionArray count ] == 0){
_uploadSheetBtn.enabled = NO;
if (sender.selected){
sender.selected = false;
}
else{
TCSTimeSheet * sc = self.timesheetList[selectedIndexForPassing];
_canEdit = sc.canEdit;
if([_canEdit isEqual: #"1"]){
sender.selected = true;
_uploadSheetBtn.enabled = YES;
TCSTimeSheet * sc = self.timesheetList[selectedIndexForPassing];
NSDictionary * detailsDictionary= [NSDictionary dictionaryWithObjectsAndKeys:sc.timesheetDetailId,#"timesheetDetailId",sc.scheduleEmployeeDetailId, #"scheduleDetailId",sc.lastUpdatedTime,#"lastUpdatedTime",sc.timesheetStatus,#"timesheetStatus",sc.shiftDate , #"shiftDate",sc.employeeId ,#"employeeId",nil];
[_storingArray addObject:detailsDictionary];
[_selectionArray addObject:sc.clientId];
}
}
}
here is my cell for at indexpath code
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * reuseIdentifier = #"timeSheetCell" ;
TimeSheetCell * dataCell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
TCSTimeSheet * currentTimeSheet = self.timesheetList[indexPath.row] ;
_statusIndicator = currentTimeSheet.timesheetStatus;
_timesheetDetailId = currentTimeSheet.timesheetDetailId;
_timesheetDocId = currentTimeSheet.timesheetDocId;
_documentType = currentTimeSheet.documentType;
if(![currentTimeSheet.notes isEqual:#""]){
_notes = currentTimeSheet.notes;
}
if (dataCell == nil)
{
dataCell = [[TimeSheetCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier];
}
dataCell.clientNameLbl.text = currentTimeSheet.clientName;
dataCell.dayLbl.text = currentTimeSheet.shiftDay;
dataCell.dateLbl.text = currentTimeSheet.shiftDate;
dataCell.shiftTime.text = currentTimeSheet.shiftTime;
dataCell.shiftType.text = currentTimeSheet.shiftType;
[dataCell.checkBtn addTarget:self action:#selector(checkButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
if ([_statusIndicator isEqual: #"D"]) {
if([currentTimeSheet.canEdit isEqual:#"1"]) {
[dataCell.remarkBtn setImage:[UIImage imageNamed:#"selectedMessage_btn"] forState:UIControlStateNormal];
dataCell.containerView.backgroundColor = [UIColor colorWithDisplayP3Red:255.0 green:191.0 blue:0 alpha:0.5];
if(![currentTimeSheet.notes isEqual:#""]){
[dataCell.remarkBtn addTarget:self action:#selector(presentMessagePopUp:) forControlEvents:UIControlEventTouchUpInside];
}
}
}
else if ([_statusIndicator isEqual: #"U"]){
if([currentTimeSheet.canDelete isEqual:#"1"]){
[dataCell.remarkBtn setImage:[UIImage imageNamed:#"selectedDelete_btn"] forState:UIControlStateNormal];
[dataCell.remarkBtn addTarget:self action:#selector(deleteDocument:) forControlEvents:UIControlEventTouchUpInside];
}
}
else{
[dataCell.remarkBtn setImage:[UIImage imageNamed:#"unselectedDelete_btn"] forState:UIControlStateNormal];
dataCell.containerView.backgroundColor = [UIColor colorWithDisplayP3Red:255 green:255 blue:255 alpha:1];
[dataCell.checkBtn setImage:[UIImage imageNamed:#"timesheetUnselectedTick"] forState:UIControlStateNormal];
}
if([_timesheetDocId isEqual: #""] && [_timesheetDetailId isEqual:#""]) {
[dataCell.previewBtn setImage:[UIImage imageNamed:#"unselectedView_btn"] forState:UIControlStateNormal];
}
else {
[dataCell.previewBtn setImage:[UIImage imageNamed:#"selectedView_btn"] forState:UIControlStateNormal];
if([_documentType isEqual:#"image"]){
[dataCell.previewBtn addTarget:self action:#selector(buttonClickedToShowImage:) forControlEvents:UIControlEventTouchUpInside];
}
else {
[dataCell.previewBtn addTarget:self action:#selector(buttonClickedToShowDocuments:) forControlEvents:UIControlEventTouchUpInside];
}
}
return dataCell ;
}
**button action of the tick mark**
-(void)checkButtonClicked:(UIButton *)sender{
CGPoint touchPoint = [sender convertPoint:CGPointZero toView:_tableView];
NSIndexPath *indexPath = [_tableView indexPathForRowAtPoint:touchPoint];
sender.tag = indexPath.row;
selectedIndexForPassing = sender.tag;
if([_selectionArray count ] == 0){
_uploadSheetBtn.enabled = NO;
if (sender.selected){
sender.selected = false;
}
else{
TCSTimeSheet * sc = self.timesheetList[selectedIndexForPassing];
_canEdit = sc.canEdit;
if([_canEdit isEqual: #"1"]){
sender.selected = true;
_uploadSheetBtn.enabled = YES;
TCSTimeSheet * sc = self.timesheetList[selectedIndexForPassing];
NSDictionary * detailsDictionary= [NSDictionary dictionaryWithObjectsAndKeys:sc.timesheetDetailId,#"timesheetDetailId",sc.scheduleEmployeeDetailId, #"scheduleDetailId",sc.lastUpdatedTime,#"lastUpdatedTime",sc.timesheetStatus,#"timesheetStatus",sc.shiftDate , #"shiftDate",sc.employeeId ,#"employeeId",nil];
[_storingArray addObject:detailsDictionary];
[_selectionArray addObject:sc.clientId];
}
}
}
else{
TCSTimeSheet * sc = self.timesheetList[selectedIndexForPassing];
if (sender.selected){
NSDictionary * detailsDictionary= [NSDictionary dictionaryWithObjectsAndKeys:sc.timesheetDetailId,#"timesheetDetailId",sc.scheduleEmployeeDetailId, #"scheduleDetailId",sc.lastUpdatedTime,#"lastUpdatedTime",sc.timesheetStatus,#"timesheetStatus",sc.shiftDate,#"shiftDate",sc.employeeId,#"employeeId",nil];
sender.selected = false;
[_storingArray removeObject:detailsDictionary];
//[_selectionArray removeAllObjects];
if([_storingArray count] == 0){
_uploadSheetBtn.enabled = NO;
[_selectionArray removeAllObjects];
}
}
else{
if([_selectionArray firstObject] == sc.clientId){
_uploadSheetBtn.enabled = YES;
sender.selected = true;
NSDictionary * detailsDictionary= [NSDictionary dictionaryWithObjectsAndKeys:sc.timesheetDetailId,#"timesheetDetailId",sc.scheduleEmployeeDetailId, #"scheduleDetailId",sc.lastUpdatedTime,#"lastUpdatedTime",sc.timesheetStatus,#"timesheetStatus",sc.shiftDate , #"shiftDate",sc.employeeId ,#"employeeId",nil];
[_storingArray addObject:detailsDictionary];
}
else{
sender.selected = false;
UIAlertView *alertCantDisply=[[UIAlertView alloc]initWithTitle:#"Can't Select" message:#"Can choose same client only" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alertCantDisply show];
}
}
}
}
The cell will reuse, but the model will not, and the state of the view should be recorded in the model

remove objects from array based on the index

I have array of images here i am doing check and uncheck the images finally i have delete button which are the images i check i need to remove the images from array based on the button selection
here is my code
- (IBAction)delete_btn_touch:(id)sender {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
for(int i=0; i<_GalleryimageArry.count;i++){
_imageV = [[UIImageView alloc]initWithFrame:CGRectMake(CGRectGetWidth(self.view.frame) * i/2*0.6, 0, 100, 100)];
self.Crossbtn =[[UIButton alloc]initWithFrame:CGRectMake(_imageV.image.size.width/2+80,0,20,20)];
UIImage *btnImage = [UIImage imageNamed:#"unselectimag"];
[self.Crossbtn setImage:btnImage forState:UIControlStateNormal];
_imageV.contentMode = UIViewContentModeScaleAspectFill;
_imageV.image = [_GalleryimageArry objectAtIndex:i];
[_imageV setUserInteractionEnabled:YES];
_imageV.tag = i;
self.Crossbtn.tag =i;
[self.Crossbtn addTarget:self action:#selector(deleteImage:) forControlEvents:UIControlEventTouchUpInside];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapMethod:)];
[_imageV addGestureRecognizer:tap];
[self.imageV addSubview:self.Crossbtn];
[self.imageGalleryscroll addSubview:_imageV];
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
}
self.imageGalleryscroll.delegate = self;
index=0;
self.imageGalleryscroll.contentSize = CGSizeMake(CGRectGetWidth(self.view.frame) * _GalleryimageArry.count/2*0.7, CGRectGetHeight(self.imageGalleryscroll.frame));
[self.imageGalleryscroll setPagingEnabled:YES];
[self.imageGalleryscroll setShowsHorizontalScrollIndicator:NO];
self.imageGalleryscroll.alwaysBounceVertical = NO;
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
-(void)deleteImage:(UIButton *)sender{
btn = (UIButton *)sender;
self.add_delete_view.hidden =YES;
self.deleteview.hidden=NO;
if( [[btn imageForState:UIControlStateNormal] isEqual:[UIImage imageNamed:#"unselectimag"]])
{
[btn setImage:[UIImage imageNamed:#"Crossimg"] forState:UIControlStateNormal];
[btn setSelected:YES];
[btn setTag:index];
}
else
{
[btn setImage:[UIImage imageNamed:#"unselectimag"] forState:UIControlStateNormal];
// other statements
self.selectedimages =#"No";
image = [self.GalleryimageArry objectAtIndex:index];
[self.GalleryimageArry addObject:image];
}
NSLog(#"%#", self.GalleryimageArry);
}
- (IBAction)delete_all_img_btn_touch:(id)sender {
// self.view (change it with your button superview)
if (btn.selected) {
[self.GalleryimageArry removeObjectAtIndex:index];
}
//here i need to removeObjectAtIndex:index based on the how many button are selected
}
any one help me to solve this issues
thanks in advance
Use the following code, where you want to clear the back stack of controllers.
-(void)clearStack
{
NSMutableArray *navigationArray = [[NSMutableArray alloc] initWithArray: self.navigationController.viewControllers];
[navigationArray removeAllObjects];
//[navigationArray removeObjectAtIndex: 2];
self.navigationController.viewControllers = navigationArray;
}

TableView reloadData does not remove images

I have tableView with multiple types of dynamic prototype cells. When I call reloadData in viewDidLoad most of the data gets reloaded but the images remain and overlap with the new content. Is there another command that I'm missing?
Here's the code snippet (tried to edit it down for simplicity):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
PFObject *question = [self.friendsPosts objectAtIndex:indexPath.row];
...
else if ([[question objectForKey:#"questionType"] isEqualToString:#"PhotoChoice"]) {
static NSString *CellIdentifier = #"PhotoChoiceCell";
PhotoChoiceTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
PFUser *asker = [question objectForKey:#"asker"];
[asker fetch];
cell.question = question;
cell.usernameLabel.text = asker.username;
cell.questionLabel.text = [question objectForKey:#"questionText"];
cell.delegate = self;
[cell setCellIndexPath:indexPath];
[cell.questionLabel adjustFontSizeToFit];
cell.answered = false;
NSDate *postedTime = [question createdAt];
NSString *postedAgo = [postedTime dateTimeAgo];
cell.timeLabel.text = postedAgo;
[cell.likeButton setTitle:[NSString stringWithFormat:#"Likes (%#)", [question objectForKey:#"likes"]] forState:UIControlStateNormal];
cell.commentButton.text = [NSString stringWithFormat:#"Comments (%lu)", (unsigned long)[[question objectForKey:#"comments" ] count]];
PFRelation *allAnswerers = [question objectForKey:#"answerersRelation"];
PFQuery *answerersQuery = [allAnswerers query];
[answerersQuery whereKey:#"objectId" equalTo:[[PFUser currentUser] objectId]];
[answerersQuery countObjectsInBackgroundWithBlock:^(int number, NSError *error) {
if (error) {
NSLog(#"Error %# %#", error, [error userInfo]);
}
else {
if (number == 0) {
if ( [[question objectForKey:#"numPhotos"] isEqualToString:#"2" ]) {
[cell.photoButtonA1 setImage:allImages[0] forState:UIControlStateNormal];
[cell.photoButtonA2 setImage:allImages[1] forState:UIControlStateNormal];
cell.photoButtonA1.hidden = NO;
cell.photoButtonA2.hidden = NO;
}
else if ( [[question objectForKey:#"numPhotos"] isEqualToString:#"3"] ) {
[cell.photoButtonB1 setImage:allImages[0] forState:UIControlStateNormal];
[cell.photoButtonB2 setImage:allImages[1] forState:UIControlStateNormal];
[cell.photoButtonB3 setImage:allImages[2] forState:UIControlStateNormal];
cell.photoButtonB1.hidden = NO;
cell.photoButtonB2.hidden = NO;
cell.photoButtonB3.hidden = NO;
}
else if ( [[question objectForKey:#"numPhotos"] isEqualToString:#"4"] ) {
[cell.photoButtonC1 setImage:allImages[0] forState:UIControlStateNormal];
[cell.photoButtonC2 setImage:allImages[1] forState:UIControlStateNormal];
[cell.photoButtonC3 setImage:allImages[2] forState:UIControlStateNormal];
[cell.photoButtonC4 setImage:allImages[3] forState:UIControlStateNormal];
cell.photoButtonC1.hidden = NO;
cell.photoButtonC2.hidden = NO;
cell.photoButtonC3.hidden = NO;
cell.photoButtonC4.hidden = NO;
}
}
So, I should have made it clear that the images were set as UIButtons.
OK, here is my guess:
You seem to have three types of cell: one with 2 images, one with 3, and one with 4; but they are all of the same class and use the same cell identifier.
So when you recycle (dequeue) your table cells, you might be reusing a cell that was previously assigned 4 images, but this time using it as a 2-image cell. Thus, you update only 2 images of the previous 4, and the other two remain unchanged. You should set the remaining images to nil when you set less than 4 images to a cell (2 or 3).
Although without further details on the pattern of occurrence of your bug, it is hard to tell.
Try this modification to your code:
// (previous code omitted)
if (number == 0) {
// Reset all cell images, regardless of type
[cell.photoButtonA1 setImage:nil forState:UIControlStateNormal];
[cell.photoButtonA2 setImage:nil forState:UIControlStateNormal];
[cell.photoButtonB1 setImage:nil forState:UIControlStateNormal];
[cell.photoButtonB2 setImage:nil forState:UIControlStateNormal];
[cell.photoButtonB3 setImage:nil forState:UIControlStateNormal];
[cell.photoButtonC1 setImage:nil forState:UIControlStateNormal];
[cell.photoButtonC2 setImage:nil forState:UIControlStateNormal];
[cell.photoButtonC3 setImage:nil forState:UIControlStateNormal];
[cell.photoButtonC4 setImage:nil forState:UIControlStateNormal];
//
if ( [[question objectForKey:#"numPhotos"] isEqualToString:#"2" ]) {
[cell.photoButtonA1 setImage:allImages[0] forState:UIControlStateNormal];
[cell.photoButtonA2 setImage:allImages[1] forState:UIControlStateNormal];
cell.photoButtonA1.hidden = NO;
cell.photoButtonA2.hidden = NO;
}
else if ( [[question objectForKey:#"numPhotos"] isEqualToString:#"3"] ) {
[cell.photoButtonB1 setImage:allImages[0] forState:UIControlStateNormal];
[cell.photoButtonB2 setImage:allImages[1] forState:UIControlStateNormal];
[cell.photoButtonB3 setImage:allImages[2] forState:UIControlStateNormal];
cell.photoButtonB1.hidden = NO;
cell.photoButtonB2.hidden = NO;
cell.photoButtonB3.hidden = NO;
}
else if ( [[question objectForKey:#"numPhotos"] isEqualToString:#"4"] ) {
[cell.photoButtonC1 setImage:allImages[0] forState:UIControlStateNormal];
[cell.photoButtonC2 setImage:allImages[1] forState:UIControlStateNormal];
[cell.photoButtonC3 setImage:allImages[2] forState:UIControlStateNormal];
[cell.photoButtonC4 setImage:allImages[3] forState:UIControlStateNormal];
cell.photoButtonC1.hidden = NO;
cell.photoButtonC2.hidden = NO;
cell.photoButtonC3.hidden = NO;
cell.photoButtonC4.hidden = NO;
}
}
// (following code omitted)

UIButtons in UIScrollView stop working after 3 rows

I have a UIScrollView with a list of UIViews within it. Bit like a fancy tableview. One issue I am having is the buttons work ok for the first 3 'rows' in the scrollview, but none of the buttons after this respond when i scroll down. Looks like its working ok for the buttons that show on screen when the view has loaded but anything further down when i scroll will now respond at all...
code from within the uiview repeated within uiscrollview
-(void)addButtons
{
UIButton *visiteWebSite = [UIButton buttonWithType:UIButtonTypeCustom];
[visiteWebSite addTarget:self
action:#selector(visitSite:)
forControlEvents:UIControlEventTouchDown];
[visiteWebSite setTintColor:[UIColor colorWithRed:247 green:143 blue:30 alpha:1.0]];
visiteWebSite.frame = CGRectMake(440.0, 10.0, 120.0, 26.0);
if(![self IsPhone5]) {
visiteWebSite.frame = CGRectMake(350.0, 10.0, 120.0, 26.0);
}
//visiteWebSite.backgroundColor = [UIColor orangeColor]; //[UIColor colorWithRed:247 green:143 blue:30 alpha:1.0];
[visiteWebSite setBackgroundImage:[UIImage imageNamed:#"orangeBG"] forState:UIControlStateNormal];
[visiteWebSite setTitle:#"VISITE WEBSITE" forState:UIControlStateNormal];
visiteWebSite.titleLabel.font = [UIFont fontWithName:#"arial" size:12];
[self addSubview:visiteWebSite];
UIButton *getDirections = [UIButton buttonWithType:UIButtonTypeCustom];
[getDirections addTarget:self
action:#selector(getDirections:)
forControlEvents:UIControlEventTouchDown];
[getDirections setTitle:#"GET DIRECTIONS" forState:UIControlStateNormal];
getDirections.titleLabel.font = [UIFont fontWithName:#"arial" size:12];
getDirections.frame = CGRectMake(440.0, 46.0, 120.0, 26.0);
if(![self IsPhone5]) {
getDirections.frame = CGRectMake(350.0, 46.0, 120.0, 26.0);
}
[getDirections setBackgroundImage:[UIImage imageNamed:#"orangeBG"] forState:UIControlStateNormal];
[self addSubview:getDirections];
}
Code from Parent View containing the UIScrollView
-(void)performSearch
{
[self.loadinglabel removeFromSuperview];
NSString* searchTerm = txtSearch.text;
searchTerm = [searchTerm stringByReplacingOccurrencesOfString:#" " withString:#""];
NSData *urldata = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://www.collectioncosmetics.co.uk/storelocatorapi?store=%#",searchTerm]]];
NSString *json = [[NSString alloc] initWithData:urldata encoding:NSUTF8StringEncoding];
SBJsonParser *jsonParser = [[SBJsonParser alloc] init];
NSArray *jsonObjects = [jsonParser objectWithString:json];
float y = 0;
float height = 84;
if([jsonObjects count] < 1) {
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:#"NO RESULTS" message:#"There are no stores near the postcode you searched" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alertView show];
[self back:nil];
return;
}
for (int i = 0; i < [jsonObjects count]; i++)
{
NSDictionary *dict = [jsonObjects objectAtIndex:i];
CARStoreResult* result = [[CARStoreResult alloc] initWithFrame:CGRectMake(0, height*i, tv.frame.size.width, height)];
result.name = [dict objectForKey:#"name"];
result.street = [dict objectForKey:#"street"];
result.area = [dict objectForKey:#"area"];
result.county = [dict objectForKey:#"County"];
result.postcode = [dict objectForKey:#"PostCode"];
result.distance = [dict objectForKey:#"distance"];
result.usersPostCode = searchTerm;
result.y = y;
result.num = i;
y = y + height;
[result build];
[tv addSubview:result];
}
[tv setFrame:CGRectMake(tv.frame.origin.x, tv.frame.origin.y, tv.frame.size.width, height*[jsonObjects count])];
[self.scrollView setContentSize:tv.frame.size];
[Flurry logEvent:#"Store Locator"];
}
FIXED!
instead of adding the views to a view within the scrollview i added them just directly to the scrollview. with the scrollview having scrollView.canCancelContentTouches set to NO.
//[tv addSubview:result];
[self.scrollView addSubview:result];
}
//[tv setFrame:CGRectMake(tv.frame.origin.x, tv.frame.origin.y, tv.frame.size.width, height*[jsonObjects count])];
[self.scrollView setContentSize:CGSizeMake(320, height*[jsonObjects count])];
//[self.scrollView setContentSize:tv.frame.size];
[Flurry logEvent:#"Store Locator"];

buttons check the correct answer objective-c

I have one UIViewController and inside I have NSArray that I put my correct answer,and also I have 3 buttons, and 3 NSArray for their titles, I want to check if my buttons title was equal to the correct answer then goes to the correct page else goes to the wrong page
would you please help me to this implementation:
Thanks in advance!
Here is my code:
NSString *correctOne = #"test1";
NSString *correctTwo = #"test2";
NSString *correctThree = #"test3";
NSString *correctFour = #"test4";
NSString *correctFive = #"test5";
NSString *correctSix = #"test6";
NSString *correctSeven = #"test7";
NSString *correctEight = #"test8";
correctComments = [[NSArray alloc] initWithObjects: correctOne, correctTwo, correctThree,
correctFour, correctFive, correctSix, correctSeven, correctEight, nil];
int rand = arc4random()%8;
NSString *correct = [correctComments objectAtIndex:rand];
[test setTitle:(firstAnswer) forState:UIControlStateNormal];
[test setTitleColor:[UIColor blueColor] forState:UIControlStateSelected];
[test setTag:0];
[ansONE setTitle:(secondAnswer) forState:UIControlStateNormal];
[ansONE setTitleColor:[UIColor blueColor] forState:UIControlStateSelected];
[ansONE setTag:1];
[ansTWO setTitle:(threeAnswer) forState:UIControlStateNormal];
[ansTWO setTitleColor:[UIColor blueColor] forState:UIControlStateSelected];
[ansTWO setTag:2];
- (IBAction)suivant:(id)sender {
//MY Question is how should I check my button title and correctComments
}
- (IBAction)suivant:(id)sender {
UIButton *button = (UIButton *)sender;
int correctIndex = ...;
BOOL thisIsTheCorrectButton = (button.tag == correctIndex);
// Do whatever
}
At first you have to store correct answer from your code snippet to a property:
self.correctAnswer = correct;
Then do the comparision of those strings:
- (IBAction)suivant:(UIButton *)sender {
// You wanted to check for title:
if ([sender.currentTitle isEqualToString:self.correctAnswer]) {
// Correct...
}
else {
// Wrong...
}
}