Keep Button State Selected in UICollection view with horizontal scroll - ios

I am following this example
I have added a button in the view
On selection the button image change to Green icon image.
How could I retain it using this example?

I had updated the existing code of your example to your requirement please find the below url for download the code and review it.
Link : https://www.dropbox.com/s/6xsr4o88khyijun/HorizontalTables.zip?dl=0
Highlight of the code which I had done it.
1) Take the NSMutableArray *arrSelection property in HorizontalTablesAppDelegate class.
2) Fill the data of arrSelection in ArticleListViewController_iPhone class of viewDidLoad method.
for (NSInteger i = 0; i < [self.articleDictionary.allKeys count]; i++)
{
HorizontalTableCell_iPhone *cell = [[HorizontalTableCell_iPhone alloc] initWithFrame:CGRectMake(0, 0, 320, 416) tag:i];
categoryName = [sortedCategories objectAtIndex:i];
currentCategory = [self.articleDictionary objectForKey:categoryName];
cell.articles = [NSArray arrayWithArray:currentCategory];
if(i == 0)
appDelegate.arrSelection = [[NSMutableArray alloc] init];
NSMutableArray *arrSubData = [[NSMutableArray alloc] init];
for(NSInteger j=0; j<currentCategory.count; j++)
[arrSubData addObject:[NSNumber numberWithBool:NO]];
[appDelegate.arrSelection addObject:arrSubData];
[arrSubData release];
[self.reusableCells addObject:cell];
[cell release];
}
3) On HorizontalTableCell_iPhone class of cellForRowAtIndexPath method
NSMutableArray *arrSelectionInfo = appDelegate.arrSelection[tableView.tag];
BOOL isSelect = [arrSelectionInfo[indexPath.row] boolValue];
if(isSelect)
[cell.btnSelection setBackgroundColor:[UIColor greenColor]];
else
[cell.btnSelection setBackgroundColor:[UIColor whiteColor]];
And didSelectRowAtIndexPath method
NSMutableArray *arrUpdate = appDelegate.arrSelection[tableView.tag];
[arrUpdate replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:YES]];
[tableView reloadData];
Hope this will work for you.

To keep button state selected you need to store information of selection on a dictionary for the cell. So once cell is reloaded, you can apply selection setting based on information you have.
There is no direct way (even if there was you should now use that, as it will lead to memory abuse) to keep it selected all the time.

Related

Reload UIScrollView by tapping a UIButton

Let me explain my project first. I have some data in my SQLIte DB table called "note".
In "note" table I have these fields: id, noteToken, note.
What I am doing here is load all the note in an NSMUtableArray from that table. And create UIButton according to that array content number and add those buttons in a UIScrollView as subView. The number of buttons and width of scrollview generate auto according to the number of content of that array. Now, when some one tap one of those Buttons, it will bring him to a next viewController and show him the corresponding note details in that viewController.
I do the same thing with another NSMUtableArray, but these time it read all the id from the "note" table. It equally generate new delete button in the same UIScrollView. But if some one tap on these delete button it will delete that particular note from the table "note" of SQLIte DB. AND RELOAD THE UIScrollView. All are done except the RELOAD THE UIScrollView part. This is what I want. I tried with all exist solution but don't know why it's not working.
Here is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
self.noteToken = [NSString stringWithFormat:#"%#%#", fairId, exibitorId];
scrollViewNoteWidth = 100;
[scrollViewNote setScrollEnabled:YES];
[scrollViewNote setContentSize:CGSizeMake((noteButtonWidth * countNoteButtonArray) + scrollViewNoteWidth, 100)];
sqLite = [[SQLite alloc] init];
[self.sqLite callDataBaseAndNoteTableMethods];
self.noteButtonArrayy = [[NSMutableArray alloc] init];
noteButtonArrayy = [self.sqLite returnDataFromNoteTable:noteToken];
[self LoadNoteButtonAndDeleteButton:noteButtonArrayy];
}
//////////////*----------------------- Note Section (Down) -----------------------*//////////////
-(void) LoadNoteButtonAndDeleteButton:(NSMutableArray *) noteButtonArray
{
sQLiteClass = [[SQLiteClass alloc] init];
noteButtonArrayToShowNoteButton = [[NSMutableArray alloc] init];
/*--------------- Load the noteButton & pass note (Down)---------------*/
for (int i = 0; i < [noteButtonArray count]; i++)
{
sQLiteClass = [noteButtonArray objectAtIndex:i];
// NSString *ids = [NSString stringWithFormat:#"%d", sQLiteClass.idNum];
NSString *nt = sQLiteClass.note;
[noteButtonArrayToShowNoteButton addObject:nt];
}
[self ShowNoteButtonMethod:noteButtonArrayToShowNoteButton];
/*--------------- Load the noteButton & pass note (Up)---------------*/
/*--------------- Load the deleteButton & pass id (Down)---------------*/
noteButtonArrayToDeleteNoteButton = [[NSMutableArray alloc] init];
for (int i = 0; i < [noteButtonArray count]; i++)
{
sQLiteClass = [noteButtonArray objectAtIndex:i];
// Convert int into NSString
NSString *ids = [NSString stringWithFormat:#"%d", sQLiteClass.idNum];
[noteButtonArrayToDeleteNoteButton addObject:ids];
}
[self ShowNoteDeleteButtonMethod:noteButtonArrayToDeleteNoteButton];
/*--------------- Load the deleteButton & pass id (Down)---------------*/
}
-(void) ShowNoteButtonMethod:(NSMutableArray *) btnarray
{
countNoteButtonArray = [btnarray count];
// For note button
noteButtonWidth = 60;
noteButtonXposition = 8;
for (NSString *urls in btnarray)
{
noteButtonXposition = [self addNoteButton:noteButtonXposition AndURL:urls];
}
}
-(int) addNoteButton:(int) xposition AndURL:(NSString *) urls
{
noteButton =[ButtonClass buttonWithType:UIButtonTypeCustom];
noteButton.frame = CGRectMake(noteButtonXposition, 8.0, noteButtonWidth, 60.0);
[noteButton setImage:[UIImage imageNamed:#"note.png"] forState:UIControlStateNormal];
[noteButton addTarget:self action:#selector(tapOnNoteButton:) forControlEvents:UIControlEventTouchUpInside];
[noteButton setUrl:urls];
noteButton.backgroundColor = [UIColor clearColor];
[self.scrollViewNote addSubview:noteButton];
noteButtonXposition = noteButtonXposition + noteButtonWidth + 18;
return noteButtonXposition;
}
-(void)tapOnNoteButton:(ButtonClass*)sender
{
urlNote = sender.url;
[self performSegueWithIdentifier:#"goToNoteDetailsViewController" sender:urlNote];
}
-(void) ShowNoteDeleteButtonMethod:(NSMutableArray *) btnarray
{
countNoteButtonArray = [btnarray count];
// For delete button
deleteNoteButtonWidth = 14;
deleteNoteButtonXposition = 31;
for (NSString *idNumber in btnarray)
{
deleteNoteButtonXposition = [self addDeleteButton:deleteNoteButtonXposition AndURL:idNumber];
}
}
-(int) addDeleteButton:(int) xposition AndURL:(NSString *) idNumber
{
deleteNoteButton =[ButtonClass buttonWithType:UIButtonTypeCustom];
deleteNoteButton.frame = CGRectMake(deleteNoteButtonXposition, 74.0, deleteNoteButtonWidth, 20.0);
[deleteNoteButton setImage:[UIImage imageNamed:#"delete.png"] forState:UIControlStateNormal];
[deleteNoteButton addTarget:self action:#selector(tapOnDeleteButton:) forControlEvents:UIControlEventTouchUpInside];
[deleteNoteButton setIdNum:idNumber];
deleteNoteButton.backgroundColor = [UIColor clearColor];
[self.scrollViewNote addSubview:deleteNoteButton];
deleteNoteButtonXposition = deleteNoteButtonXposition + deleteNoteButtonWidth + 65;
return deleteNoteButtonXposition;
}
-(void)tapOnDeleteButton:(ButtonClass*)sender
{
idNumb = sender.idNum;
[self.sqLite deleteData:[NSString stringWithFormat:#"DELETE FROM note WHERE id IS '%#'", idNumb]];
// NSLog(#"idNumb %#", idNumb);
//[self.view setNeedsDisplay];
//[self.view setNeedsLayout];
//[self LoadNoteButtonAndDeleteButton];
//[self viewDidLoad];
// if ([self isViewLoaded])
// {
// //self.view = Nil;
// //[self viewDidLoad];
// [self LoadNoteButtonAndDeleteButton];
// }
}
//////////////*----------------------- Note Section (Up) -----------------------*//////////////
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"goToNoteDetailsViewController"])
{
NoteDetailsViewController *noteDetailsViewController = [segue destinationViewController];
[noteDetailsViewController setUrl:sender];
}
}
Here's the screen shot:
Here we can feel the difference between UIScrollView and UICollectionView, however UICollectionView is made up of UIScrollView, UICollectionView can be reload and adjust its content accordingly, where UIScrollView can't.
Ok, now in your case, you've to reload (refresh) your scroll view, which is not possible as we can with UICollectionView or UITableView.
You've two options,
Best option (little tough) : replace UIScrollView with UICollectionView - will take some of your time, but better for reducing code complexity and good performance of your app.
Poor option (easy) : Stay as it with UIScrollView - when you want to reload, delete each subview from it, and then again show and load everything. Highly not recommended.
IMHO, you should go with best option.

Calling action in TableView.m from customCell button

I have a UIViewController with a tableView in it with CustomCells, the CustomCell load a PLAY Button for some of the cells, this button are generated within the CustomCell.m
- (UIButton *)videoButton {
if (!videoButton) {
videoButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
videoButton.frame = CGRectMake(120, 319, 50, 30);
[videoButton setTitle:#"Play" forState:UIControlStateNormal];
[videoButton addTarget:self action:#selector(PlayClicked:) forControlEvents:UIControlEventTouchUpInside];
videoButton.backgroundColor= [UIColor clearColor];
[self.contentView addSubview:videoButton];
}
playIMG.hidden = false;
return videoButton;
}
- (IBAction)PlayClicked:(id)sender {
TableView *tvvc = [[TableView alloc] init];
[tvvc PlayBtnClicked:[NSString stringWithFormat:#"%d", [sender tag]]];
}
in my TableView.m
- (IBAction)PlayBtnClicked:(id)sender {
NSString *tag = [NSString stringWithFormat:#"%#", sender]; //OK
int tagNumber = [tag intValue]; //OK
NSString *Media = [arrayID objectAtIndex:tagNumber]; //Not Getting Result !
NSLog(#"%#", arrayID); //Array is empty when logging it from this action
}
arrayID is NSMutableArray
arrayID = [[NSMutableArray alloc] init];
[arrayID addObject#"123"];
[arrayID addObject#"321"];
[arrayID addObject#"231"];
soo i checked the array by adding an action button in my TableView to log the array and its not empty.
how can i fix the empty array which is actually not empty ?
I solved the problem in much easier way than the delegate thing
removed
[videoButton addTarget:self action:#selector(PlayClicked:) forControlEvents:UIControlEventTouchUpInside];
and the action in the custom cell .m file
- (IBAction)PlayClicked:(id)sender {
TableView *tvvc = [[TableView alloc] init];
[tvvc PlayBtnClicked:[NSString stringWithFormat:#"%d", [sender tag]]];
}
in the tableView.m i added edited the action i want to link to this
- (IBAction)PlayBtnClicked:(UIButton*)button {
NSLog(#"Button Clicked Tag: %d", button.tag);
}
and in the cellForRowAtIndexPath method i added the action to the button in the custom cell
if ([MediaType isEqualToString:#"video"]) {
cell.videoButton.hidden = NO;
cell.videoButton.tag = indexPath.row;
[cell.videoButton addTarget:self action:#selector(PlayBtnClicked:) forControlEvents:UIControlEventTouchUpInside];//here linking the action to the button
cell.playIMG.hidden = NO;
}
now everything is working very well :)
The array isn't your problem - you're breaking the model-view-controller nature of the table view controller and its cells. If you want a control in the cell to call a method in the table view controller, make the table view controller the delegate of the cell, and call the delegate method from the cell's button.
If the code you've posted is correct, then you're creating a new table view instance in the PlayClicked method, which is definitely not the way to do it.
As a minor stylistic point, the Cocoa convention of method naming is camelCase, with a lower-case initial letter.

iOS - Horizontal UIScrollView with multiple UITableViews

UIScrollView scrolls Horizontally and UITableView scrolls vertically inside that but unable to load different data when scroll horizontally.
have one scrollview which scrolls horizontally on screen and inside of that i have added multiple tableview and want to display different different datas on tableview when swipe. i have tried this but with no luck :(
NSArray *arr1 = [[NSArray alloc] initWithObjects:#"1",#"2",#"3", nil];
NSArray *arr2 = [[NSArray alloc] initWithObjects:#"4",#"5",#"6", nil];
NSArray *arr3 = [[NSArray alloc] initWithObjects:#"7",#"8",#"9", nil];
NSArray *arr4 = [[NSArray alloc] initWithObjects:#"10",#"11",#"12", nil];
arrData = [[NSMutableArray alloc] initWithObjects:arr1,arr2,arr3,arr4, nil];
int width=0;
for (int i = 0; i<[arrData count]; i++) {
tblData = [[UITableView alloc] initWithFrame:CGRectMake(width, 20, 300, 245) style:UITableViewStylePlain];
tblData.dataSource = self;
tblData.delegate = self;
[tblData setBackgroundColor:[UIColor clearColor]];
tblData.separatorColor = [UIColor blackColor];
[scrHorizontal addSubview:tblData];
width+=300;
}
[self.scrHorizontal setContentSize:CGSizeMake(([arrData count])*300, self.scrHorizontal.frame.size.height)];
here 4 pages inside scrollview which includes 4 tableviews i want to display 1,2,3 on first table and 4,5,6 on second table when swipe scrollview and so on...
please help me thanks in advance.
I have seen your code , you can do with tag,
set tag to tableview in loop
for (int i = 0; i<[arrData count]; i++) {
tblData = [[UITableView alloc] initWithFrame:CGRectMake(width, 20, 300, 245) style:UITableViewStylePlain];
tblData.tag=i;
tblData.dataSource = self;
tblData.delegate = self;
[tblData setBackgroundColor:[UIColor clearColor]];
tblData.separatorColor = [UIColor blackColor];
[scrHorizontal addSubview:tblData];
width+=300;
}
now in cellForRowAtIndexPath method just use it
like
NSArray *arr = [arrData objectAtIndex:tableView.tag];
cell.textLabel.text = [arr objectAtIndex:indexPath.row];
check it ScrollViewDemo
Hope it Helps.

IOS 6 UISegmentedControl

I use this code to create a UISegment:
//segment controll
NSString *key2 = [allKeys2 objectAtIndex:i];
NSString *obj2 = [DictionaryHomework objectForKey:key2];
int val;
val = [obj2 intValue];
//segment controll
NSArray *itemArray2 = [NSArray arrayWithObjects: #"very easy", #"easy", #"ok", #"hard", #"challenging", nil];
UISegmentedControl *segmentedControl2 = [[UISegmentedControl alloc] initWithItems:itemArray2];
segmentedControl2.frame = CGRectMake(480, -60, 130, 350);
segmentedControl2.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl2.selectedSegmentIndex = val - 1;
[segmentedControl2 addTarget:self action:#selector(segmentedControlHomework:) forControlEvents:UIControlEventValueChanged];
segmentedControl2.transform =
CGAffineTransformRotate(segmentedControl2.transform, degreesToRadians(90));
NSArray *arr = [segmentedControl2 subviews];
for (int i = 0; i < [arr count]; i++) {
UIView *v = (UIView*) [arr objectAtIndex:i];
NSArray *subarr = [v subviews];
for (int j = 0; j < [subarr count]; j++) {
if ([[subarr objectAtIndex:j] isKindOfClass:[UILabel class]]) {
UILabel *l = (UILabel*) [subarr objectAtIndex:j];
l.transform = CGAffineTransformMakeRotation(- M_PI / 2.0); //do the reverse of what Ben did
}
}
}
[image1 addSubview:segmentedControl2];
segmentedControl2.tag = i;
[segmentArray addObject: segmentedControl2];
//segment control
On ios5 the control loads the titles in horizontal, while in ios6 in vertical. Why is this? has there been a change in iOS6?
You are fiddling with the inner mechanics of the UISegmentedControl. While you are not technically using private APIs, you are still accessing parts of UIKit that are not publicly documented.
One reason the behavior might have changed in iOS 6 could be that the segmented control now builds its subviews lazily in layoutSubviews ore some other place. It might even not use subviews at all. But I'm just making guesses here. However, it's Apple's choice to change undocumented internals of the framework.
Your code should never have been used in a shipping app. If you want to do something like this (vertical segments?) that the build-in segmented control can't do, build it on your own.

uitextfield and uilabel depends on checkmark

In my tableview containing 8 row datas, I want to show the 8 label and 8 textfield in otherview, for ex: If the user selects(checkmarked) 4 rows in uitableview means I want to show 4 label and 4 texfield in other view. Can any one help me for this logic?
- (void)viewDidLoad
{
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background.png"]];
[lb5 setHidden:YES];
[text5 setHidden:YES];
[lb6 setHidden:YES];
[text6 setHidden:YES];
//[lb7 setHidden:YES];
//[text7 setHidden:YES];
//[lb8 setHidden:YES];
//[text8 setHidden:YES];
scrollView.frame = CGRectMake(0, 0, 320, 460);
[scrollView setContentSize:CGSizeMake(320, 678)];
int s=[am.genar count];
am=(AppDelegate*)[[UIApplication sharedApplication] delegate];
NSLog(#"test %d",[am.genar count]);
NSLog(#"test %#",[am.genar objectAtIndex:0]);
lb1.text=[am.genar objectAtIndex:0];
NSLog(#"test %#",[am.genar objectAtIndex:1]);
lb2.text=[am.genar objectAtIndex:1];
NSLog(#"test %#",[am.genar objectAtIndex:2]);
lb3.text=[am.genar objectAtIndex:2];
NSLog(#"test %#",[am.genar objectAtIndex:3]);
lb4.text=[am.genar objectAtIndex:3];
if(s>3)
{
[lb5 setHidden:NO];
[text5 setHidden:NO];
[lb6 setHidden:NO];
[text6 setHidden:NO];
// [lb7 setHidden:NO];
// [text7 setHidden:NO];
// [lb8 setHidden:NO];
// [text8 setHidden:NO];;
NSLog(#"test %#",[am.genar objectAtIndex:4]);
lb5.text=[am.genar objectAtIndex:4];
NSLog(#"test %#",[am.genar objectAtIndex:5]);
lb6.text=[am.genar objectAtIndex:5];
// NSLog(#"test %#",[am.genar objectAtIndex:6]);
// lb7.text=[am.genar objectAtIndex:6];
// NSLog(#"test %#",[am.genar objectAtIndex:7]);
// lb8.text=[am.genar objectAtIndex:7];
}
[super viewDidLoad];
}
right now I'm using this logic for showing texfield and label, but it showing error if user selects 5 rows and it's working 6 rows. can any help me to clear?
Following your application design it might have sense to use the table view in the second view controller, it will be easy to create as many rows as needed and display the titles correctly.
If you need to use the outlet labels and textfields, i'd make it like
NSArray * arrayOfLabelsAndTextViews = [NSArray arrayWithObjects:lb1, text1, lb2, text2, lb3, text3, lb4, text4, lb5, text5, lx6, text6, lb7, text7, lb8, text8, nil];
With the help of this array you can quickly enumerate through all the label/text pairs accessing it as:
i - pair index
i*2 - label index
i*2 +1 - text index
Then you need to show exactly the number of pairs checked at the previos view:
am=(AppDelegate*)[[UIApplication sharedApplication] delegate];
const int totalPairsCount = 8;
for(int i = 0; i<totalPairsCount; i++) {
UILabel * pairLabel = [arrayOfLabelsAndTextViews objectAtIndex:i*2];
UITextView * pairText = [arrayOfLabelsAndTextViews objectAtIndex:i*2 +1];
BOOL isPairVisible = i < am.count;
if (isPairVisible) {
pairLabel.text = [am objectAtIndex:i];
pairText.text = #"";
}
pairLabel.hidden = !isPairVisible;
pairText.hidden = !isPairVisible;
}
I don't think that is production quality code but at list it must help you understand how do you operate the data and use the UI elements.
dont code like this..,
int s=[am.genar count];
am=(AppDelegate*)[[UIApplication sharedApplication] delegate];
add S values after declaration of AppDelegate Variable.,
am=(AppDelegate*)[[UIApplication sharedApplication] delegate];
int s=[am.genar count];
and try to print the values.,.
On Click of Check Mark add that particular string to an Global Array. From that you can get an Global array count
In Second View
View Did Load Method
create a for loop
(int i =0 ; i < appDelegate.globalArray; i++)
{
Here you can create a label Dynamically whatever number will be. your labels will create according to that
}
if you have any questions feel free to ask

Resources